Windows-API: Was ist die erste Nachricht, die ein Fenster garantiert erhalten kann?

7

Ich bin daran gewöhnt, dass WM_CREATE die erste Nachricht ist, die ein Fenster empfängt. Beim Testen dieser Annahme in einem Top-Level-Fenster stellt es sich jedoch als falsch heraus. In meinem Test wurde WM_MINMAXINFO als erste Nachricht angezeigt.

Was ist also die erste Nachricht, die ein Fenster erhalten soll?

    
Agnel Kurian 16.11.2009, 10:27
quelle

4 Antworten

6

Sie haben Ihre eigene Frage beantwortet. Ich sehe auch WM_GETMINMAXINFO, unter Windows XP SP3, gefolgt von WM_NCCREATE, WM_NCCALCSIZE und schließlich WM_CREATE, bevor CreateWindowEx () sogar die Kennung an das zu erstellende Fenster zurückgegeben hat. Was für ein Garabage '

Die allgemeine Antwort ist, dass Microsoft inkompetent ist, wenn es um die geordnete Erstellung und Zerstörung von Objekten geht. Sie haben es falsch mit Windows, mit COM und mit Gerätetreibern. Es gibt immer einen Haken 22, bei dem ein Objekt halb kreiert oder halb zerstört wird, was eine umständliche Lösung erfordert, um ein zuverlässiges Produkt herzustellen.

    
Steel 19.12.2009, 23:37
quelle
14

WM_NCCREATE ist eigentlich die allererste Nachricht, die Ihr Fenster erhalten wird , die vor WM_CREATE eintreffen. Es bezieht sich auf das Erstellen des Nicht-Client-Bereichs (z. B. Titelleiste, Systemmenü usw.), daher das Präfix NC .

WM_GETMINMAXINFO wird gesendet, bevor die Fenstergröße / -position geändert wird , und kann vor WM_CREATE eintreffen (siehe unten für mehr).

Die Nachricht WM_CREATE wird gesendet, bevor CreateWindow() zurückkehrt, sodass Sie garantieren können, dass die Initialisierung pro Fenster bis zu diesem Zeitpunkt durchgeführt wurde. Ihr Fenster proc erhält WM_CREATE nachdem das Fenster erstellt wurde, aber bevor das Fenster sichtbar wird ( WM_SHOWWINDOW ).

Tatsächlich gibt es eine interessante Inkonsistenz in der MSDN-Dokumentation - die Erstellungsnachrichten scheinen davon abhängig zu sein, ob Sie CreateWindow() oder CreateWindowEx() , es spezifiziert jedoch nicht, dass die Nachrichten notwendigerweise in der Reihenfolge des Absendens aufgelistet werden.

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

Ich vermute stark, dass die Nachrichtenreihenfolge in CreateWindow() zuerst WM_NCCREATE und die reguläre WM_CREATE zuletzt haben sollte, was konsistent mit der Benachrichtigungsdokumentation und der CreateWindowEx() Referenz ist (und auch konsistent mit dem, was Sie tun beschreiben).

Raymond Chen hat auch einige interessante Informationen zum Erstellen und Löschen von Fenstern .

Es zeigt nur, dass selbst scheinbar einfache Dinge komplexer werden können, je mehr man sie betrachtet.

    
gavinb 16.11.2009 10:38
quelle
2

Ergebnisse durch Experimente sind besser als nur die Quelle zu vertrauen, besonders da die Quelle aus einer Legion von Programmierern besteht und keiner den ganzen Code kennt. Das sagte:

Die erste Nachricht, die ich erhalte, ist 0x24 (WM_GETMINMAXINFO).

Kann ich davon ausgehen, dass es immer die erste Nachricht sein wird? Nein, da der Code zwischen Windows-Versionen geändert wurde und Microsoft keine Nachricht dokumentiert hat, die garantiert die erste sein wird, die empfangen wurde.

Unterste Zeile: Nimm nicht an, dass WM_CREATE vor einer anderen Nachricht aufgerufen wurde.

    
rxantos 06.03.2011 16:00
quelle
1

Sie können spy ++ verwenden, das mit Visual Studio geliefert wird, um zu sehen, welche Nachrichten beim Start der Anwendung oder des Fensters generiert werden.

    
K Singh 20.11.2009 12:04
quelle

Tags und Links