Neulich im http://www.c-plusplus.de/forum/ fand sich folgende Empfehlung:
XYZ schrieb:
Schreibe knapp vor der MAIN MESSAGE LOOP:
C/C++ Code:
PostMessage(DeinHandle,WM_CREATE,NULL,NULL); //oder so ähnlich vielleicht noch mit Instanz
while //MAIN MESSAGE LOOP
Ich staunte nicht schlecht. Grund für diesen Holzhammer war, dass „angeblich“ die Nachricht WM_CREATE, von Windows nicht verschickt wird. Also helfen wir einfach etwas nach und versenden diese selber.
Das sich dieser Code verbietet ist klar und ich will hier gar nicht weiter darauf eingehen warum.
Aber es bringt mich zum Thema:
Es ist eine beliebte Unsitte Windows Nachrichten, die nur für das interne Zusammenspiel der Komponenten und als „Benachrichtigungen“ dienen, selber zu versenden.
Favoriten hier sind oft WM_SETFOCUS, WM_PAINT, WM_SIZE, WM_KEYDOWN und manche andere.
Und Windows macht es dem Programmierer nicht einfach. In den Anfangszeiten von Windows wurde zu wenig bei der Namensgebung darauf geachtet, welche Nachrichten mehr oder weniger Aktionen auslösen und Eigenschaften setzen (z.B. WM_SETFONT) und welche Nachrichten als Notifications des OS dienen einem Programm mitzuteilen, dass etwas passiert ist, oder geschehen soll (z.B. WM_CREATE, WM_PAINT, WM_SETFOCUS, WM_SIZE, WM_ACTIVATE etc.).
Vieles wäre einfacher, wenn man Anhand des Nachrichtenamens erkennen würde, dass diese Nachricht vom OS versendet wird und damit nicht für den Eigenbedarf bestimmt ist.
Die letzte Gruppe der Nachrichten steht hier oft in einem direkten Zusammenhang mit einer API-Funktion (CreateWindow, UpdateWindow, SetFocus, SetWindowPos, SetActivteWindow etc.). Mit in diese Kategorie fällt, der Versuch mit WM_KEY… Nachrichten Tastatureingaben zu simulieren was auch nur in Ausnahmefällen korrekt funktioniert.
Mit der Einführung der neuen Common Controls, wurde hier nachgebessert. Sicherlich auch weil WM_COMMAND als Benachrichtigungs Medium etwas schmalbrüstig ist. WM_NOTIFY wurde eingeführt
Dieser Schritt war gut. Interessanter Weise habe ich noch niemals den Versuch gesehen solche Notifications zu simulieren. Obwohl dies hier auch kein Problem wäre, denn es gibt hier keine API Funktionen, die Konfliktpotential anbieten würden.
Häufigster Grund solch einer Versuchung nachzugeben eine Nachricht selbst zu versenden, ist oft einfach Unwissen über die Windows-API. Und Eingangs erwähnte ich es schon: Die Dokumentation ist oft genug nicht eindeutig und macht zu selten auch Hinweise auf die entsprechenden verbundenen API Funktionen, siehe Doku zu WM_SETFOCUS in der wir nichts zu SetFocus lesen, außer in der Fußnote für See also. Erst die Doku der SetFocus API-Funktion gibt Aufschluss, dass diese Nachricht durch SetFocus versendet wirdund damit in gewisser Weise intern ist. Windows führt Buch welches Fenster den Fokus hat, aber dieser wird eben durch SetFocus gesetzt und nicht durch WM_SETFOCUS!
Fazit: Verurteilen kann man diese Unsitte schwer, außer mit dem Hinweis: „Es wurde nicht korrekt in der Doku gelesen, RTFM (Read the fine MSDN)“. Allerdings ist für Anfänger die MSDN oft genug einfach nur mehr erschlagend als informativ.
Dennoch kommt man nicht umhin sorgfältig auf die Zusammenhänge von Nachrichten und API-Funktionen zu studieren. Das bedeutet in diesem Zusammenhang, gerade die Dokumentationen der Funktionen, Nachrichten und Methoden zu lesen, die in der Fußnote unter See also aufgeführt werden. Oft genug findet man auf diesem Weg die Zusammenhänge (oft etwas mühsam) heraus.
Anmerkung: Die Dokumentation der MFC mach das Ganze leider noch schlimmer, denn hier werden nur kurze Auszüge der Windows-API wiedergegeben, die leider oft genug nicht detailliert genug sind. Hier ist immer angeraten, hinter einer virtuellen On… Funktion einen Windows Nachrichten Handler zu vermuten und in der Windows API noch einmal genauer nachzulesen. Allerdings macht sie auch einiges wiederklarer, denn sie kapselt die WM_… Nachrichten, die als Methoden/Getter/Setter funktionieren direkt in eigenständigen Memberfunktionen. Aber auch hier empfiehlt es sich nachzusehen was unter See also steht.