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.