Mittwoch, 14. März 2012

WndProc() überschreiben

Das Betriebssystem Windows arbeitet ereignisorientiert, dass heißt, Programme fragen nicht laufend den Zustand bestimmter Systemvariablen ab, sondern werden durch Ereignisse (Nachrichten) ggf. über deren Veränderung informiert.

In diesem Post möchte ich zeigen, wie man die Funktion, welche vom Betriebssystem an die C# Applikation gesandte Nachrichten abfängt, überschreibt, und so in diesen Verarbeitungsprozess eingreifen kann.

Die erwähnte Funktion nennt sich WndProc() und ist Teil jeder Form Klasse. Während die Anwendung läuft, sendet Windows sehr viele Nachrichten an die Anwendung, WndProc() nimmt sie entgegen. Windows benachrichtigt unser Programm quasi über alles, was irgendwie von Interesse sein könnte, vom Bewegen des Mauszeigers über das Aktivieren einer anderen Anwendung bis zum Klick auf den Schließen Button des Formulars. Im Grunde genommen sind alle Aktionen, die der Benutzer auf dem Formular durchführt, Ereignisse, die von Windows registriert, verarbeitet und dann erst der Anwendung zurückgeschickt werden, sodass diese sie dann verarbeiten kann. Der Anwendungsfall, dass der Benutzer auf das "X" zum Schließen unserer C# Anwendung klickt, ruft demnach in etwa folgende Aktionskette hervor: Windows erkennt einen Mausklick im Bereich unserer Anwendung, schickt dieses Ereignis an die Anwendung, welche anhand der Position erkennt, dass "X" gedrückt wurde und sich selbst beendet.

Soviel zur Theorie, nun zur praktischen Umsetzung: Wie schon erwähnt ist WndProc() bereits eine Funktion aus der Form Klasse, wir müssen diese also überschreiben, was mit dem Schlüsselwort override geschieht.
Tippen wir in der Entwicklungsumgebung die ersten Zeichen der Signatur
protected override void WndProc(ref Message m) ein, ergänzt C# dieses zu

protected override void WndProc(ref Message m)
{
    base.WndProc(ref m);
}

Die hinzugefügt Code Zeile besagt, dass nach Durchlauf unserer nun geänderten Funktion die Originalfunktion aufgerufen wird.
Löscht man diese Zeile, kann die Anwendung überhaupt nicht starten, da nun alle Ereignisse in unserer neuen Funktion "enden" und nicht verarbeitet werden.

Um eine Ahnung dafür zu kriegen, welche und wie viele Ereignisse empfangen werden, kann man z.B. eine ListBox dem Formular hinzufügen und folgende Zeile in der Funktion ergänzen: listBox1.Items.Add(m.ToString());

Dieser Post ist nun offensichtlich ganz abstrakt gehalten, ich hoffe bald aber einige interessante Anwendungen zeigen zu können, die sich über dieses Prinzip realisieren lassen.

Nachtrag: Im nächsten Post wird gezeigt, wie man mit dieser Funktion erkennt, ob sich Hardwareeinstellungen geändert haben.
Damit kann man zum Beispiel prüfen ob eine CD eingelegt oder ein USB-Stick eingesteckt wurde.

Kommentare:

  1. konntest du vlt mal ein Post machen wie man mit wndproc z.b. mausbewegungen oder tastertureingaben abfragen kann

    AntwortenLöschen
  2. Hi joker,
    ich kann mal schauen wenn ich Zeit habe, ist sicherlich auch interessant die Frage.
    Du kannst aber auch schonmal selber z.B. obigen Tipp umsetzen und dir alle auftretenden Ereignisse ausgeben, dann siehst du wie die entsprechenden Ereignisse heißen welche dafür zuständig sind (z.B. WM_MOUSEMOVE, WM_SETCURSOR etc.).

    AntwortenLöschen