Search code examples
windowsdelphidelphi-12-athens

Problem: How to Restore the Application after previous Minimize?


In Windows 11, Delphi 12.1, I have a simple Delphi VCL Application with only one button:

procedure TForm1.Button1Click(Sender: TObject);
begin
  Application.Minimize;
  ShowMessage('Test');
  Application.Restore;
end;

Unfortunately, the application's Form is not restored. Only after clicking on the taskbar icon the form is restored.

How can I programmatically restore the Form after the ShowMessage call?

EDIT:

In the meantime, I've found a very simple solution:

procedure TForm1.Button1Click(Sender: TObject);
begin
  //Application.Minimize;
  Application.MainForm.Visible := False;

  ShowMessage('Test');

  Application.MainForm.Visible := True;
  //Application.Restore;
end;

However, the taskbar icon disappears when the ShowMessage dialog is shown. How to avoid this?


Solution

  • Unfortunately, the application's Form is not restored. Only after clicking on the taskbar icon the form is restored.

    Try using the Form's WindowState property instead:

    procedure TForm1.Button1Click(Sender: TObject);
    begin
      Self.WindowState := wsMinimized;
      ShowMessage('Test');
      Self.WindowState := wsNormal;
    end;
    

    However, the taskbar icon disappears when the ShowMessage dialog is shown.

    That is because Application.MainFormOnTaskbar is True by default. You are hiding/showing the window that owns the Taskbar button, which is why the button also hides/show.

    How to avoid this?

    You would have to set Application.MainFormOnTaskbar = False in the main .dpr file before Application.Run() is called. This will make the Application window be the owner of the Taskbar button. It should also address the behavior of Application.Minimize()/Application.Restore(), too.

    However, doing this will effectively make the VCL's Form window management behave like it did in the pre-Vista days, which may cause other side effects in Vista+ that MainFormOnTaskbar=True is meant to address. So be very careful with this.

    The alternative is to simply move your Form window offscreen, and then move it back.

    In the meantime, I've found a very simple solution

    You can use the Form's Hide() and Show() methods instead:

    procedure TForm1.Button1Click(Sender: TObject);
    begin
      Self.Hide;
      ShowMessage('Test');
      Self.Show;
    end;