设置 MainFormOnTaskBar 导致模态对话框出现问题

问题描述 投票:0回答:1

我正在使用一个旧的 Delphi 项目开发 Delphi 11.2,在

Application.MainFormOnTaskBar
的介绍之前,所以默认情况下它被设置为
False
。我尝试将以下行添加到项目的
.dpr
文件中
Application.Initialize;
之后,就像 Delphi 文档 建议的那样:

Application.MainFormOnTaskBar := True;

我的目标是模仿所有其他现代 Windows 应用程序,并在 Windows 任务栏上显示当前 MainView 的预览。虽然我的更改确实实现了这一点,但它也导致了模态对话框的不良行为。

确定模式对话框的父级和窗口 z 顺序的逻辑与具有

Application.MainFormOnTaskBar := False;
的应用程序不同。现在,这经常会在应用程序中的其他浮动窗口后面显示模式对话框,从而使模式对话框不可单击并锁定应用程序。

许多其他人也看到了相同的行为,并且在 Delphi 的文档中进行了说明。不幸的是,我能找到的关于恢复旧 z 排序的最有用的信息都有死链接,因为它是从 2007/2008 年引入

Application.MainFormOnTaskBar
的时候开始的。旧的论坛帖子指出使用
PopupParent
PopupMode
Application.ModalPopupMode
来重现旧的模式对话框行为。我在这些方面没有取得任何成功。

我发现有效的一个解决方法是在表单的

Params.WndParent := 0;
中设置
CreateParams()
。然而,我更愿意为所有模式对话框找到一个通用的解决方案,因为我使用内置的 VCL 方法,如
ShowMessage()
和系统对象
TMsgDlgType
来显示简单的模式对话框。

我希望旧的模式对话框 z 排序并让实时 MainView 预览出现在 Windows 任务栏上。有没有新的最佳方法来实现这一目标?自推出以来,此功能有任何进步吗?我可以在不设置

Application.MainFormOnTaskBar
的情况下在 Windows 任务栏上显示实时 MainView 预览吗?

编辑:

以下是有关项目整体流程的更多信息

Application.MainFormOnTask := False;

我首先显示一个登录表单,这是一个通过调用

TForm
继承自
LoginForm.ShowModal()
的自定义表单。项目的 Windows 任务栏图标出现,预览显示登录表单。输入信息后预览会保持更新。输入信息后,我将继续显示另一个自定义“TForm”,同时在后台创建内容。这也反映在 Windows 任务栏预览中。创建完成后,我将显示主视图。任务栏现在将登录表单显示为任务栏预览,即使它不再出现在屏幕上的任何位置。然后,我通过调用下面两个函数之一来显示其他弹出自定义表单,具体取决于我是否希望它是模态的。

  // Set form to stay on top
  SetWindowPos(Self.Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE or SWP_NOSENDCHANGING);

  Self.Show();
  // Set form to stay on top
  SetWindowPos(Self.Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE or SWP_NOSENDCHANGING);

  Result := Self.ShowModal();

Application.MainFormOnTask := True;
时情况略有不同。我显示的登录和创建表单与以前相同。但是,直到显示 MainView 后,任务栏图标才会出现。在整个运行过程中,预览都会保持更新。但是,当显示模态形式时,使用上述方法,z 顺序将位于非模态形式的后面。

windows delphi modal-dialog vcl taskbar
1个回答
0
投票

希望这对某人有帮助,我发现让模态表单出现在

StayOnTop
表单上方的唯一可靠方法是在调用
PopupMode
之前立即设置
ShowModal

您可以通过创建一个新的 Delphi 11 应用程序轻松重现模态表单出现在

StayOnTop
表单后面的问题,该应用程序具有两个表单:Form1 (
FormStyle := fsStayOnTop;
) 和包含
TComboBox
和公共方法
SetEnvironment
的 Form2 .

Form2

SetEnvironment
只是清除
TComboBox.Items
:

procedure TForm2.SetEnvironment;
begin
  // Comment out the below line and it doesn't matter where PopupMode is set
  // it always works as expected
  ComboBox1.Items.Clear;
end;

Form1 有

FormStyle := fsStayOnTop
并有一个以模态方式显示 Form2 的按钮:

procedure TForm1.Button1Click(Sender: TObject);
begin

  Form2 := TForm2.Create(nil);
//  Form2.PopupMode := pmAuto; {---> Uncomment this line and Form2 will appear BEHIND Form1}
  Form2.SetEnvironment;
//  Form2.PopupMode := pmAuto;  {---> Uncomment this line and Form2 will appear IN FRONT of Form1}
  Form2.ShowModal;
  Form2.Free;

end;

如果在Form2中注释掉

ComboBox1.Items.Clear
,那么设置
PopupMode
的顺序并不重要,Form2总是显示在Form1之上。

© www.soinside.com 2019 - 2024. All rights reserved.