【问题标题】:Delphi MainFormOnTaskBar Modal windows bugDelphi MainFormOnTaskBar 模态窗口错误
【发布时间】:2010-09-22 22:55:43
【问题描述】:

我使用的是 Delphi 2007 并将 MainFormOnTaskBar 属性设置为 true。

我遇到的问题是这样的。

如果您从主窗体打开一个子窗口,然后从您刚刚打开的子窗口显示一个消息对话框。当您关闭消息对话框然后关闭子窗口时,主窗体将被发送到您在屏幕上的任何其他应用程序的后面。

在 Windows Vista 和 Windows 7 下会发生这种情况。有谁知道为什么会发生这种情况以及如何解决?

【问题讨论】:

    标签: delphi windows-vista modal-dialog delphi-2007


    【解决方案1】:

    我猜那是QC66892-Closing forms deactivates the application,根据报告,这似乎已在 Delphi 2009 中得到修复。在 QC 报告的底部,您会找到 Andreas Hausladen 的评论,其中包括指向他修复错误的链接。但你真的很想利用他的VCL Fix Pack,其中还包括许多其他修复。

    【讨论】:

    • 谢谢你。是的,我发现关闭任何表单时都会发生这种情况,而不仅仅是模式表单。例如,如果我从主窗体打开一个子窗体,然后从第一个子窗体打开第二个子窗体。关闭第二个子窗体然后关闭第一个子窗体会将主窗体发送到任何其他应用程序的后面。
    • 我下载了 QC #66892 的修复程序,并注意到它提到了缺少 stdcall 指令导致问题。因此,我没有在我的项目中包含修复单元,而是将 stdcall 添加到 Forms.pas 的 DoFindWindow 函数并重新编译了 VLC。效果很好,谢谢。
    • @no spoon - 不客气,但功劳确实是安迪的。 :)
    • 更正,它适用于我的测试应用程序,但不适用于我的主应用程序。我似乎没有选择 stdcall 指令。我尝试将 Andy 的 HideStackTrashingFix 添加到 uses 子句,但这似乎也不起作用。
    • 啊,我找到了原因。在我们的主应用程序中,当我们关闭子屏幕时,我们处理表单的 OnClose 事件并返回 caFree。但是 FindTopMostWindow(它使用 DoFindWindow)只有在您返回 caHide(默认值)时才会被调用。这也是为什么 Andy 的代码也没有解决问题的原因,因为他的代码也钩住了 FindTopMostWindow,它真的有点咸。
    【解决方案2】:

    我已经通过两种方式解决了这个问题。

    首先,按照 Andreas Hausladen 的描述,将 stdcall 添加到 Forms.pas 中 DoFindWindow 的末尾。当子表单被隐藏(CloseAction = caHide)而不是在关闭表单时被释放时,这会处理。

    其次 - 从调用 FindTopMostWindow 的 TCustomForm.CMShowingChanged 复制代码,然后激活返回到 TCustomForm.CMRelease 的窗口。

    (编辑:代码块需要缩进4个空格)

    procedure TCustomForm.CMRelease;
    var
      NewActiveWindow: LongInt;
    begin
      if Application.MainFormOnTaskbar then
      begin
        NewActiveWindow := 0;
    
        if (GetActiveWindow = Handle) and not IsIconic(Handle) then
        begin
          NewActiveWindow := FindTopMostWindow(Handle);
        end;
    
        if NewActiveWindow <> 0 then
        begin
          SetActiveWindow(NewActiveWindow);
        end;
      end;
    
      Free;
    end;
    

    这似乎已经做到了,我会继续测试以确保。

    【讨论】:

      【解决方案3】:

      PopupMode 和 PopupParent 属性专门添加到 TForm 以解决此问题。在显示子窗体之前,将其 PopupParent 设置为主窗体,并将 PopupMode 设置为 pmAuto。

      PopupParent 在显示其他窗口时特别影响窗口的 Z 顺序。

      Delphi 2007 帮助有一些关于这两个属性的文档,但您必须通过 TForm 才能找到它们。使用“TForm,Pop”作为您的搜索主题(显然,不带引号)到达那里。文档对 PopupParent 有点困惑,因为它讨论了 PopupMode 对 PopupParent 自动分配的影响。不过,在阅读文档后进行一些小实验应该会有所收获。

      【讨论】:

        猜你喜欢
        • 2014-11-29
        • 2017-01-26
        • 1970-01-01
        • 2017-01-18
        • 1970-01-01
        • 1970-01-01
        • 2010-10-31
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多