Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the z-order in windows?

I'm making an application where I interact with each running application. Right now, I need a way of getting the window's z-order. For instance, if Firefox and notepad are running, I need to know which one is in front.

Any ideas? Besides doing this for each application's main window I also need to do it for its child and sister windows (windows belonging to the same process).

like image 473
user361526 Avatar asked May 05 '09 15:05

user361526


People also ask

What is Z ordered list of windows?

Z-order is an ordering of overlapping two-dimensional objects, such as windows in a stacking window manager, shapes in a vector graphics editor, or objects in a 3D application. One of the features of a typical GUI is that windows may overlap, so that one window hides part or all of another.

Is a child window of to level window?

A child window, owned by a parent form, is not a top-level form, because it has a parent. But it can be on top in the Z order, and can be modal or modeless depending on how it is displayed, with either ShowDiaglog() or Show() respectively.


2 Answers

You can use the GetTopWindow function to search all child windows of a parent window and return a handle to the child window that is highest in z-order. The GetNextWindow function retrieves a handle to the next or previous window in z-order.

GetTopWindow: http://msdn.microsoft.com/en-us/library/ms633514(VS.85).aspx
GetNextWindow: http://msdn.microsoft.com/en-us/library/ms633509(VS.85).aspx

like image 189
NineBerry Avatar answered Sep 23 '22 11:09

NineBerry


Nice and terse:

int GetZOrder(IntPtr hWnd) {     var z = 0;     for (var h = hWnd; h != IntPtr.Zero; h = GetWindow(h, GW.HWNDPREV)) z++;     return z; } 

If you need more reliability:

/// <summary> /// Gets the z-order for one or more windows atomically with respect to each other. In Windows, smaller z-order is higher. If the window is not top level, the z order is returned as -1.  /// </summary> int[] GetZOrder(params IntPtr[] hWnds) {     var z = new int[hWnds.Length];     for (var i = 0; i < hWnds.Length; i++) z[i] = -1;      var index = 0;     var numRemaining = hWnds.Length;     EnumWindows((wnd, param) =>     {         var searchIndex = Array.IndexOf(hWnds, wnd);         if (searchIndex != -1)         {             z[searchIndex] = index;             numRemaining--;             if (numRemaining == 0) return false;         }         index++;         return true;     }, IntPtr.Zero);      return z; } 

(According to the Remarks section on GetWindow, EnumChildWindows is safer than calling GetWindow in a loop because your GetWindow loop is not atomic to outside changes. According to the Parameters section for EnumChildWindows, calling with a null parent is equivalent to EnumWindows.)

Then instead of a separate call to EnumWindows for each window, which would also be not be atomic and safe from concurrent changes, you send each window you want to compare in a params array so their z-orders can all be retrieved at the same time.

like image 31
jnm2 Avatar answered Sep 24 '22 11:09

jnm2