Skip to content

Commit

Permalink
Unminimize before displaying message boxes and task dialogs.
Browse files Browse the repository at this point in the history
Now that MainFormOnTaskBar=True, Application.Restore doesn't steal the foreground anymore.
  • Loading branch information
jordanrussell authored Dec 16, 2024
1 parent aef9408 commit ee956cc
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 27 deletions.
26 changes: 0 additions & 26 deletions Projects/Src/Setup.MainForm.pas
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ TMainForm = class(TComponent)
procedure Finish(const FromPreparingPage: Boolean);
procedure InitializeWizard;
function Install: Boolean;
procedure RestoreApp;
procedure SetStep(const AStep: TSetupStep; const HandleExceptions: Boolean);
class procedure ShowException(Sender: TObject; E: Exception);
class procedure ShowExceptionMsg(const S: String);
Expand Down Expand Up @@ -502,31 +501,6 @@ procedure TMainForm.Close;
end;
end;

procedure TMainForm.RestoreApp;
{ Restores the app if it is currently minimized, and tries to make its taskbar
button blink (by attempting to bring it to the foreground, which Windows
normally blocks). This should be called before displaying any dialogs that
aren't user-initiated (like NewDiskForm). }
begin
if IsIconic(Application.Handle) then begin
{ If called alone, Application.Restore annoyingly brings WizardForm to the
foreground even if you're actively clicking/typing in the foreground
app. Evidently the SW_RESTORE command used by Application.Restore
bypasses Windows' usual foreground-stealing protections. However, if
we show WizardForm in advance (and leave the application window still
minimized), then SW_RESTORE doesn't bring WizardForm to the foreground
(not sure why).
Calling ShowWindow(Application.Handle, SW_SHOWNOACTIVATE) before
Application.Restore also works, but I worry that's relying on an
implementation detail: Application.Restore could be a no-op if it finds
the application window isn't minimized. (In fact, it used to be, until
the Forms unit added that fake IsIconic function.) }
//UpdateWizardFormVisibility(True);
Application.Restore;
end;
Application.BringToFront;
end;

class procedure TMainForm.AppOnGetActiveFormHandle(var AHandle: HWND);
begin
{ IDE's TMainForm has this too; see comments there }
Expand Down
3 changes: 2 additions & 1 deletion Projects/Src/Setup.NewDiskForm.pas
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ implementation
function SelectDisk(const DiskNumber: Integer; const AFilename: String;
var Path: String): Boolean;
begin
MainForm.RestoreApp;
Application.Restore; { see comments in AppMessageBox }
Application.BringToFront; { usually just makes taskbar button blink }

with TNewDiskForm.Create(Application) do
try
Expand Down
12 changes: 12 additions & 0 deletions Projects/Src/Shared.CommonFunc.Vcl.pas
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,18 @@ function AppMessageBox(const Text, Caption: PChar; Flags: Longint): Integer;
ActiveWindow: HWND;
WindowList: Pointer;
begin
{ Always restore the app first if it's minimized. This makes sense from a
usability perspective (e.g., it may be unclear which app generated the
message box if it's shown by itself), but it's also a VCL bug mitigation
(seen on Delphi 11.3):
Without this, when Application.MainFormOnTaskBar=True, showing a window
like a message box causes a WM_ACTIVATEAPP message to be sent to
Application.Handle, and the VCL strangely responds by setting FAppIconic
to False -- even though the main form is still iconic (minimized). If we
later try to call Application.Restore, nothing happens because it sees
FAppIconic=False. }
Application.Restore;

{ Always try to bring the message box to the foreground. Task dialogs appear
to do that by default.
Without this, if the main form is minimized and then closed via the
Expand Down
1 change: 1 addition & 0 deletions Projects/Src/Shared.TaskDialogFunc.pas
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ function TaskDialogMsgBox(const Icon, Instruction, Text, Caption: String; const
NButtonLabelsAvailable: Integer;
ButtonIDs: array of Integer;
begin
Application.Restore; { See comments in AppMessageBox }
if Icon <> '' then
IconP := PChar(Icon)
else begin
Expand Down

0 comments on commit ee956cc

Please sign in to comment.