Dim Out the Main Form of an Application When a Modal Form (/Dialog) is Displayed

Dim Main Form From Dialog
Dialog windows you use to display critical information to the user are, in most cases, displayed modally. A modal window (form) is the one where the application can’t continue to run until the modal window is closed. Delphi’s ShowMessage, InputBox and MessageDlg, for example, display a modal form to the user waiting for some action. Your custom dialogs are displayed using the ShowModal method of a form.

Dimmer – a device for varying the brightness of light

To emphasize the importance of a modal form and the information it presents, you could gray out the main form of the application when the modal form is activated.

Here’s how to add a dim-out effect to your main form when modal forms are waiting for the user input.

  • Have a main form in your application. (Or some other form you want to dim).
  • Add a new form to the project. This will be the “dimmer” form.
  • Drop the TApplicationEvents component on the main form
  • Handle OnModalBegin and OnModalEnd events…

The dimmer form is created at application startup – and since it is not the main form, it will not be displayed initially.

The Display procedure aligns the dimmer form above the main form and gets displayed before any modal form is shown. This happens in the ApplicationEvent’s OnModalBegin event. OnModalEnd ensures that dimmer form is hidden until needed next time.

procedure TDimmerForm.FormCreate(Sender: TObject);
begin
  AlphaBlend := true;
  AlphaBlendValue := 128;
  BorderStyle := bsNone;
end; 

The above is the OnCreate event handler for the dimmer form. By using the AlphaBlend property and the AlphaBlendValue you can make the form translucent. As it will be displayed over the main form, we want it to create the dim-out effect. BorderStyle ensures this form has no border, no caption bar, no title buttons.

The Display procedure aligns the dimmer form above the main form:

type
  TDimmerForm = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    procedure Display(const dimForm : TForm);
  end;

...

procedure TDimmerForm.Display(const dimForm: TForm);
begin
  with Self do
  begin
    Left := dimForm.Left;
    Top := dimForm.Top;
    Width := dimForm.Width;
    Height := dimForm.Height;

    Show;
  end;
end; 

Finally, handle the OnModalBegin and OnModalEnd events of the TApplicationEvents component on the main form:

procedure TMainForm.ApplicationEvents1ModalBegin(Sender: TObject);
begin
  if Assigned(DimmerForm) then DimmerForm.Display(self);
end;

procedure TMainForm.ApplicationEvents1ModalEnd(Sender: TObject);
begin
  if Assigned(DimmerForm) then DimmerForm.Hide;
end;

And … that’s it.

You can also decide to “Time Out a Message Dialog – Auto Close a Dialog Window After Some Time / Seconds” since we know no user is actually reading what the dialog has to say.

6 thoughts on “Dim Out the Main Form of an Application When a Modal Form (/Dialog) is Displayed

  1. Fronzel Neekburm

    Personally, I would not hook the global OnModalBegin and OnModalEnd events. Maybe my scenario is different (full screen kiosk application), but I prefer to have to popup itself do it. This way, I can dim out the underlying form with some dark grey for notifications, and use a red colour for errors/warnings. Also, multiple darkenings of the underlying content is possible this way. Just my 2 cents 😎

    Reply
  2. Jeremy

    I have tried to do this SO many times! Your article showed me what I was missing. YAY….it works 🙂

    Reply
  3. Ian Branch

    Hi Zarko,
    Now that’s nice functionality. Pity the capability isn’t built-in. 🙂
    Hmm. As I read the code you need a TApplicationEvents component on each Form that calls a modal dialog. It would be nicer if just the one component could be added to the main form and then called/functional from any sub form in the application.

    Reply
    1. zarkogajic Post author

      Hi Ian,

      No, only needed on Main for. Application object is global and needs only one TAppEvents.

      Reply
  4. emailx45

    uses
    uFormDimmer,
    uSecondForm;

    procedure TForm1.ApplicationEvents1ModalBegin(Sender: TObject);
    begin
    if Assigned(frmFormDimmer) then
    frmFormDimmer.Display(self);
    end;

    procedure TForm1.ApplicationEvents1ModalEnd(Sender: TObject);
    begin
    if Assigned(frmFormDimmer) then
    frmFormDimmer.Hide;
    end;

    procedure TForm1.BtnSecondFormClick(Sender: TObject);
    begin
    try
    frmSecondForm := TfrmSecondForm.Create(nil);
    //
    frmSecondForm.ShowModal; // DimForm doesnt works as expected = FormDimmer stay back to the FormMain!!!
    finally
    FreeAndNil(frmSecondForm);
    end;
    end;

    procedure TForm1.BtnShowMessageClick(Sender: TObject);
    begin
    ShowMessage(‘Hello FormMain’); // works!!!
    end;

    procedure TForm1.FormCreate(Sender: TObject);
    begin
    frmFormDimmer := TfrmFormDimmer.Create(Application);
    end;

    Reply

Leave a Reply to Ian Branch Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.