What are the differences between BringWindowToTop, SetForegroundwindow, SetWindowPos etc.?

There are many closely-related concepts involved, and related terms are often misused, even in the official documentation.

Important types of windows:

  • top-level windows: Windows that have no parent window. The main window for an application is almost always a top-level window. It does not have anything to do with z-order.

  • child windows: Windows that are contained by a parent window. Their position is always relative to the parent window’s area. Child windows are often “controls”: UI things like buttons and edit boxes.

  • parent windows: Windows that have child windows. Top-level windows often have children. But note that child windows may also have children and thus be both parent and child windows.

  • owned windows: Windows that are controlled by a another window, but aren’t necessarily children of the other window. An example is a floating tool palette: it’s owned by another window in the application, but it’s not locked to that other window’s area.

  • owner windows: Windows that own an owned window.

Often the distinction between an owner/owned relationship and a parent/child relationship isn’t important, so the parent and child terms are often used for both contexts, even in documentation. In some cases, parent fields and parameters are overloaded to mean parent and/or owner.

Important concepts:

  • top of the z-order: This literally means the window that displays above other windows.

  • active window: A fuzzy concept, but it typically means the top-level window the user would consider the “current” window. The active window is typically drawn with a distinctive border and its tile on the task bar is highlighted. The active window is usually at or near to the top of the z-order among all other top-level windows, and it is the parent or owner (perhaps indirectly) of the window with keyboard focus.

  • keyboard focus: Indicates the window that will receive the keyboard messages. Conceptually, there is one window with keyboard focus. Often the window with focus is a child (or grandchild, etc.) of the active window.

  • foreground: The active window is typically in the foreground. The name seems to suggest that it’s at the top of the z-order, but it really means that the thread that created the window gets a slight priority boost. That active window is usually also the foreground window.

So let’s say you’ve got this browser window open, and you’ve also got an instance of Notepad running. If you click on the document in Notepad, a whole flurry of messages and state changes occur. You’re actually clicking on a big edit box, which is a child window of Notepad’s top-level window. That click causes the edit box to get activated, but child windows can’t really be the “active” window, so it just takes the keyboard focus and passes the activation message up through its ancestors until it gets to a top-level window. The top-level window “activates” by moving to the top of the z-order, highlighting its border, etc. It also becomes the foreground window, so its thread gets a little boost to make the UI a little more responsive than any other windows.

With these terms in mind, you can parse the MSDN descriptions for the functions you listed to tease out the subtle differences.

If you’re trying to lay out your window’s children, just use SetWindowPos (or MoveWindow, SizeWindow, and ShowWinow). Of the remaining functions, SwitchToThisWindow looks deprecated and essentially the same as SetForegroundWindow. (Note that, in many cases, SetForegroundWindow won’t do what you want unless you’re the active application or the active application has given you permission to use it.) BringWindowToTop is mostly about bringing a window to the top of the z-order (which you can do with SetWindowPos), with extra side effects that make it behave like SetForegroundWindow if you call it on a top-level window.

Update: Raymond Chen posted a clearer distinction between the active window and the foreground window. To quote:

The concept of the foreground window was introduced when input was desynchronized in order to express the “really global active window”, as opposed to Set¬≠Active¬≠Window, which continued to refer to the local active window.

Leave a Comment