Domanda

Da un paio di test preliminari sembra che EnumWindows restituisce sempre le finestre in ordine inverso all'istanza, ovvero prima l'ultima istanza della finestra. È un'osservazione valida? In tal caso, è vero in tutte le versioni di Windows? E questo è un presupposto affidabile, cioè quel comportamento è documentato da qualche parte?


Contesto: Ho a che fare con una situazione in cui sto attivando un'applicazione di terze parti per aprire diverse finestre non modali e ho bisogno di inviare alcuni messaggi di finestra a quelle finestre una volta aperte, eppure io non hanno un modo sicuro di identificarli in quanto né le loro classi di finestre né le loro didascalie differiranno e inoltre non conosco le loro coordinate previste. Tuttavia, se potessi fare affidamento sul comportamento precedente di EnumWindows , potrei semplicemente utilizzare il primo handle restituito da EnumWindows la cui classe e didascalia corrispondono alle mie aspettative. Ciò lascia ancora alcune ipotetiche lacune ma penso che sarà abbastanza buono. Suggerimenti alternativi sono comunque ben accetti.

È stato utile?

Soluzione

Li restituisce in ordine Z. Prima la finestra più in alto con WS_EX_TOPMOST impostato, fino alla finestra più in basso con WS_EX_TOPMOST impostato , quindi la finestra più in alto senza WS_EX_TOPMOST , sebbene nella finestra più in basso senza WS_EX_TOPMOST . Nota che la visibilità non è un fattore determinante, quindi una finestra invisibile più alta nell'ordine Z rispetto a una finestra visibile apparirà ancora prima di essa.

Modifica :

È altamente improbabile che tu possa usarlo come vuoi, semplicemente prendendo il primo ritorno da EnumWindows . Non solo è improbabile che la tua nuova finestra sia il primo ritorno, ma avresti una condizione di gara in cui altre finestre potrebbero essere aperte nel frattempo. Tuttavia, è possibile mantenere un elenco di tutte le finestre conosciute per l'applicazione e quando è necessario trovare una finestra aperta di recente, chiamare EnumWindows e confrontare le maniglie delle finestre con quelle dell'elenco. Quando ne trovi uno con la classe e la didascalia corrette (potresti persino verificare che appartenga al processo corretto con GetWindowThreadProcessID ) che è non nell'elenco, quindi " ho trovato la nuova finestra.

Per i tuoi scopi, tuttavia, potresti essere ancora meglio servito installando un hook CBT e guardando la notifica HCBT_CREATEWND. Consulta la guida di MSDN su SetWindowsHookEx () e il CBTProc callback per ulteriori informazioni.

Livello di certezza sull'ordine di enumerazione :

Numerosi commenti e altre risposte a questa domanda hanno menzionato la mancanza di una documentazione precisa in MSDN sull'ordine in cui EnumWindows restituisce gli handle di finestra. E infatti, le pagine su EnumWindows e il EnumWindowsProc callback sono entrambi abbastanza silenziosi sulla questione. Offro come prova quanto segue:

  1. A C ++ Q & amp; Un articolo nella rivista MSDN indica specificamente:

      

    EnumWindows enumera le finestre in ordine Z dall'alto in basso

  2. La pagina su EnumChildWindows allude all'ordine nella sezione osservazioni:

      

    Una finestra figlio che viene spostata o riposizionata nell'ordine Z durante il processo di enumerazione verrà correttamente elencata.

    Ciò implica che l'ordine dipende dall'ordine Z. E poiché, nella descrizione del parametro hWndParent , dice questo:

      

    Se questo parametro è NULL, questa funzione è equivalente a EnumWindows.

    si può presumere che la stessa logica e ordinamento si applichino a EnumWindows.

  3. Questo è il comportamento osservabile di questa funzione, che la rende una modifica rivoluzionaria per alterarla. In generale, Microsoft è stata molto brava a non apportare modifiche sostanziali al comportamento osservabile. Questa non è una garanzia, ma è una scommessa abbastanza sicura. È più probabile che nella prossima versione la funzione che stai usando sia stata deprecata e sostituita con un'altra "Ex" versione — che per scoprire che il suo comportamento osservabile è cambiato.

Naturalmente, tutto ciò è molto accademico a questo punto, dal momento che EnumWindows non è probabilmente la soluzione migliore per il problema del PO - almeno EnumThreadWindows probabilmente sarebbe un

Altri suggerimenti

Le risposte precedenti richiedono un notevole perfezionamento. Enum-order = Z-order solo se GetSystemMetrics (SM_IMMENABLED) = 0, ovvero le funzioni Gestione metodo di input / Editor metodo di input sono disabilitate. Perché tutta la classe di Windows "IME" (il titolo "IME predefinito") e "UI MSCTFIME" sono elencati dopo la finestra "Progman" (" Program Manager "), cioè non nell'ordine Z.

L'ordine non è specificato nell'API ( Link MSDN ), quindi non è garantito che ci sia qualcosa di particolare - se esistesse una garanzia, sarebbe esplicitamente specificato nell'API. Cosa succede, ad esempio, se una finestra viene creata a metà dell'enumerazione: viene inclusa nell'enumerazione? Ciò consente al gestore delle finestre la libertà di modificarne l'implementazione qualora diventi più efficiente.

Tuttavia, esiste un valore univoco che può essere utilizzato per differenziare le finestre: la finestra stessa si gestisce. Nel tuo metodo EnumWindowProc , salva l'handle della finestra per ogni finestra corrispondente - ti serve comunque per inviare messaggi alla finestra.

Se controlli entrambi i processi puoi inviare dal primo un SendMessage con " HWND_BROADCAST " come primo parametro.

Quindi l'altro programma quando riceve il messaggio, può fare un SendMessage alle finestre di suo figlio.

Se la documentazione non dice nulla sull'ordine di enumerazione, suggerirei VIVAMENTE di stare alla larga da qualsiasi ipotesi. Un paio di post sul blog di Raymond Chen (blogs.msdn.com/oldnewthing) ti rivelerebbero quante app ci sono che si basano su tutta questa roba / osservazione non documentata e qualcosa va terribilmente storto quando esce una nuova versione di Windows (a meno che Gli sviluppatori MS introducono ancora un altro shim per l'ennesima app che si comporta male).

Per quanto riguarda il tuo scopo, ci sono diverse funzioni, come GetWindowThreadProcessID, GetParent, EnumThreadWindows ed EnumWindows che potrebbero aiutarti a raggiungere il compito.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top