Display a TopMost System Modal Message Box

From an Inactive Delphi Application

System Modal Message from an Inactive Application
System Modal Message from an Inactive Application.

In desktop (Windows) application, a message (dialog) box is used to alert the user of the application, that some action needs to be taken or that some operation was completed or, in general, to get users attention.

In Delphi, there are several ways of displaying a message to the user. You can either use any of the ready-made message displaying routines provided in the RTL, like: ShowMessage or InputBox; or you can create your own dialog box (for reuse): CreateMessageDialog.

A common "problem" to all the above dialog boxes is that they require the application to be active to be displayed to the user. By "active" I mean when your application has the "input focus".

If you really want to grab the user attention and stop him/her from doing anything else, you need to be able to display a system-modal topmost message box even when your application is not active.

System-Modal Top Most Message Box

Even though this might sound complicated, it is, as you will see, not.

Since Delphi can easily access most of the Windows API calls, executing the "MessageBox" Windows API function will do the trick.

Defined in the "windows.pas" unit - the one included by default in the uses clause of every Delphi form, the MessageBox function creates, displays, and operates a message box. The message box contains an application-defined message and title, along with any combination of predefined icons and push buttons.

Here's how the MessageBox is declared:

 function MessageBox(
   hWnd: HWND;
   lpCaption : PAnsiChar;
   uType : Cardinal) : integer;
The first parameter, hwnd, is the Handle of the owner window of the message box to be created. if you create a message box while a dialog box is present, use a handle to the dialog box as the hWnd parameter.

The lpText and lpCaption specify the caption and the message text that gets displayed in the message box.

The uType parameter is the most interesting one. This parameter specifies the contents and behavior of the dialog box. This parameter can be a combination of various flags.

An Example: System Modal Warning Box when the System Date/Time Changes

For an example of creating a system modal topmost message box I'll handle the Windows message that is dispatched to all the running applications when the system date/time changes - for example using the "Date and Time Properties" Control Panel applet.

The MessageBox function will be called as:

     'This is a system modal message'#13#10'from an inactive application',
     'A message from an inactive application!',
The most important piece is the last parameter. The "MB_SYSTEMMODAL or MB_SETFOREGROUND or MB_TOPMOST" ensures the message box is system modal, top most and becomes the foreground window.
  • MB_SYSTEMMODAL flag ensures that the user must respond to the message box before continuing work in the window identified by the hWnd parameter.
  • MB_TOPMOST flag specifies that the message box should be placed above all non-topmost windows and should stay above them, even when the window is deactivated.
  • MB_SETFOREGROUND flag ensures that the message box becomes the foreground window.

Well, that's it. :)

And now for the full example code (TForm named "Form1" defined in unit "unit1"):

 unit Unit1;
   Windows, Messages, SysUtils, Variants, Classes,
   Graphics, Controls, Forms, Dialogs, ExtCtrls;
   TForm1 = class(TForm)
     procedure WMTimeChange(var Msg: TMessage) ; message WM_TIMECHANGE;
     { Public declarations }
   Form1: TForm1;
 {$R *.dfm}
 procedure TForm1.WMTimeChange(var Msg: TMessage) ;
     'This is a system modal message'#13#10'from an inactive application',
     'A message from an inactive application!',
Try running this simple application. Make sure the application is minimized - or at least that some other application is active. Run the "Date and Tim Properties" Control Panel applet and change the system time. As soon as you hit the "Ok" button (on the applet) the system modal topmost message box from your inactive application will be displayed!