Zurueck zum Inhaltsverzeichnis

Zurück

1.2 Unser Dialog empfängt und verarbeitet Nachrichten

Nachdem wir jetzt ein "brauchbares" Dialog-Fenster vorliegen haben, wenden wir uns dem nächsten Schritt zu, nämlich der in Windows so wichtigen Nachrichtenverarbeitung. Schauen wir uns unsere Dialoganwendung aus Abb. 1.15 diesbezüglich genauer an. Worauf reagiert unser Fenster? Bisher reagiert unsere Anwendung für uns erkennbar nur auf das Anklicken der von uns hinzugefügten Fenster-Elemente wie z.B. MINIMIZEBOX, MAXIMIZEBOX, SYSMENU.

Klickt man in die von der hübschen Client-Kante eingerahmte graue Fläche, dann passiert nichts. Was müssen wir unternehmen, damit hier eine Aktion erfolgt? Zunächst müssen wir die Nachricht "linke Maustaste gedrückt" in unser Programm einbinden.

Dieser Nachricht (Message) müssen wir anschließend eine Member-Funktion zuordnen, die als Reaktion auf die Nachricht ausgelöst wird.
Zum Schluß müssen wir diese Funktion mit Quellcode füllen, damit auch wirklich etwas passiert.

Bisher haben wir uns mit den Ressourcen beschäftigt. Nun wechseln wir im Arbeitsbereich zu den mittels MFC erstellten Klassen unserer Anwendung. Wir verwandeln alle "+" in "-", um den kompletten Klassen-Aufbau zu sehen:


Abb. 1.16: Klassenansicht der beiden DialogEins-Klassen

Das Projekt umfaßt zwei Klassen: CDialogEinsApp und CDialogEinsDlg.

Die Klasse CDialogEinsApp besitzt zwei Member-Funktionen (Methoden):
den Konstruktor CDialogEinsApp() und
die Funktion InitInstance().

Die Klasse CDialogEinsDlg besitzt fünf Member-Funktionen und eine Member-Variable (Attribut):
den Konstruktor CDialogEinsDlg(...),
DoDataExchange(...),
OnInitDialog(),
OnPaint(),
OnQueryDragIcon() und
m_hIcon.

Die Klassenansicht zeigt symbolhaft den Zugriffsstatus auf Member-Variablen bzw. Member-Funktionen an:


 Hinweis zur objektorientierten Programmierung (OOP):

 Klassen sind nichts anderes als "Baupläne" für Objekte. 
 Klassen enthalten Member-Funktionen (Methoden) und  Member-Variablen (Attribute). 
 Der "Bau" der Objekte erfolgt in der Konstruktor-Funktion (kurz. Konstruktor). 
 Der Konstruktor hat den gleichen Namen wie die Klasse. 

 Der Zugriff auf Funktionen und Variablen wird bei deren Deklaration erledigt: 
 public, protected oder private. 

 Bei private kann nur von innerhalb der Klasse zugegriffen werden. 
 Bei public kann man auch von außen auf die Daten der Klasse zugreifen. 
 Bei protected können abgeleitete Klassen von außen zugreifen.
 

Hier müssen wir in die richtige Klasse eine Funktion zur Reaktion auf den Mausklick einfügen.
Wie machen wir das? Genau wie bei den Ressourcen gibt es hier den sogenannten Klassen-Assistenten.
Wie ruft man diesen auf? Im Menü findet sich ein Zauberstab. Wenn Sie den Pfeil rechts daneben anklicken,
öffnet sich folgendes Menü (Auch über Strg + W erreichbar bzw. Ansicht /Klassen-Assistent):

Abb. 1.17: Der Klassen-Assistent bietet seine Hilfe an

Wählen Sie hier bitte "Behandlungsroutine für Windows-Nachrichten hinzufügen".

Abb. 1.18: Der Klassen-Assistent bietet eine Fülle von Nachrichten an

Wir wählen nun links unter "Neue Windows-Nachrichten/-Ereignisse" WM_LBUTTONDOWN aus.
Dann drücken wir rechts auf "Behandlungsroutine hinz(ufügen)". Der Assistent fügt die gewünschte Nachricht WM_LBUTTONDOWN zu den bereits vorhandenen Nachrichten WM_PAINT und WM_INITDIALOG (in der Mitte) hinzu. Damit haben wir unser Programm auf diese Nachricht vorbereitet.

Nun ordnen wir sofort eine Funktion zu. Da wir die Nachricht bereits hinzugefügt haben, drücken wir auf "Vorhandene bearbeiten" (hierbei muß WM_LBUTTONDOWN ausgewählt sein). Jetzt springt der Assistent direkt in die Funktion "CDialogEinsDlg::OnLButtonDown(UINT nFlags, CPoint point)". Der Assistent hat diese Funktion angelegt. Ein Blick nach links auf die Klassenansicht zeigt die neue Funktion in der Klasse CDialogEinsDlg. Jetzt müssen wir nur noch etwas bewirken, sprich programmieren.
 

1.3 Textausgabe mit TextOut()

Geben Sie bitte nach der Kommentarzeile folgendes ein:

Abb. 1.19: Punkt hinter Objekten öffnet eine Auswahlliste für Funktionen und Datenelemente

Mit "CClientDC dc(this);" definieren wir einen sogenannten Gerätekontext (Device Context), der die Rolle der Schnittstelle zwischen Programm und Bildschirmausgabe übernimmt. Das erzeugte Objekt dc (der Name ist frei wählbar) besitzt eine große Menge von Funktionen (natürlich automatisch durch MFC vorgegeben), die wir sofort einsehen können, sobald wir in der zweiten Zeile den Punkt hinter dc eintippen.
Ein Listenfeld klappt auf, das uns eine breite Auswahl bietet (auch hier spürt man etwas vom "Visual" des MS VC++).

Wir wollen Text ausgeben und wählen daher per Doppelclick die Funktion "TextOut" aus.
Sobald wir anschließend eine öffnende runde Klammer hinter TextOut eingeben, erhalten wir die nächste Information:

Abb. 1.20: Eingabe der Klammer hinter Funktionsnamen öffnet eine Parameterliste

Sie sehen, VisualC++ läßt uns nicht im Stich, sondern stellt kontextbezogene Informationen zur Verfügung.
Wir geben in dieser Zeile folgendes ein:
 
 dc.TextOut( point.x, point.y, "linke Maustaste" );

Achten Sie bei der Eingabe von Programmcode bitte auf alle Klammern, Kommas und Semikolons. Da ist C++ besonders empfindsam.
Wir benützen als x- und y-Ausgabe für den Text die von der Funktion übergebenen Mauskoordinaten, die in point als Elemente point.x und point.y enthalten sind. Wenn Sie alles richtig gemacht haben, dann erhalten Sie nach dem Speichern und Kompilieren eine Anwendung, die auf das Niederdrücken der linken Maustaste im sogenannten Client-Bereich des Fensters wie folgt reagiert:

Abb. 1.21: Unser "Fenster" reagiert auf die Nachricht WM_LBUTTONDOWN mit einer Textausgabe

Dieses Beispiel demonstriert Ihnen, daß es nicht schwierig ist, eigene Nachrichten-Behandlungs-Funktionen in eine Klasse einzubauen.
In welche Klasse haben wir eigentlich unsere Funktion eingebaut?
Ein Blick in den Arbeitsbereich beantwortet diese Frage sofort:

Abb. 1.22: Die Nachricht WM_LBUTTONDOWN startet die Funktion OnLButtonDown(...)

OnLButtonDown(...) ist eine Funktion der Klasse CDialogEinsDlg. Wenn Sie mehr über diese Klasse wissen wollen,
führen Sie einfach einen Doppelklick auf den Klassennamen CDialogEinsDlg aus.

Im rechten Fenster sehen wir daraufhin die Header-Datei "DialogEinsDlg.h". Diese Datei enthält die Definition der Klasse CDialogEinsDlg,
die von der MFC-Klasse CDialog abgeleitet wurde. CDialog ist wiederum abgeleitet von CWnd, der MFC-Basisklasse für Fenster.

Hinweis:
Die gesamte (Vererbungs-)Hierarchie sieht wie folgt aus:

CObject
  CCmdTarget
    CWnd
      CDialog
        CDialogEinsDlg

Die Klasse CDialogEinsDlg enthält im Bereich "Generierte Message-Map-Funktionen" die Deklaration der von uns hinzugefügten Funktion OnLButtonDown(...). Der Assistent hat dies für uns hier eingefügt. In diesem Bereich wollen wir nichts ändern, da wir neue Datenelemente oder Funktionen nicht mit dem Texteditor, sondern mit dem Klassen-Assistenten eingeben wollen. Der Assistent kennzeichnet seine Bereiche durch seine graue Handschrift, die er mit (grünen) AFX...-Kommentaren eingrenzt. Das ist für uns im Normalfall Sperrgebiet, obwohl der Assistent uns bereitwillig zu all den Stätten seines Wirkens führt. Man vertraut uns eben.

Das Fenster mit all seinen Ausstattungen ist bis zum Schließen der Anwendung stabil. Wenn man das Fenster mit der Maus z.B. teilweise über den Bildschirmrand hinaus schiebt und dann wieder zurück zieht, dann gehen keine Details oder Funktionen verloren. Auch nach dem Minimieren (Ablegen) und Wiederaufrufen besitzt das Fenster noch all seine Details (Rahmen, Titel, Buttons, Farbe). Anders ist dies mit dem von uns erzeugten Text. Dieser ist nicht stabil gespeichert, sondern vergänglich. Schieben Sie nach einigen Mausklicks (über das gesamte Fenster verteilt) das Fenster zur Hälfte über den Bildschirmrand hinaus. Nach dem Zurückziehen könnte Ihr Fenster dann wie folgt aussehen:

Abb. 1.23: Der in OnLButtonDown(...) ausgegebene Text ist vergänglich.

Unser Gerätekontext leitet seine Ausgaben direkt an das Fenster. Nach dem Verschwinden dieser Informationen können diese beim Wiederaufbau des Fensters nicht mehr berücksichtigt werden.
 
 

Hier geht's weiter Zum Nächsten Kapitel

Zurueck zum Inhaltsverzeichnis