正确处理模态窗口“最小化”行为

时间:2011-06-10 08:03:44

标签: delphi winapi windows-7 delphi-6

我有以下问题:我们正在构建一个相当大的应用程序(win32,Delphi 6 Enterprise)。在应用程序的几个部分中,使用模态窗口,通常包含主窗口选择的细节。

我们修改了WM_SYSCOMMAND消息的处理,这样,如果窗口是模态的,那么SW_SHOWMINNOACTIVE消息将被发送到应用程序的主窗口。这会导致整个应用程序最小化,而不仅仅是模态形式。

然而,在特定情况下会出现问题:如果调用窗口设置为全屏,则在恢复时,模态窗口将显示在(禁用)最大化主窗口下(这似乎发生在Windows上7)

我的问题有两个:

首先,当应用程序恢复时,我似乎没有得到任何syscommand消息,因此我无法引入代码来恢复Z-Order,因为我不知道放在哪里。 其次,在我看来,如果整个应用程序被最小化,单击任务栏中的应用程序按钮应该以相同的状态恢复它,而不是在它下面的模式窗口。有办法解决这个问题吗?

编辑:我们做了一些额外的测试,看起来我们实际上可以在WM_ACTIVATE处理程序中检测主窗体的问题。我们还可以在该阶段识别模态窗口。但是,我无法找到将其恢复到Z-Order顶部的方法。

Edit2:这是在模式形式最小化时最小化应用程序的代码:

procedure TfmGITForm.WMSysCommand(var Message: TWMSysCommand);
begin
  if (fsModal in FormState) or
      not Application.MainForm.Visible then
  begin
    case Message.CmdType of
      SC_MINIMIZE:
      begin
        ShowWindow(Application.Handle, SW_SHOWMINNOACTIVE);
      end;
      SC_RESTORE:
      begin
        ShowWindow(Application.Handle, SW_SHOWNORMAL);
        inherited;
      end;
    else
      inherited;
    end;    // case
  end
  else
    inherited;
end;

我们所有的形式都来自那个。

2 个答案:

答案 0 :(得分:3)

覆盖对话框的CreateParams功能并将Params.WndParent设置为全屏窗口(如果您正确拥有内容,则设置为Owner.Handle)。默认值为Application.Handle,这会导致这些问题。在后面的Delphi版本中引入的PopupParent属性完全相同。

答案 1 :(得分:1)

这与Windows(我认为)XP中引入的Windows重影有关。我在这些操作系统上的D5应用程序中遇到了同样的问题。 Peter Below当时提供了以下工作,它仍然很适合我:

procedure DisableProcessWindowsGhosting;
type
  TDisableProcessWindowsGhostingProc = procedure; stdcall;
const
  sUser32 = 'User32.dll';
var
  ModH: HMODULE;
  _DisableProcessWindowsGhosting: TDisableProcessWindowsGhostingProc;
begin
  ModH := GetModuleHandle(sUser32);
  if ModH <> 0 then begin
    @_DisableProcessWindowsGhosting := nil;
    @_DisableProcessWindowsGhosting := GetProcAddress(ModH,
        'DisableProcessWindowsGhosting');
    if Assigned(_DisableProcessWindowsGhosting) then begin
      _DisableProcessWindowsGhosting;
    end;
  end;
end;

我在应用程序主窗体的OnCreate处理程序的开头调用它。