Delphi窗口置于所有其他应用程序之上,而主窗口在下方

3

我有一个由一个主窗口和一个弹出窗口组成的应用程序,我希望它位于所有其他应用程序之上。我们将主窗口称为“窗口A”,将置顶弹出窗口称为“窗口B”,将另一个应用程序的窗口称为“窗口C”。

我使用以下代码将窗口B置于最上面:

    SetWindowPos(Handle, HWND_TOPMOST, 0, 0, 0, 0,
                 SWP_NoMove or SWP_NoSize);

这个操作如预期一样,我可以打开另一个应用程序(Window C),而Window B仍然保持在最前面。但是,如果我点击其窗口标题,“Window A”会置于“Window C”之上。有没有办法防止主窗口(Window A)在单击Window B的任何部分时置于最前面?


重写B的CreateParams以将WndParent设置为0。这里已经问了很多次。顺便说一下,您可以使用fsStayOnTop作为FormStyle。 - Sertac Akyuz
显然你无法处于所有其他窗口的顶部。你会输给想要做同样事情的其他窗口。很可能A是B的所有者,在Win32意义上。按照Sertac的建议让B成为未拥有的。 - David Heffernan
如果这个问题在这里已经被问过很多次了,@Sertac,那么你可否请投票将其标记为重复问题,而不是在评论中给出答案? - Rob Kennedy
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Jerry Dodge
@Rob - 我可能错了,我没有找到完全相同的副本。 - Sertac Akyuz
显示剩余2条评论
1个回答

6
要始终将“窗口B”置于顶部,可以将其FormStyle属性设置为fsStayOnTop,无需调用SetWindowPos。重写CreateParams以使其不受任何窗口拥有,这样当它被激活时就不会将其所有者带到前面。
type
  TWindowB = class(TForm)
    procedure FormCreate(Sender: TObject);
  protected
    procedure CreateParams(var Params: TCreateParams); override;
  end;

procedure TWindowB.CreateParams(var Params: TCreateParams);
begin
  inherited;
  Params.WndParent := 0;
end;

procedure TWindowB.FormCreate(Sender: TObject);
begin
  FormStyle := fsStayOnTop;
end;

对于普通的窗口(例如,BorderStyle=bsSizeable),你会有一个任务栏按钮和Alt+Tab图标来表示“窗口B”。这是正常的,因为该窗口现在不依赖于任何其他窗口进行激活,它应该有激活的手段。要避免这种情况,您可以使用bsToolWindowbsSizeToolWin作为BorderStyle,或者将隐藏的应用程序窗口设置为窗口所有者,方法是将Application.Handle设置为Params.WndParent
请注意,最顶层的窗口并没有比其他可能的最顶层的窗口更具优先级,它们中的任何一个都可能被置于前台。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接