2010-07-19 2 views
7

Lo scenario è che ho un elenco di handle di finestra per le finestre di livello superiore e voglio spostarli in modo che siano disposti nell'ordine z di mia scelta. Ho iniziato ripetendo l'elenco (con la finestra che voglio finire all'ultimo), chiamando SetForegroundWindow su ognuno di essi. Sembrava funzionare un po 'di tempo, ma non sempre, migliorando un po' quando mi fermavo leggermente tra ogni chiamata.Aggiornamento dell'ordine Z di molti Windows utilizzando l'API Win32

C'è un modo migliore per farlo?


Edit:

Sembra che il percorso BeginDeferWindowPos/DeferWindowPos/EndDeferWindowPos è la strada da percorrere. Tuttavia, non riesco a farlo funzionare con più di una finestra alla volta. Quando limito l'elenco delle finestre a una singola finestra, funziona correttamente. Quando la lista ha più finestre, sembra solo averne una. Ecco pseudo-codice di quello che sto facendo:

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); 

Sono sicuro che è qualcosa di piccolo/ovvio che mi manca qui, ma non sto solo vedendo.

risposta

11

C'è uno speciale set di API per impostare la posizione delle finestre per le finestre multiple: BeginDeferWindowPos + DeferWindowPos + EndDeferWindowPos (SetWindowPos in un ciclo funzioneranno anche, ovviamente, ma potrebbe avere più flicker)

+0

+1: questo è sicuramente il percorso migliore, soprattutto se hai a che fare con un gran numero di finestre. –

+0

Grazie per il suggerimento, questo sembra l'approccio giusto da prendere. Vedi la mia modifica della domanda per il problema con cui mi sto imbattendo. –

+1

@Greg Shackles: Probabilmente vuoi SWP_NOACTIVATE, e forse SWP_ASYNCWINDOWPOS – Anders

5

È possibile utilizzare SetWindowPos per ordinare le finestre di primo livello.

// 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

buona chiamata , Non avevo notato che SetWindowPos aveva anche un parametro per z-order. Sai se questo soffrirà degli stessi problemi di temporizzazione che ho menzionato con SetForegroundWindow? –

+0

Provalo e vedi se funziona meglio di 'SetForegroundWindow()' :-) –

+0

Pianifico su di esso, non posso farlo più tardi. Riporteremo in seguito con i risultati :) –