Heute möchte ich einmal über Windows-Messages schreiben.
Bei der Programmierung von Windows-Anwendungen hat man immer wieder damit zu tun.
Im Gegensatz zu Consolen-Anwendungen reagieren Windows-Anwendungen auf Ereignisse. Diese Ereignisse werden üblicherweise durch Messages dem Programm mitgeteilt.
Jede Maus-Bewegung oder jeder Tastendruck ist ein Ereignis, dem verschiedene Messages zugeordnet sind. Aber es gibt noch viel mehr, etliche hundert. Ich werde mich hier aber auf eine Handvoll der wichtigsten beschränken.
Generische Windows-Programmierung ist prozedural. Verbreitet sind jedoch Frameworks, die die Behandlung in Objekten kapseln.
Ich muss mich wirklich zurückhalten, um nicht zu ausführlich und spitzfindig zu werden. Die hier lesenden Entwickler mögen mir verzeihen, wenn ich nicht alle Einzelheiten berücksichtige.
Wie auch immer – Betriebssystem und Anwendungen tauschen Messages aus. Das läuft etwa über den Befehl sendmessage. Dieser nimmt als Parameter das Handle des Fensters, die Art der Message und zusätzliche Werte, die die Message genauer definieren und Daten übergeben, und gibt ein Ergebnis zurück, dem man im einfachsten Fall entnehmen kann, ob die Verarbeitung der Message fehlerlos abgelaufen ist.
Jedes Fenster kreist in einer Schleife („wndproc“), in der die Queue der eingehenden Messages abgearbeitet wird.
Wichtige Botschaften sind etwa das Anzeigen/Verstecken oder Aktivieren/Deaktivieren eines Fensters. Mouse- und Tastaturereignisse hatte ich bereits erwähnt. Ein Fenster muss auch wissen, wann es sich selbst zeichnen muss, wenn sich seine Größe oder Position ändert, oder wenn es der Nutzer schließen will, und muss dann entsprechend reagieren.
Der Entwickler hat die Möglichkeit, sich in jede einzelne Ereignisroutine einzuklinken. Windows liefert zwar eine Default-Behandlung, aber wenn man etwas besonderes will, muss man das ausdrücklich programmieren.
Nicht nur ein ganzes Anwandungsfenster ist ein Fenster, sondern es kann aus einer ganzen Hierarchie weiterer Fenster bestehen. So ist jede Schaltfläche ein Fenster, genauso wie es ein Eingabefeld ist.
Jedes Kontrollelement hat spezifische Messages. Ein Eingabefeld bietet beispielsweise die Möglichkeit, über eine Message den Text auszulesen oder zu setzen.
Wer ein gut durchdachtes, intuitives Windows GUI erstellen will, kommt nicht um die Kenntnis der wichtigsten Messages herum (auch wenn sie in diversen Frameworks so gekapselt sind, dass man das nicht mehr direkt merkt).
RAD-Umgebungen vereinfachen das Positionieren und Konfigurieren der visuellen Elemente, so dass sich der Entwickler auf die Programmieraufgaben konzentrieren kann, die hinter der Benutzeroberfläche geschehen sollen.
Kommt drauf an, in welcher Sprache man entwickelt. Für meine WPF-Anwendungen arbeite ich mit dem MVVM-Konzept – da gibt es keine Messages zwischen den Fenstern, sondern die Daten werden via Databinding ans Viewmodel gekoppelt und die Kommunikation läuft in Commands innerhalb des Viewmodels oder über EventListeners.
Du schreibst vermutlich Deine Applikationen in C++, oder?
LikeLike
Du nutzt eben ein Framework (WPF).
Ich normalerweise auch, aber hin und wieder ergibt sich trotzdem die Notwendigkeit, die Default-Behandlung zu überschreiben, oder Messages zu nutzen, die vom Framework nicht unterstützt werden.
Dann hol‘ ich mir mit getwindowlong einen Funktionspointer auf die wndproc des Fensters, und hänge meine eigene Callback-Routine ein.
LikeLike
Ah. OK. Hab ich noch nie gebraucht. Meine Applikationen laufen im Normalfall in einem MainWindow, das verschiedene Container enthält, nicht in vielen Windows, die sich gegenseitig Nachrichten schicken müssten.
LikeLike
Trotzdem muss auch dein Mainwindow auf Nutzer-Aktionen reagieren, und die kriegt es über Messages mit.
Darum kümmert sich halt das WPF.
OT: Hast du mitgekriegt, wie auf https://auschfrei.wordpress.com/2017/05/02/auf-editionf_com-von-_die_sara-wie-ich-das-programmieren-fuer-mich-entdeckt-habe/ über HTML-„Programmiererinnen“ rumgelästert wird? 😈
LikeLike
Ja – aber dafür nutze ich in der Regel (eigene) Commands im ViewModel oder TriggerEvents.
Den Eintrag hatte ich gelesen, aber nicht die Kommentare. Ich bin grad wieder an meiner Webapplikation (ASP.NET) und krieg bei dem HTML-Gepröbel regelmässig die Krise.
LikeLike
Kennst du eigentlich den Spy++? Der ist (oder war?) Bestandteil des Windows SDK, und man kann mit ihm anschauen, welche Messages ein bestimmtes Fenster kriegt.
LikeLike
Ja – kenn ich. Mit dem durfte ich mich schon bei diversen Firmen und Legacy-Code rumschlagen.
Jetzt muss ich mich nur noch mit eigenem Code rumschlagen 🙂
LikeLike
Aha.
Gibt es davon noch eine Fortsetzung?
LikeLike
Ist eigentlich nicht geplant.
Aber – wer weiß – vielleicht bringe ich irgendwann ein ähnliches Thema.
LikeLike
Pingback: Computer – was tut er? //1601 | breakpoint
Pingback: Lenztweets //1735 | breakpoint
Pingback: breakplaining: Klick! //1801 | breakpoint
Pingback: Der Hölle entkommen //2521 | breakpoint