Reputation: 1161
I have an application composed of one main window and a popup I want to be on top of all other applications. Let's call "Window A" to the main window, "Window B" to the on-top popup and "Window C" to another application's window.
I'm setting Window B on top using this code:
SetWindowPos(Handle, HWND_TOPMOST, 0, 0, 0, 0,
SWP_NoMove or SWP_NoSize);
This works as expected, I can open another application (Window C) and Window B keeps on top. But if I click on its window title the "Window A" brings to front, on top of "Window C". Is there a way to prevent the main window (Window A) to brint to front when clicking any part of Window B?.
Upvotes: 3
Views: 3904
Reputation: 54812
To have "Window B" always on top, you can set its FormStyle
property to fsStayOnTop
, you don't need to call SetWindowPos
. Override CreateParams
to have it unowned by any window, so that it won't bring along its owner to the front when it is activated.
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;
For a normal window (e.g. BorderStyle
= bsSizeable
), you'll have a taskbar button and Alt+Tab icon for "Window B". This is normal, as the window does not depend on any other window for activation now, it should have means to activate it. To avoid that you can use bsToolWindow
or bsSizeToolWin
as BorderStyle
, or the hidden Application window as window owner by setting Application.Handle
to Params.WndParent
.
Note that a topmost window does not have any priority over other possible topmost windows, any one of them might be brought to front.
Upvotes: 6