2010-07-19 21 views
7

El caso es que tengo una lista de identificadores de ventanas de nivel superior y quiero cambiarlos para que estén ordenados en el orden z de mi elección. Comencé iterando la lista (con la ventana en la que quiero terminar el último), llamando al SetForegroundWindow en cada uno. Esto pareció funcionar algunas veces, pero no siempre, mejorando un poco cuando me detuve un poco entre cada llamada.Actualizando el orden Z de muchas ventanas usando Win32 API

¿Hay una mejor manera de hacerlo?


Editar:

Parece que la ruta BeginDeferWindowPos/DeferWindowPos/EndDeferWindowPos es el camino a seguir. Sin embargo, parece que no puedo hacer que funcione con más de una ventana a la vez. Cuando limito la lista de ventanas a una sola ventana, funciona correctamente. Cuando la lista tiene varias ventanas, solo parece obtener una de ellas. Aquí es pseudo código de lo que estoy haciendo:

HWND[] windows; 
HWND lastWindowHandle = 0; 
HDWP positionStructure = BeginDeferWindowPos(windows.length); 

for (int i = 0; i < windows.length; i++) 
{ 
    positionStructure = DeferWindowPos(positionStructure, windows[i], 
     lastWindowHandle, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); 
} 

EndDeferWindowPos(positionStructure); 

Estoy seguro de que es algo pequeño/obvio que me falta aquí, pero yo no lo veo.

Respuesta

11

Hay un conjunto especial de la API para establecer posiciones de las ventanas de varias ventanas: BeginDeferWindowPos + DeferWindowPos + EndDeferWindowPos (SetWindowPos en un bucle también trabajarán por supuesto, pero podría tener más de parpadeo)

+0

+1: esta es definitivamente la mejor ruta, especialmente si se trata de una gran cantidad de ventanas. –

+0

Gracias por la sugerencia, este parece ser el enfoque correcto para tomar. Vea mi edición de la pregunta para el problema con el que me estoy encontrando. –

+1

@Greg Shackles: Probablemente quiera SWP_NOACTIVATE, y tal vez SWP_ASYNCWINDOWPOS – Anders

5

Puede solicitar SetWindowPos para pedir sus ventanas de nivel superior.

// Hypothetical function to get an array of handles to top-level windows 
// sorted with the window that's supposed to be topmost at the end of array. 
HWND* windows = GetTopLevelWindowsInOrder(); 
int numWindows = GetTopLevelWindowCount(); 

for(int i = 0; i < numWindows; ++i) 
{ 
    ::SetWindowPos(windows[i], HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); 
} 
+0

buena llamada , No me había dado cuenta de que SetWindowPos también tenía un parámetro para z-order. ¿Sabes si esto sufrirá los mismos problemas de tiempo que mencioné con SetForegroundWindow? –

+0

Pruébalo y ve si funciona mejor que 'SetForegroundWindow()' :-) –

+0

Lo planeo, simplemente no puedo hacer eso hasta más tarde. Informará más tarde con los resultados :) –

Cuestiones relacionadas