http://blogs.msdn.com/b/oldnewthing/archive/2005/11/21/495246.aspx
The special values HWND_TOP
and HWND_TOPMOST
have similar names but do completely different things when passed as the hWndInsertAfter
parameter to the DeferWindowPos
function (or its moral equivalents such as SetWindowPos
). As a backgrounder, you should start off by reading the MSDN discussion, which is perfectly accurate as far as it goes. Here, I'll discuss the issue from a historical perspective in the hopes that looking at it from a different direction may improve understanding.
Sibling windows are maintained in an order called the Z-order. (For the purpose of this discussion, top-level windows are also treated as siblings. In fact, it is the Z-order of top-level windows that most people think of when they say "Z-order".)
The Z-order should be visualized as a vertical stack, with windows "above" or "below" siblings.
Before Windows 3.0, the behavior was simple: HWND_TOP
brings the window to the top of the Z-order.
Windows 3.0 added the concept of "topmost" windows. These are top-level windows that always remain "above" non-topmost windows. To make a window topmost, call DeferWindowPos
(or one of its moral equivalents) with HWND_TOPMOST
as the hWndInsertAfter
. To make a window non-topmost, use HWND_NOTOPMOST
.
As a result of the introduction of "topmost" windows, HWND_TOP
now brings the window "as high in the Z-order as possible without violating the rule that topmost windows always appear above non-topmost windows". What does this mean in practice?
- If a window is topmost, then
HWND_TOP
puts it at the very top of the Z-order. - If a window is not topmost, then
HWND_TOP
puts it at the top of all non-topmost windows (i.e., just below the lowest topmost window, if any).
Note: The above discussion completely ignores the issue of owner and owned windows. I left them out because they would add a layer of complication that distracts from the main topic.