2009-11-16 10 views
7

Sono stato abituato a pensare che WM_CREATE sia il primo messaggio ricevuto da una finestra. Tuttavia, quando si verifica questa ipotesi in una finestra di livello superiore, risulta essere falso. Nel mio test, WM_MINMAXINFO è apparso come primo messaggio.API Windows: Qual è il primo messaggio che una finestra è garantita per ricevere?

Quindi, qual è il primo messaggio che una finestra è garantita per ricevere?

+1

Questa domanda non ha senso. Come hai notato, i primi messaggi non sono sempre gli stessi. A seconda che la finestra sia stata creata o meno, potrebbe venire un'intera serie di messaggi a WindowPRoc prima che CreateWindow ritorni. quali messaggi e il loro ordine è cambiato tra le versioni di Windows. Tutto ciò che è garantito è che WM_CREATE - e ora WM_NCREATE - sarà inviato prima che venga restituito CreateWindow (presupponendo che sia stata creata una finestra di successo). –

+3

Chris, perché un commento invece di una risposta? Inoltre, non ha senso? Scommetto che il 90% degli sviluppatori Win32 giurerebbe che WM_CREATE è il primo messaggio ricevuto (e io ero uno di loro fino a 30 secondi fa). Dopotutto, questo è ciò che leggiamo tutti nei nostri libri di testo. –

+0

D'accordo Serge Wautier, ho pensato anche a questo finché non ho fatto un piccolo test. Questo è l'ordine di tutti i miei messaggi WM fino a WM_CREATE: WM_GETMINMAXINFO, WM_NCCREATE, WM_NCCALCSIZE, WM_CREATE. – Kit10

risposta

6

Hai risposto alla tua domanda. Vedo anche WM_GETMINMAXINFO, su Windows XP SP3, seguito da WM_NCCREATE, WM_NCCALCSIZE e infine WM_CREATE prima che CreateWindowEx() abbia persino restituito l'handle alla finestra in fase di creazione. What garabage

La risposta generale è che Microsoft è incompetente quando si tratta di creare e distruggere oggetti con ordine. Hanno sbagliato con Windows, con COM e con i driver di dispositivo. C'è sempre un po 'di catch-22 in cui un oggetto è semi-creato o semistrutturato che richiede una soluzione contorta rotondeggiante per produrre un prodotto affidabile.

+0

WM_GETMINMAXINFO è il primo messaggio per una finestra di livello superiore. Per altre finestre, sembra WM_NCCREATE. –

13

WM_NCCREATE è in realtà il very first message your window will receive, che arriverà prima di WM_CREATE. È legato alla creazione dell'area non client (ad esempio barra del titolo, menu di sistema, ecc.), Quindi il prefisso NC.

WM_GETMINMAXINFO viene inviato before the window size/position is changed e può arrivare prima di WM_CREATE (vedere sotto per ulteriori informazioni).

Il messaggio WM_CREATE viene inviato prima dei ritorni CreateWindow(), pertanto è possibile garantire che l'inizializzazione per finestra sia stata eseguita da quel punto. La finestra proc riceverà WM_CREATE dopo la creazione della finestra, ma prima che la finestra diventi visibile (WM_SHOWWINDOW).

In realtà, c'è un'interessante incoerenza nella documentazione MSDN - i messaggi di creazione sembrano dipendere dal fatto che si chiami CreateWindow() o CreateWindowEx(), tuttavia non specifica che i messaggi siano necessariamente elencati in ordine di dispacciamento.

  • CreateWindow(): WM_CREATE, WM_GETMINMAXINFO e WM_NCCREATE
  • CreateWindowEx(): WM_NCCREATE, WM_NCCALCSIZE, e WM_CREATE

ho il forte sospetto che l'ordine messaggio descritto nella CreateWindow() dovrebbe avere WM_NCCREATE prima, e il regolare WM_CREATE ultima , che è coerente con la documentazione di notifica e il riferimento CreateWindowEx() (e anche coerente con ciò che descrivere).

Raymond Chen ha anche qualche interessante information on window creation/destruction.

Solo per mostrare, anche le cose apparentemente semplici possono diventare complesse più le guardi.

+0

Interessante che WM_NCCREATE è stato introdotto in Win95, il che spiega perché non è stato documentato in "Programming Windows" di Petzold quando l'ho letto per la prima volta nel 1997. –

+2

WM_NCCREATE è presente da Windows 1.0. C'è molto che Petzold non ha mai cercato di coprire. –

+1

Un sacco di informazioni utili qui e mi dispiace per il downvote. Tuttavia, WM_NCCREATE è il primo messaggio solo per le finestre di primo livello. –

1

È possibile utilizzare spy ++ fornito con Visual Studio per vedere quali messaggi vengono generati all'avvio dell'applicazione o della finestra.

2

I risultati della sperimentazione sono meglio che fidarsi solo della fonte, soprattutto perché la fonte è composta da una legione di programmatori e nessuno conosce tutto il codice.Detto questo:

Il messaggio di pugno che ricevo è 0x24 (WM_GETMINMAXINFO).

Posso supporre che sarà sempre il primo messaggio? No, dal momento che il cambio di codice tra le versioni di Windows e Microsoft non ha documentato un messaggio garantito per essere il primo ricevuto.

Bottom line: Non dare per scontato che WM_CREATE sia stato chiamato prima di un altro messaggio.

+1

No, la sperimentazione non è mai una buona idea. Queste cose non sono documentate per una ragione. Non c'è alcuna garanzia che 'WM_GETMINMAXINFO' sarà * sempre * il primo messaggio inviato, indipendentemente dalla versione di Windows e dalla configurazione della macchina dell'utente. Qualsiasi applicazione che si basa sulla ricezione di messaggi in un determinato ordine come questo è fondamentalmente infranta. La documentazione ti dice di assumere che 'WM_NCCREATE' è il primo messaggio ricevuto. Dovresti eseguire tutte le operazioni di inizializzazione qui: funzionerà sempre, indipendentemente dal sistema su cui viene eseguita la tua app. Non eseguire il reverse engineering di Windows. –

Problemi correlati