首页 > 解决方案 > 如何恢复最小化的模态形式?

问题描述

我有一个从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;

...当我最小化模态表单时,整个应用程序也被最小化。一切都很好,但是当我单击任务栏按钮并恢复应用程序时,焦点窗口是MainForm,而不是模态窗口,就像它应该的那样。我应该怎么做才能恢复以最模态形式为重点的应用程序?

标签: formsdelphimodal-dialogdelphi-2009

解决方案


在您当前的设计中,您有一个用于最小化窗口的任务栏按钮,该按钮由于模态表单而被禁用。我认为您无法为此设置制定一个明智的解决方案,WM_SYSCOMMAND因为它没有任务栏按钮和主表单,因为它被禁用,所以表单都没有收到 - 模态表单。

在最小化模态表单时更改策略并切换任务栏按钮。也就是说,您将有一个用于模态表单而不是主表单的任务栏按钮。然后,当您收到恢复命令时,您可以在同一个事件处理程序中拦截和反转。下面是一个工作示例,但我应该注意,强烈建议不要在创建窗口后更改窗口的所有者,事实上已经有一段时间没有记录了。


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;

推荐阅读