如何恢复最小化的模态形式?
How to restore a minimized modal form?
我有一个在 MainForm
中显示为模态的表单。在这种模态形式中,我像这样覆盖 WM_SYSCOMMAND
:
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;
... 当我最小化模态形式时,整个应用程序也被最小化。一切正常,但是当我单击任务栏按钮并恢复应用程序时,焦点 window 是 MainForm
,而不是模态,就像它应该的那样。我应该怎么做才能以最集中的形式恢复应用程序?
在您当前的设计中,您有一个用于最小化 window 的任务栏按钮,该按钮由于模态形式而被禁用。我不认为你能够为这个设置制定一个明智的解决方案,两种形式都没有收到 WM_SYSCOMMAND
- 模态形式,因为它没有任务栏按钮和主形式,因为它被禁用。
在最小化模态窗体时更改您的策略并切换任务栏按钮。也就是说,您将有一个模式窗体的任务栏按钮,而不是主窗体。然后,当您收到恢复命令时,您可以在同一个事件处理程序中进行拦截和反转。下面是一个工作示例,但我应该注意,强烈建议不要在创建 window 之后更改 window 所有者,并且实际上已经有一段时间没有再记录了。
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;
我有一个在 MainForm
中显示为模态的表单。在这种模态形式中,我像这样覆盖 WM_SYSCOMMAND
:
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;
... 当我最小化模态形式时,整个应用程序也被最小化。一切正常,但是当我单击任务栏按钮并恢复应用程序时,焦点 window 是 MainForm
,而不是模态,就像它应该的那样。我应该怎么做才能以最集中的形式恢复应用程序?
在您当前的设计中,您有一个用于最小化 window 的任务栏按钮,该按钮由于模态形式而被禁用。我不认为你能够为这个设置制定一个明智的解决方案,两种形式都没有收到 WM_SYSCOMMAND
- 模态形式,因为它没有任务栏按钮和主形式,因为它被禁用。
在最小化模态窗体时更改您的策略并切换任务栏按钮。也就是说,您将有一个模式窗体的任务栏按钮,而不是主窗体。然后,当您收到恢复命令时,您可以在同一个事件处理程序中进行拦截和反转。下面是一个工作示例,但我应该注意,强烈建议不要在创建 window 之后更改 window 所有者,并且实际上已经有一段时间没有再记录了。
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;