How to: change Z-Order of a window

Currently working with the Windows API to manipulate window’ handles, I needed to put a window just behind the focused (topmost) window. The programming language is C#.

First of all, you’ll need to get the window handle, an unique number that identify each window that is loaded in memory. To know this number, you have two choices:

  1. Finding the window handle using EnumWindows GetWindowModuleFileName (See this thread: Codeguru Forum – Get window handle from process)
  2. Use a software like Spy++, that is provided by VisualStudio 2010 (See the official help page of Microsoft: MSDN Help Page about Spy++ )

Once you have the handle of the window you want to put just behind the window that has actually the focus, you can use the SetWindowPos function. According, you can declare this function like this:

[DllImport("user32.dll", SetLastError = true)]
 [return: MarshalAs(UnmanagedType.Bool)]
 private static extern bool SetWindowPos(IntPtr hWnd,
 int hWndInsertAfter, int x, int y, int cx, int cy, int uFlags);

Then, simply pass the window handle as first parameter to SetWindowPos. You will need to call this function twice, and you have to specify action to be applied to this handle:

int hWndInsertAfter

If you want to put this window on the top of all window (including the currently focused (topmost) window), put this parameter to HWND_TOPMOST (corresponding value: -2). If you want to bring the window handle just behind the focused window, you will need to recall SetWindowPos with HWND_BOTTOM parameter.

 int x, int y, int cx, int cy 

These values allows you to resize the window (cx, cy) or the position on the screen (x, y). For my example, I put all of them to the 0 value.

int uFlags

This last parameter is very important. It allows to specify some nice actions:

  • SWP_NOACTIVATE (0x0010) : The window handle provided in parameter will not be focused (placed on topmost position). So you have to set it with HWND_TOPMOST, and you will be able to get the second position of all windows on the screen.
  • SWP_NOSIZE (0x0001) : The window will not be resized. It allows ignoring cx and cy parameters.
  • SWP_NOMOVE (0x0002) : The window will not be moved. It allows ignoring x and y parameters.

This is the final function:

public static bool BringBehindTopMostWindow(IntPtr hWnd)
 bool ret;

//First, we set the window as Topmost window in the Z order, but without the focus
 ret = SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);

//Set the window as non-topmost window, to be sure it will not be always on top
 ret = SetWindowPos(hWnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);

return ret;

You can download a working example here: (634 downloads) .

Leave a Reply