Ich habe versucht, eine Schaltfläche (untergeordnetes Fenster) in der WM_NCCREATE-Nachricht zu erstellen, und die Position wurde scheinbar auf Bildschirmkoordinaten und nicht auf Clientkoordinaten festgelegt. Zuerst dachte ich, dass WM_CREATE und WM_NCCREATE uns das gleiche Handle für das Fenster liefern, aber das scheint unwahr zu sein. Kann mir also jemand die Unterschiede zwischen WM_CREATE- und WM_NCCREATE-Nachrichten erklären? Was sind die Unterschiede zwischen Handle zu Fenster in WM_CREATE und WM_NCCREATE?
Pro MSDN:
WM_NCCREATE:
wurde vor der WM_CREATE-Nachricht gesendet wenn ein Fenster erstellt wird.
Rückgabewert:
Wenn eine Anwendung dies verarbeitet Nachricht sollte es TRUE zurückgeben Fortsetzen der Erstellung des Fensters. Ob Die Anwendung gibt FALSE zurück, das CreateWindow oder CreateWindowEx Funktion wird einen NULL-Handle zurückgeben.
WM_CREATE:
Wird gesendet, wenn eine Anwendung dies anfordert Ein Fenster wird durch Aufrufen des CreateWindowEx oder CreateWindow Funktion. (Die Nachricht wird vorher gesendet Die Funktion kehrt zurück.) Das Fenster Prozedur des neuen Fensters empfängt Diese Nachricht nach dem Fenster ist erstellt, aber bevor das Fenster wird sichtbar.
Rückgabewert:
Wenn eine Anwendung dies verarbeitet Nachricht, sollte es zu Null zurückgeben Fortsetzen der Erstellung des Fensters. Ob Die Anwendung gibt -1, das Fenster zurück ist zerstört und CreateWindowEx oder CreateWindow-Funktion gibt einen NULL zurück handle.
Die WM_NC-Nachrichten sind für den Nicht-Client-Bereich, d. h. den Fensterrahmen und die Bildunterschrift. Für Ihre Bedürfnisse sind Sie nicht an diesen Nicht-Client-Nachrichten interessiert.
WM_NCCREATE ist ein Beispiel für ein Wettrüsten im Gange. Es wurde anscheinend eingeführt, um eine Notwendigkeit zu erfüllen, wo DefWindowProc (oder das Basisfensterproc eines häufig untergeordneten Fensters) benötigt wird, um eine Initialisierung durchzuführen, möglicherweise bevor WM_CREATE verarbeitet wurde (oder um die Tatsache auszugleichen, dass viele Fensterimplementierungen WM_CREATE direkt verarbeiten und gibt TRUE zurück und gibt es nicht an DefWindowProc weiter.)
WM_NCCREATE ist daher die Nachricht, auf die Sie reagieren sollten, wenn Sie eine Standardfensterprozedur implementieren, die eine Initialisierung durchführen muss, bevor der Fensterprozess des Benutzers die WM_CREATE-Nachricht verarbeitet. WM_NCCREATE MUSS auch an das entsprechende DefWindowProc weitergegeben werden, wahrscheinlich bevor Sie Ihre eigene Verarbeitung durchführen, da einige Aspekte der unteren Ebene des Fensters eindeutig in einem nicht initialisierten Zustand sind, bevor WM_NCCREATE verarbeitet wird.
Wenn Sie versuchen, die Erst-Look-Verarbeitung zu garantieren, ist dies NICHT der richtige Ort, um Ihre Fensterinitialisierung durchzuführen: Alle anderen Layer, die eine jist-in-time-Einrichtung über WM_NCCREATE haben, wurden durchgeführt in einem stabilen Zustand mit Dingen wie seinen Nicht - Client - Metriken, Bildschirmposition usw.
Oder: Wenn Sie nicht wissen, warum Sie WM_NCCREATE über WM_CREATE verwenden sollten, sollten Sie WM_NCCREATE nicht verwenden.
Nicht sicher, warum Sie eine Schaltfläche in der WM_NCCREATE erstellen - weil das Fenster, auf dem die Schaltfläche erscheint, noch nicht existiert, daher (glaube ich) die Destop-Koordinaten. WM_NCCREATE wird an Sie gesendet, wenn die "Nicht-Client" -Bereiche des Fensters erstellt werden (Nicht-Client-Bereiche wie Fensterrahmen, Titelleiste usw.)
Müssen Sie eine Schaltfläche im Nicht-Client-Bereich platzieren? Wenn die Antwort nein ist, warum nicht den Knopf innen erstellen? WM_CREATE.
Wenn Sie die Schaltfläche aus irgendeinem Grund in WM_NCCREATE erstellen müssen, warum speichern Sie nicht das Fensterhandle, das von Ihrem Createwindow () - Aufruf zurückgegeben wird. Dann greifen Sie in Ihrem WM_CREATE-Meldungshandler auf das Fenster-Handle dieser Schaltfläche und führen ein "MoveWindow (...)" mit dem Anwendungsfenster aus, in dem Sie jetzt Koordinaten haben sollten, wenn Sie sich im Meldungshandler WM_CREATE befinden.
Ich glaube, dass einer der Parameter, den Sie an Ihren CreateWindow-Aufruf (...) übergeben können, um die Schaltfläche zu erstellen, Ihnen erlaubt, eine 'SW _...' anzugeben. Flag, wie 'SW_HIDE', wenn der Speicher mir richtig dient. Also erstellen Sie, aber zeigen Sie nicht die Schaltfläche in WM_NCCREATE Handhabung, wenn Sie müssen, dann, wenn WM_CREATE kommt schnell danach, ein 'MoveWindow (.... Fenster Coords, ...... SW_SHOW, ......) etc. um den Knopf zu positionieren und sichtbar zu machen.