Reputation: 3608
I am writing a custom tooltip window (let's call it A). It has to be displayed over another window (let's call it B) and:
Do not steal the focus from the B
Do not lose its position in z-order to B while user continues input into B
A must recieve WM_NCHITTEST messages (i use them to track mouse position over inactive window)
When another window is brought over B, it must be brought over A as well; situation where B is covered and not visible, but A is displayed should be averted
I have tried to implement this by using the SetWindowPos function, calling its wrapper (defined in A) from B like this:
public void SetLocation(Point location, IntPtr UnderHandle)
{
SetWindowPos(Handle, HWND_TOPMOST, location.X, location.Y, Width, Height,
SetWindowPosFlags.DoNotActivate);
}
(SetWindowPosFlags from pinvoke.net)
The result satisfies almost all my needs except the lst one.
What have i also tried:
HWND_TOP: does not brings window A over active window B; to be more precise: immediately after the call, it does bring window A to foreground, but then B goes to foreground instead; in practice, while B is moved by the title bar and mouse button is pressed, window A is drawn over it - but goes under the moment mouse button is unpressed
calling SetWindowPos with UnderHandle as first parameter and Handle as second, in attempt to "bring window B under window A" yields the same result
How should SetWindowPos be usd correctly to achieve desired result - or, alternatively, how can window B's position in zorder be monitored to force window A into position next to it (from being a foreground window)?
Upvotes: 4
Views: 2184
Reputation: 612794
Clearly HWND_TOPMOST
is your problem and you certainly must not do that. You could use HWND_TOP
, but then the challenge is how to keep window A on top of window B. The way to do that is to make A be owned by B.
Owned Windows
An overlapped or pop-up window can be owned by another overlapped or pop-up window. Being owned places several constraints on a window.
- An owned window is always above its owner in the z-order.
- The system automatically destroys an owned window when its owner is destroyed.
- An owned window is hidden when its owner is minimized.
Only an overlapped or pop-up window can be an owner window; a child window cannot be an owner window. An application creates an owned window by specifying the owner's window handle as the hwndParent parameter of
CreateWindowEx
when it creates a window with theWS_OVERLAPPED
orWS_POPUP
style. The hwndParent parameter must identify an overlapped or pop-up window. If hwndParent identifies a child window, the system assigns ownership to the top-level parent window of the child window. After creating an owned window, an application cannot transfer ownership of the window to another window.
In fact, as you can see from the first bullet point above, once the ownership is correctly setup, there's no need for HWND_TOP
.
Upvotes: 3