我有一个应用程序,由一个主窗口和一个我想要在所有其他应用程序之上的弹出窗口组成.让我们将"Window A"调用到主窗口,将"Window B"调用到顶部弹出窗口,将"Window C"调用到另一个应用程序的窗口.
我使用以下代码将Window B设置为顶部:
SetWindowPos(Handle, HWND_TOPMOST, 0, 0, 0, 0,
SWP_NoMove or SWP_NoSize);
Run Code Online (Sandbox Code Playgroud)
这按预期工作,我可以打开另一个应用程序(窗口C),窗口B保持在顶部.但如果我点击它的窗口标题,"窗口A"会在"窗口C"之上显示在前面.有没有办法在单击Window B的任何部分时阻止主窗口(窗口A)向前打开?
要使"Window 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;
Run Code Online (Sandbox Code Playgroud)
对于普通窗口(例如BorderStyle
= bsSizeable
),您将有一个任务栏按钮和"窗口B"的Alt + Tab图标.这是正常的,因为窗口现在不依赖于任何其他窗口进行激活,它应该有激活它的方法.要避免这种情况,你可以使用bsToolWindow
或bsSizeToolWin
作为BorderStyle
,或通过设置隐藏的应用程序窗口,窗口所有者Application.Handle
来Params.WndParent
.
请注意,最顶层的窗口没有任何优先级高于其他可能的最顶层窗口,其中任何一个窗口都可能被带到前面.