I have a Form that is shown modal from the MainForm
. In this modal form I override the WM_SYSCOMMAND
like this :
protected
procedure WMSysCommand(var Msg: TWMSysCommand); message WM_SYSCOMMAND;
procedure TModalDlg.WMSysCommand(var Msg: TWMSysCommand);
begin
if (fsModal in FormState) and (Msg.CmdType and $FFF0 = SC_MINIMIZE)
then Application.MainForm.WindowState:= wsMinimized
else inherited;
end;
... and when I minimize the modal form, the whole application is minimized. Everything is ok, but when I click on the taskbar button and the application is restored, the foscused window is the MainForm
, not the modal one, like it should. What should I do to restore the app with the most modal form focused ?
In your current design you have a taskbar button for a minimized window which is disabled because of the modal form. I don't think you will be able to work out a sensible solution for this setup, neither form receives a WM_SYSCOMMAND
- modal form because it doesn't have a taskbar button and the main form because it is disabled.
Change your strategy and switch taskbar buttons when you are minimizing the modal form. That is, you'll have a taskbar button for the modal form and not for the main form. You can then intercept and reverse in the same event handler when you receive a restore command. Below is a working example, but I should note that changing the window owner of a window after it has been created is strongly discouraged and in fact not documented any more for quite some time.
type
TModalDlg = class(TForm)
...
private
FParentWnd: HWND;
protected
procedure WMSysCommand(var Msg: TWMSysCommand); message WM_SYSCOMMAND;
end;
...
procedure TModalDlg.WMSysCommand(var Msg: TWMSysCommand);
begin
if (fsModal in FormState) then begin
case Msg.CmdType and $FFF0 of
SC_MINIMIZE:
begin
SetWindowLong(Handle, GWL_EXSTYLE,
(GetWindowLong(Handle, GWL_EXSTYLE) or WS_EX_APPWINDOW));
FParentWnd := GetWindowLong(Handle, GWL_HWNDPARENT);
if FParentWnd <> 0 then
ShowWindow(FParentWnd, SW_HIDE);
SetWindowLong(Handle, GWL_HWNDPARENT, 0);
end;
SC_RESTORE:
begin
SetWindowLong(Handle, GWL_EXSTYLE,
(GetWindowLong(Handle, GWL_EXSTYLE) and not WS_EX_APPWINDOW));
if FParentWnd <> 0 then begin
SetWindowLong(Handle, GWL_HWNDPARENT, FParentWnd);
ShowWindow(FParentWnd, SW_SHOW);
end;
end;
end;
end;
inherited;
end;