C++ und MFC
Dr. Erhard Henkes  (Stand: 02.08.2001)



Zurueck zum Inhaltsverzeichnis

Stichworte fuer diese Seite:

Einführung
Was macht eigentlich Windows aus?
Dialogbasierende Anwendung
Wiederfinden der Steuerelemente
Dateien im Arbeitsverzeichnis
Windows Styles



 
 

Vorwort

Wenn Sie dieses Tutorial gewählt haben, sind Sie offensichtlich entschlossen, Windows-Programme mit Hilfe der objektorientierten Sprache C++ und den Microsoft Foundation Classes (MFC) zu erstellen. Sie sind vielleicht noch verunsichert, da es für diesen Zweck z.B. auch die Sprachen Visual Basic, Delphi und Java gibt. Bleiben Sie bei Ihrer Entscheidung. Mit C++ stehen Ihnen von Konsolen- bis zu Windows-Anwendungen alle Programmier-Wege offen. C++ unterstützt durch die Programmierumgebung MS Visual C++ ist ein professionelles Werkzeug.

Die Programmiersprache C++ gründet auf C, das sich seit den siebziger Jahren bestens bewährt hat. C++ in Verbindung mit den sich kontinuierlich weiter entwickelnden Bibliotheken Win32-API (nicht objektorientiert) und MFC (objektorientiert)  ist eine Windows-Programmiersprache ständig wachsender Möglichkeiten, und genau da liegt auch das Problem für Sie als Programmierer.

Wenn Sie heute mit der Erkundung der MFC starten, liegt ein langer Weg vor Ihnen. Sie benötigen Zeit, Ausdauer und Geduld.
Schwer verständliche Fehlermeldungen von Compiler und Linker werden Ihren Weg in "düsteren" Stunden begleiten. Aber nur aus der Überwindung von Fehlern und der Bewältigung von Problemen erwächst wirkliche Stärke, und groß kann die innere Freude sein, wenn man die Klippe eines neuen Programmbausteins genommen hat.

Ein wesentlicher Vorteil der aktuellen MFC-Bibliothek besteht darin, daß der Quellcode zugänglich ist. Hier liegt oft die klarste Antwort auf viele Fragen. Auch der Debugger oder die Suche nach Definitionen führen direkt in die MFC.


 
  Zwei Sprüche sollen Ihren Weg begleiten:

 MFC: Macht für C++
 Nur in der Ruhe liegt die Kraft.

 Erhard Henkes


Einführung

In Zusammenhang mit dem Betriebssystem UNIX entstand 1972 die Programmiersprache C. Das Buch von
Kernighan und Ritchie "The C Programming Language" von 1977 (mit dem berühmten Gruß "hello, world")
und die Schaffung eines Standards durch das ANSI (American National Standards Institute) im Jahre 1987
waren Meilensteine. Unter Einbeziehung von Elementen der objektorientierten Programmierung (OOP) entwickelte
sich hieraus die Sprache C++.

Für das Betriebssystem MS Windows bietet Microsoft seit einigen Jahren das Programmierwerkzeug Visual C++
(z.Z. in der Version 6.0). Sie können hiermit von Assistenten und grafischen Editoren unterstützt die Sprachelemente
sowohl von C als auch von C++ einsetzen.

Wesentlicher Bestandteil von Visual C++ sind die Microsoft Foundation Classes (MFC), Microsofts objektorientierte
Klassenbibliothek für die Windows-Programmierung mit C++. Die MFC "umhüllen" die Funktionalität der
Application Programming Interface (API), die Sie in der MFC-Programmierung zusätzlich direkt einsetzen können und müssen.

Für den interessierten Einsteiger in Visual C++, der zunächst nicht den historisch vorgegebenen Weg über C- und C++ gehen will,
gibt es wenig leicht verständliche Literatur zum Einstieg in MFC. Das liegt meines Erachtens daran, daß man bei einem MFC-Einsteiger oft Vorkenntnisse in C, C++ bzw. Windows-Programmierung ohne MFC erwartet. Das vorliegende Tutorial unternimmt den Versuch, eine praktische Anleitung für Einsteiger oder Gelegenheits-Programmierer zu sein. An hoffentlich überschaubaren und leicht nachvollziehbaren Beispielen werden Sie ohne Umwege die Möglichkeiten der MFC-Programmierung kennenlernen.


Sie werden von Anfang an die in Visual C++ vorhandenen Assistenten einsetzen. MFC in Verbindung mit der grafischen Erstellung von Ressourcen erleichtern die Erstellung von Programmen erheblich und ermöglichen es, daß Einsteiger direkt für das Betriebssystem
MS Windows programmieren können. Für die Windows-Programmierung in C++ sollten Sie zumindest die grundlegenden
Sprachelemente und Kontrollstrukturen von C und C++ verstehen, um nicht ständig in Fehlersuche zu verharren.

Diese Grundlagen können Sie spielerisch und Schritt für Schritt im Rahmen der Windows-Programmierung erwerben.
An praktischen Beispielen lernen Sie die Vielfalt der Programm-Bausteine und das faszinierende Zusammenspiel von
C, C++,  API und MFC kennen. Lassen Sie uns beginnen.
 

Was macht eigentlich Windows aus?

In Windows-Programmen ist der Ablauf nicht streng vorgeben.

Nehmen wir folgendes Beispiel:
Der Anwender soll zwei Zahlen eingeben, die das Programm multipliziert.
Das Ergebnis wird auf dem Bildschirm ausgegeben.

Konsolen-Programme fragen über Tastatur die beiden Zahlen nacheinander ab,
kontrollieren die Eingaben auf Plausibilität, führen die mathematische Verknüpfung durch
und geben das Ergebnis anschließend auf dem Bildschirm aus, etwa wie folgt:

Computer über Bildschirm: Benutzer mittels Tastatur:
------------------------------------------------------------------------------------------------------------------
Bitte erste Zahl eingeben: (Eingabe 1)

Bitte zweite Zahl eingeben: (Eingabe 2)

Das Ergebnis ist (Eingabe 1 * Eingabe 2)
 

Der Benutzer kann nicht Eingabe 2 vor Eingabe 1 eingeben. Wird gerade Eingabe 2 abgefragt,
kann man nur diese Eingabe durchführen und nicht noch rasch Eingabe 1 korrigieren.
Dies nennt man ablauforientierte Programmierung. Solche Anwendungen kann man z.B.
mit C oder C++ (auch unter Windows) im DOS-Fenster erstellen
(MS Visual C++ bietet solche Möglichkeiten mittels Win32-Konsolenanwendungen).

In MS Windows erfolgen Abfragen dagegen nicht streng nacheinander.
In sogenannten Dialogfenstern werden ohne strenge Abfolge die notwendigen Eingaben entgegen genommen,
nicht systematisch abgefragt. Die Verknüpfung erfolgt nicht automatisch nach der letzten Eingabe,
sondern der Anwender leitet den nächsten Schritt jeweils selbst ein (typischerweise mit OK, WEITER oder FERTIG).
Er kann Eingaben einer Stufe durch "Abbrechen" zunichte machen. Korrekturen sind in der Regel leicht möglich.

Windows-Programmierer haben den Anwender (User) inzwischen an gewisse Darstellungen und Routinen gewöhnt,
die er nun auch von Ihren Programmen erwartet. Bei der Erstellung von Windows-Anwendungen sollte man daher
bezüglich der Benutzerführung nicht zuviel Kreativität walten lassen, sondern die gewohnte Windows-Umgebung bieten.
Damit kann der Anwender intuitiv reagieren, und das Programm erweckt Vertrauen.

Hier bietet Ihnen Visual C++ die notwendigen professionellen Standards.
Im ersten Kapitel werden Sie zwei wesentliche Elemente von MS Windows erforschen,
das "Fenster" (Window) und die Bedienung mit der "Maus".

---------------------------------------------------------------------------------------------------------------------------------------------------------------

 
 
 
 
 
 
 

Kapitel 1 - Einstieg in MFC und Windows

1.1 Dialogbasierende Anwendung

Wesentliche Bestandteile von Windows sind die auf dem Bildschirm angezeigten Fenster (Windows) und die z.B. durch Benutzeraktionen ausgelösten internen Nachrichten (Messages). Daher beginnen wir mit diesen beiden Elementen der Windows-Programmierung. Sie werden die sogenannte Integrierte Entwicklungsumgebung (IDE) und den mitgelieferten MFC-Anwendungs-Assistenten von Anfang an einsetzen. Gleichzeitig werden wir den Direkteinstieg in den hiermit erzeugten Code wagen. Sie sollen das Zusammenspiel von Ressourcen, Source-Dateien und MFC-Klassen verstehen lernen, damit Sie gezielt in der Fülle von Dateien und Klassen agieren können. In Visual C++ erstellen Sie keine einfache Datei, sondern ein ganzes Projekt, das in einem gleichnamigen Ordner mehrere Dateien umfaßt.

Sie starten nun Ihr erstes Projekt, eine sogenannte "dialogfeldbasierende" Anwendung. Diese besitzt eine relativ einfache Datei- und Klassenstruktur und ist daher zum Einstieg ideal geeignet.

Starten Sie bitte MS Visual C++ und zur unabhängigen Datei-Überwachung den MS Explorer.
 

Vorbereitender Schritt:

Nach dem Start wählen Sie den Menü-Befehl "Datei / Neu" (Strg + N).
Hinweis: Bitte nicht mit dem Toolbar-Befehl "Neue Textdatei" verwechseln.
Es erscheint der Startbildschirm zur Erstellung neuer Projekte.
Wählen Sie "MFC-Anwendungs-Assistent (exe)".
Im Eingabefeld Projektname fügen Sie "DialogEins" und im Eingabefeld Pfad den gewünschten Pfad ein.
Bitte beachten Sie, daß standardmäßig "Neuen Arbeitsbereich erstellen" und die Plattform "Win32" aktiviert ist.
Das könnte dann wie folgt aussehen:

Abb.1.1: Einstiegsbildschirm zur Auswahl des zu erstellenden Projektes

Zum Abschluß bestätigen Sie die Auswahl mit einem Klick auf den OK-Button.

MFC-Anwendungs-Assistent Schritt 1:

Die Frage "Welche Art von Anwendung wollen Sie erstellen?" beantworten Sie durch Auswahl von "Dialogfeldbasierend" (Übersetzung von Dialog based). Dieser einfache Anwendungs-Typ ist für unsere ersten Experimente bestens geeignet. Klicken Sie nun auf "Weiter >".

MFC-Anwendungs-Assistent Schritt 2:

Beseitigen Sie alle Häkchen, damit ein möglichst einfaches Windows-Anwendungsgerüst resultiert. Also weg mit Dialogfeld "Info", 3D- und ActiveX-Steuerelemente. Wir benötigen auch keine Hilfe, keine Automatisierung und keine Windows-Sockets. In diesem Schritt können Sie den Titel des Dialogfeldes ändern. Geben Sie bitte "Mein erster Dialog" ein.
Es sollte nun wie in Abb. 1.2 aussehen:

Abb. 1.2: Wir erstellen eine abgemagerte Dialog-Anwendung

Klicken Sie bitte auf "Weiter >".

MFC-Anwendungs-Assistent Schritt 3:

Hier führen Sie keine Änderungen durch. Der Assistent versieht das Programm mit Kommentaren.
Klicken Sie bitte auf "Weiter >".

MFC-Anwendungs-Assistent Schritt 4:

Der Assistent kündigt an, daß er die Klassen CDialogEinsApp und CDialogEinsDlg erstellen wird. Als Namen schlägt er folgende Zusammenziehung vor: C + Projektname + Klassen-Typ. Das C steht für Class, App für Application und Dlg für Dialog. Sie können die Klassennamen ändern. Dies sollten Sie jedoch unterlassen, damit Ihre MFC-Anwendungen von Anfang an vergleichbar sind. Jetzt noch ein Klick auf "Fertigstellen", und der Anwendungs-Assistent liefert eine Zusammenfassung. Nach einem letzten OK wird das Projekt "DialogEins" erstellt. Nun geht der Ball an Sie zurück.

Sie befinden sich nun in der Arbeitsumgebung zur Windows-Programmierung.

Toggles für:                          Arbeitsbereich  Ausgabe  Fensterliste

Abb. 1.3: Ausschnitt aus der Menüleiste

Der Bildschirm zeigt neben dem Menü zwei Bereiche: den Arbeitsbereich und die Fensterliste.

Der Arbeitsbereich (linkes Feld) dient zur Übersicht über Klassen, Ressourcen und Dateien. Im Arbeitsbereich trifft man die Auswahl, die Fensterliste (rechtes Feld) zeigt dann die entsprechenden Inhalte. Da wir eine Dialog-Anwendung entwickeln wollen, zeigt der Assistent im Arbeitsbereich bereits auf die Ressourcen (Dialog, Icon, Menu, Toolbar, Bitmap, ...).

In der Fensterliste sehen Sie eine Standard-Dialog-Vorlage mit einem Textfeld, einem OK- und Abbrechen-Button, die Sie verändern/ergänzen sollen. Hierzu steht ein Werkzeugkasten mit der Überschrift "Steuerelemente" bereits bereit. An dieser Stelle erkennen Sie deutlich, was das "Visual" in Visual C++ für Ihre Programmierarbeiten bedeutet. Sie müssen nicht alles durch Tastatureingaben ("Codieren") festlegen, sondern können zumindest beim Editieren von Ressourcen im wesentlichen mit der Maus agieren, also grafisch unterstützt programmieren.

Wichtiger Hinweis: Üben Sie vorsorglich das Wiederfinden des "Werkzeugkastens" mit den Steuerelementen (bei Verlust). Klicken Sie rechts oben auf das "X". Nun ist der Werkzeugkasten weg. Ein Mausklick, der Zeit und Nerven kosten kann. Das Wiederfinden der Steuerelemente ist nämlich deutlich schwieriger: Bewegen Sie die Maus in die oberste Menüleiste rechts neben das Fragezeichen. Klicken Sie mit der rechten Maustaste in den freien Bereich. Ein Auswahlmenü erscheint (dies funktioniert auch bei MS Office). Aktivieren Sie "Steuerelemente", und der Werkzeugkasten ist wieder da. Prägen Sie sich diesen Rechts-Klick gut ein, denn in den Menüs suchern Sie vergebens.

Abb. 1.4: Die Arbeitsumgebung zur Erstellung von Dialogfeldern

Wir könnten jetzt leicht eine Dialog-Anwendung mit einer Vielzahl von Steuerelementen entwerfen und diese zum Funktionieren bringen.
Dies ist für einen Einsteiger jedoch nicht der richtige Weg zur sicheren Beherrschung der Materie.
Bevor wir den Werkzeugkasten munter einsetzen, nutzen wir zunächst die Möglichkeit, genauer zu analysieren,
was der hilfsbereite und flinke Assistent bisher erzeugt hat.
 

Hierzu setzen wir den Windows-Explorer ein. In dem von Ihnen angegebenen Pfad hat der Assistent ein Verzeichnis mit dem Projektnamen (DialogEins) angelegt, das z.Z. folgende Dateien und Verzeichnisse ("Debug" ist noch leer) umfaßt:

Abb. 1.5: Die vom Assistenten erzeugten Dateien

Sie sehen, daß selbst unsere vom Design her einfache Anwendung bereits zu einer großen Zahl von Dateien führt.
Dies ist sicher einer der Gründe, warum viele Autoren objektorientiertes Programmieren mit C++ nicht mit Windows-Programmen einüben, sondern einfache Konsolenanwendungen vorziehen. Auf diese Weise läßt sich der Programmcode leicht in ein oder zwei Dateien unterbringen. Da wir jedoch MFC-Windows-Programme erstellen wollen, müssen wir uns sofort mit dieser Dateivielfalt anfreunden. Nachdem der Assistent seine Aufbauarbeit geleistet hat, die wir jederzeit rasch wiederholen könnten, werden wir einen kleinen Ausflug in die erzeugten Dateien unternehmen. Lassen wir MS Visual C++ selbst sprechen. Wir beginnen mit der Textdatei ReadMe.txt.
Sie finden hier folgendes (in Auszügen):

Diese DialogEins-Anwendung hat der Klassen-Assistent für Sie erstellt. ... Diese Datei enthält die Zusammenfassung der Bestandteile aller Dateien, die Ihre DialogEins-Anwendung bilden.

DialogEins.dsp
Diese Datei (Projektdatei) enthält Informationen auf Projektebene und wird zur Erstellung eines einzelnen Projekts oder Teilprojekts verwendet. ...

DialogEins.h
Hierbei handelt es sich um die Haupt-Header-Datei der Anwendung. Diese enthält andere projektspezifische Header (einschließlich Resource.h) und deklariert die Anwendungsklasse CDialogEinsApp.

DialogEins.cpp
Hierbei handelt es sich um die Haupt-Quellcodedatei der Anwendung. Diese enthält die Anwendungsklasse CDialogEinsApp.

DialogEins.rc
Hierbei handelt es sich um eine Auflistung aller Ressourcen von Microsoft Windows, die vom Programm verwendet werden. Sie enthält die Symbole, Bitmaps und Cursors, die im Unterverzeichnis RES abgelegt sind. Diese Datei lässt sich direkt in Microsoft Visual C++ bearbeiten.

DialogEins.clw
Diese Datei enthält Informationen, die vom Klassen-Assistenten verwendet wird, um bestehende Klassen
zu bearbeiten oder neue hinzuzufügen. Der Klassen-Assistent verwendet diese Datei auch, um Informationen
zu speichern, die zum Erstellen und Bearbeiten von Nachrichtentabellen und Dialogdatentabellen benötigt
werden und um Prototyp-Member-Funktionen zu erstellen.

res\DialogEins.ico
Dies ist eine Symboldatei, die als Symbol für die Anwendung verwendet wird. Dieses Symbol wird durch die Haupt-Ressourcendatei DialogEins.rc eingebunden.

res\DialogEins.rc2
Diese Datei enthält Ressourcen, die nicht von Microsoft Visual C++ bearbeitet wurden.
In diese Datei werden alle Ressourcen abgelegt, die vom Ressourcen-Editor nicht bearbeitet werden können.

DialogEinsDlg.h, DialogEinsDlg.cpp - das Dialogfeld
Diese Dateien enthalten die Klasse CDialogEinsDlg. Diese Klasse legt das Verhalten des Haupt-Dialogfelds
der Anwendung fest. Die Vorlage des Dialogfelds befindet sich in DialogEins.rc ...

StdAfx.h, StdAfx.cpp
Mit diesen Dateien werden vorkompilierte Header-Dateien (PCH) mit der Bezeichnung DialogEins.pch
und eine vorkompilierte Typdatei mit der Bezeichnung StdAfx.obj erstellt.

Resource.h
Dies ist die Standard-Header-Datei, die neue Ressourcen-IDs definiert.
Microsoft Visual C++ liest und aktualisiert diese Datei.

...

Zunächst prüfen wir, ob der Assistent in seiner Auflistung auch alle Dateien beschreibt, die der Explorer zeigt. Neben den oben beschriebenen finden wir folgende Dateien, die er nicht in "ReadMe.txt" aufführt. Alle drei Dateien lassen sich problemlos mit einem Texteditor (z.B. dem Notizblock oder WordPad im Windows-Zubehör) öffnen:

DialogEins.aps:
Binäre Version der aktuellen Ressourcenskriptdatei; wird zum schnellen Laden verwendet.
Hier haben wir nichts verloren.

DialogEins.ncb:
Zugang mit dem Texteditor nur bei geschlossenem Arbeitsbereich möglich.
Also absolutes Sperrgebiet für uns, da hier ständig Details unseres Projektes dokumentiert werden.

DialogEins.opt:
Interne Aufzeichnungen über unser Projekt. Hier dürfen wir ebenfalls nichts ändern.

DialogEins.dsw:
Innerhalb dieser Datei finden wir folgenden Hinweis:
"WARNUNG: DIESE ARBEITSBEREICHSDATEI DARF NICHT BEARBEITET ODER GELÖSCHT WERDEN!"
Also ebenfalls nichts für uns. Diese Datei ist beim Starten des Projektes mit dem Explorer
jedoch die ideale Startdatei, die den gesamten Arbeitsbereich mit allen notwendigen Dateien öffnet.
Eine Verknüpfung auf dem Desktop direkt zu dieser Datei bietet eine komfortable Verbindung
zu Ihrem aktuellen Arbeitsbereich.

Hinweis: In MS Visual C++ organisieren Sie Projekte in einem Arbeitsbereich.
Ein Arbeitsbereich kann mehrere Projekte enthalten, jeweils mit Unterprojekten oder abhängigen Projekten.

Das Unterverzeichnis .../Debug bzw. .../Release wartet auf die binären Erzeugnisse von Compiler und Linker, ist also im Moment noch leer.

Im Unterverzeichnis .../res findet man zur Zeit zwei Dateien:

DialogEins.ico (32*32-Pixel-Icon mit MFC-Darstellung):

DialogEins.rc2: Öffnet man diese Datei mit einem Texteditor, so liest man folgendes:

// DIALOGEINS.RC2 - Ressourcen, die Microsoft Visual C++ nicht direkt bearbeitet
#ifdef APSTUDIO_INVOKED
#error this file is not editable by Microsoft Visual C++
#endif //APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
// Fügen Sie hier manuell bearbeitete Ressourcen hinzu...
/////////////////////////////////////////////////////////////////////////////

Nachdem Sie jetzt über die vom Assistenten erzeugte Dateistruktur einen ersten Überblick erhalten haben, kehren Sie zur grafischen Arbeitsumgebung von Abb. 1.4 zurück. Jetzt üben Sie das Schließen und Wiederöffnen des Arbeitsbereiches:

Schließen Sie bitte mittels Menü "Datei / Arbeitsbereich schließen".
Die Frage, ob alle Dokumentfenster geschlossenen werden sollen, beantworten Sie mit ja.

Das Öffnen des Arbeitsbereiches erfolgt über das Menü mit "Datei / Arbeitsbereich öffnen". Durch Auffinden und Öffnen der Datei DialogEins.dsw befinden Sie sich wieder in der Arbeitsumgebung. Einfacher geht es übrigens mit dem Menübefehl "Datei / Zuletzt geöffnete Arbeitsbereiche" über Auswahl von ...DialogEins.

Bleiben Sie bitte neugierig, und untersuchen Sie im Arbeitsbereich alle bereits jetzt vorhandenen (also noch nicht von uns erzeugten) Ressourcen. Öffnen Sie bitte den gesamten Baum durch Anklicken. Folgende Ressourcen sind vorhanden:

IDD_DIALOGEINS_DIALOG ist der Name des Dialogfeldes. Durch Doppelklicken darauf gelangen Sie in der
Fensterliste zu der Ressource, die man dort auch bearbeiten kann.

IDR_MAINFRAME zeigt auf ein 32*32-Pixel-Icon, das die Buchstaben MFC (Microsoft Foundation Class)
grafisch verarbeitet (siehe oben). Probieren Sie an diesem Icon den mitgelieferten einfachen Grafik-Editor aus.
Nach Änderungen kann man grundsätzlich "Datei / Speichern" (Strg + S) oder "Datei / Alle Speichern" anwenden.

VS_VERSION_INFO beinhaltet Versions-Informationen, die vom Assistenten erzeugt wurden.
 

Sie werden nun probeweise kompilieren und linken: Dies erfolgt mittels Taste F7 oder über das Menü mit "Erstellen / DialogEins.exe erstellen". Nur Mut! Es sollte nichts schiefgehen, da Sie bisher keine eigenen und damit evtl. fehlerhaften Dinge eingebaut haben. Die Frage nach dem Neuerstellen der Datei "...\Debug\DialogEins.exe" beantworten Sie bitte mit ja. Die Festplatte surrt, das Ausgabefeld (unten) öffnet sich und begleitet den Compiler- und Linker-Vorgang mit folgenden Meldungen:
 

--------------------Konfiguration: DialogEins - Win32 Debug--------------------

Ressourcen werden kompiliert...
Kompilierung läuft...
StdAfx.cpp
Kompilierung läuft...
DialogEins.cpp
DialogEinsDlg.cpp
Generieren von Code...
Linker-Vorgang läuft...
DialogEins.exe - 0 Fehler, 0 Warnung(en)

0 Fehler, 0 Warnung(en):

Das klingt nach Erfolg! DialogEins.exe wurde offensichtlich erzeugt.

Die in das Unterverzeichnis Debug kompilierten Programme sind nicht unbedingt alleine lauffähig.
Dies erfolgt erst durch Kompilierung in das Verzeichnis Release. Die Umstellung zwischen Dateiausgabe in das
Projekt-Unterverzeichnis Debug bzw. Release erfolgt über das Menü Erstellen / Aktive Konfiguration festlegen.
 
 
 Hinweis:
 Zur Erstellung einer exe-Datei bedarf es folgender Arbeitsvorgänge, die hier kurz skizziert  werden:

 resource.h 
 xxx.h       --- C++-Compiler ---------> xxx.obj
 xxx.cpp

 xxx.rc      --- Ressourcen-Compiler --> xxx.res

 xxx.obj
 xxx.res     --- Linker ---------------> xxx.exe
 yyy.lib


 

Der Arbeitsbereich bietet nun folgendes Bild:

Abb. 1.6: Nach dem ersten Testlauf: DialogEins.exe - 0 Fehler, 0 Warnung(en)

Durch Kompilieren und Linken ist nun DialogEins.exe entstanden.
Starten Sie dieses Programm mit Strg + F5 (oder über das Menü Erstellen).
Auf dem Bildschirm sehen Sie unsere vom Assistenten erzeugte Anwendung:

Abb. 1.7: Die erste Anwendung stellt sich vor

Sollten Sie das 32*32-Pixel-Icon bereits verändert haben, so sehen Sie jetzt den in Windows vorgesehenen Einsatzort: Links neben dem Titel "Mein erster Dialog" findet sich dieses Icon, das auch in der Taskleiste eingesetzt wird. Betrachten Sie bitte das erzeugte Fenster mit all seinen Elementen und Funktionen im Detail, da wir zum besseren Verständnis gezielt Änderungen an diesem Fenster vornehmen werden.

Nach dem Start wird unser Dialogfenster in der Bildschirmmitte plaziert. Durch Festhalten der Titelleiste mit der linken Maustaste kann man das Fenster beliebig verschieben (ziehen). Die Anwendung schließt direkt durch Anklicken des OK-Buttons, des Abbrechen-Buttons und des "X" rechts oben. Durch Anklicken des Icons links oben öffnet sich ein Popup-Menü, das zwei Menü-Punkte hat: Verschieben und Schließen. Rechnet man noch Strg + F4 hinzu, so können Sie das Fenster auf mindestens fünf verschiedene Arten schließen, um damit die Anwendung zu beenden. Das Fenster kann interessanterweise nicht in der Größe verändert, nach unten geklickt (minimiert) oder auf volle Größe (maximiert) gebracht werden. Ein Rand ist vorhanden. Man kann ihn jedoch nicht mit der Maus ziehen, um die Größe zu verändern.

Neben den beiden Buttons mit der Aufschrift "OK" und "Abbrechen" muß es in der Mitte des Window noch ein Feld geben, das den Text "ZU ERLEDIGEN: Dialogfeld-Steuerelemente hier plazieren." darstellt. Wir erkennen jedoch keine Abgrenzung dieses Textfeldes (Der Rand ist unsichtbar).

Nachdem wir nun die Standard-Dialog-Anwendung des Anwendungs-Assistenten ausreichend untersucht haben, gehen wir weiter. Wie kann man z.B. den Titel "Mein erster Dialog", den Text in der Mitte oder das Erscheinungsbild (das Fenster) der Anwendung ändern? Wie kann man eine Unterscheidung zwischen dem Abbruch durch "OK" und "Abbrechen" treffen?

Zuerst suchen wir in der Arbeitsumgebung (zum Arbeiten sollte man die Ausgabe im unteren Bildschirmbereich schließen, um mehr Platz zu haben) nach dem Titel unserer Dialog-Anwendung. An zwei Stellen werden wir fündig:

Öffnen Sie unter Ressourcen im Ordner Dialog die Ressource IDD_DIALOGEINS_DIALOG und klicken Sie mit der rechten Maustaste auf die Titelleiste. Sie erhalten ein Menü, in dem Sie bitte "Eigenschaften" auswählen. Daraufhin öffnet sich ein weiteres Fenster, in dem man umfangreiche Einstellmöglichkeiten bezüglich verschiedener Bezeichnungen und Formate hat:

Abb. 1.8: Eingabefelder für Eigenschaften des Dialoges

Geben Sie bitte einen anderen Titel ein, um die sofortige Wirkung zu beobachten. Noch während Sie den Titel eingeben, zeigt das rechte Fenster den aktualisierten Dialog. Jetzt öffnen Sie bitte (ohne zu speichern) mit einem Texteditor (z.B. Notizblock oder Wordpad aus dem Windows-Zubehör) die Datei DialogEins.rc. Im Abschnitt mit Überschrift "Dialog" finden sich folgende Eintragungen:

IDD_DIALOGEINS_DIALOG DIALOGEX 0, 0, 320, 200
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_APPWINDOW
CAPTION "Mein erster Dialog"
FONT 8, "MS Sans Serif", 0, 0, 0x1
BEGIN
DEFPUSHBUTTON "OK",IDOK,260,7,50,14
PUSHBUTTON "Abbrechen",IDCANCEL,260,23,50,14
LTEXT "ZU ERLEDIGEN: Dialogfeld-Steuerelemente hier plazieren.",
IDC_STATIC,50,90,200,8
END

Hier ist noch der ursprüngliche Titel "Mein erster Dialog" eingetragen, wenn Sie nicht gespeichert haben.
Schauen wir die vom Assistenten generierten Zeilen genauer an:

IDD_DIALOGEINS_DIALOG DIALOGEX 0, 0, 320, 200

Hier findet sich der Name IDD_DIALOGEINS_DIALOG, der der Dialogressource zugeordnet wurde. Die Ausdehnung 320 * 200 (Breite und Höhe in Dialogfeldeinheiten) wird hier festgelegt. Dies sind keine Bildschirm-Pixel. Die dargestellte Größe hängt von der Schriftgröße (Font Size) ab. Das "EX" in DIALOGEX bietet gegenüber der älteren Ressourcenskript-Anweisung DIALOG erweiterte Möglichkeiten an. In unserem Fall könnte hier jedoch ebenso das ältere "DIALOG 0, 0, 320, 200" stehen.

Üben Sie hier bitte das Aufrufen der Hilfe (? / Index) unter Eingabe des Suchbegriffes "DIALOGEX" (Gesammte Sammlung anwählen). Die Hilfe steht Ihnen übrigens nur zur Verfügung, wenn Sie MSDN (Microsoft Developer Network)Library aufgespielt haben.

Man findet unter "DIALOGEX Resource" ausführliche Hinweise auf die erweiterten Möglichkeiten, die für uns momentan jedoch nicht wichtig sind. Wesentlich ist in jedem Fall das Verständnis der notwendigen Syntax eines Befehls, in unserem Fall:

nameID x,y,width,height

Die nameID ist IDD_DIALOGEINS_DIALOG. In der Hilfe findet man diesbezüglich:

nameID: Identifies the dialog box. This is either a unique name or a unique 16-bit unsigned integer value in the range 1 to 65,535.
Wie ist dies nun konkret in unserer Anwendung? Die Antwort findet man in der vom Assistenten angelegten Datei resource.h.
Für unsere Dialog-Anwendung steht dort:

#define IDD_DIALOGEINS_DIALOG 102
#define IDR_MAINFRAME 128

Windows verwendet also zur Identifizierung der Dialogressource den Wert 102. Mittels der Präprozessor-Anweisung #define wird hier dieser Zahl die symbolische Konstante IDD_DIALOGEINS_DIALOG zugeordnet. Diese symbolischen Konstanten dienen der besseren Verständlichkeit von Programmtexten. IDR_MAINFRAME ist übrigens der Name für das MFC-ICON.

Benutzen Sie die Hilfe möglichst oft, damit Sie sich an den leider etwas umständlichen Erklärungsstil gewöhnen, denn Sie finden hier sehr detaillierte Ausführungen und entsprechende Querverweise.

Gehen wir im Ressourcenskript weiter:

STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU

Hier werden verschiedene Window Styles (WS), das heißt Eigenschaften des Fensters festgelegt. WS_CAPTION bedeutet, daß das Fenster eine Titelzeile hat. WS_SYSMENU liefert das Menü links oben und das "X" rechts oben, mit dem man die Anwendung einfach beenden kann. Die senkrechten Striche sind bitweise ODER-Verknüpfungen der verschiedenen Window Styles.

EXSTYLE WS_EX_APPWINDOW
EXSTYLE ist die erweiterte Version von STYLE (siehe oben) und definiert WS_EX_... .

CAPTION "Mein erster Dialog"
CAPTION legt die Titelzeile des Fensters fest.

FONT 8, "MS Sans Serif", 0, 0, 0x1
Die zu verwendende Schrift wird hier vorgegeben: MS Sans Serif der Größe 8 ist die Standardschrift der 32-bit-Windowsversionen.

BEGIN
DEFPUSHBUTTON "OK",IDOK,260,7,50,14
PUSHBUTTON "Abbrechen",IDCANCEL,260,23,50,14
LTEXT "ZU ERLEDIGEN: Dialogfeld-Steuerelemente hier plazieren.",
IDC_STATIC,50,90,200,8
END

Zwischen BEGIN und END erhält unser Dialog seine innere Dekoration:

Wir haben jetzt gesehen, daß wir mit dem grafischen Ressourcen-Editor eine Ressourcenskriptdatei (.rc) und die Datei resource.h erzeugen. Der Explorer zeigt Ihnen im Projekt-Unterverzeichnis "Debug" die Datei DialogEins.res, eine binäre Datei, die vom Ressourcen-Compiler aus dieser Ressourcenskriptdatei (.rc) erzeugt wurde.

Nachdem Sie den Ausgangszustand der Ressourcenskriptdatei mit dem Texteditor ausführlich untersucht haben, können Sie ein wenig experimentieren. Die Vorgehensweise wird folgendermaßen sein: Wir verändern unser Dialogfenster im grafischen Ressourcen-Editor und speichern (Strg + S) die Ressource jeweils unter DialogEins.rc. Anschließend öffnen wir die Datei mit einem Texteditor und überprüfen das Ergebnis. Sie können natürlich auch einfach hier mitlesen. Insgesamt geht es darum, ein erstes grundlegendes Verständnis für die Konstruktion von Fenster-Ressourcen zu erhalten.

Da wir an einer möglichst einfachen Anwendung interessiert sind, entfernen wir den OK- und Abbrechen-Button (einfach das jeweilige Steuerelement anklicken und die Taste "Entf" drücken) und ändern das Textfeld (rechte Maus, Eigenschaften, Text-Eigenschaften / Formate: für "Text ausrichten" die zentrierte Darstellung wählen) in der Mitte auf "Hallo Welt !!!" (die Titeländerung erfolgt unter "Text-Eigenschaften / Allgemein" im Eingabefeld "Titel"). Dies ist ein notwendiges Anfänger-Erfolgserlebnis. Das muß aus historischen Gründen (vgl. das Buch von
Kernighan und Ritchie "The C Programming Language" von 1977 mit dem berühmten Gruß "hello, world") zumindest einmal sein. Das könnte dann in DialogEins.rc (mit Texteditor öffnen) folgendermaßen aussehen:

IDD_DIALOGEINS_DIALOG DIALOGEX 0, 0, 320, 200
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_APPWINDOW
CAPTION "Neuer Titel"
FONT 8, "MS Sans Serif"
BEGIN
CTEXT "Hallo Welt !!!",IDC_STATIC,50,90,200,8
END

Wir haben einen neuen Titel, die beiden Buttons sind weg, und CTEXT bedeutet zentrierter Text. Jetzt bitte speichern (Strg + S), kompilieren und starten (Strg + F5). Jetzt "grüßt" Ihr Rechner die "Welt".

Im nächsten Schritt vereinfachen wir das Dialog-Fenster weiter: Das "X" oben rechts soll verschwinden. Also zurück zum grafischen Ressourcen-Editor. Rechtsklick auf die Titelzeile nach Auswahl von Eigenschaften in Dialog-Eigenschaften | Formate. Bitte Auswahl "Systemmenü" deaktivieren. Zur Übung bitte alles speichern und starten. Schon ist das "X" (SYSMENU bzw. Systemmenü) beseitigt.

Unser weiter vereinfachtes Dialogfenster sieht nun - hoffentlich auch bei Ihnen - wie folgt aus:

Abb. 1.9: Dialog-Window mit Titelleiste und statischem Textfeld

Immerhin können wir das Window noch mit der linken Maustaste verschieben. Vorhin hatten wir doch noch (mindestens) vier Möglichkeiten zum Schließen, und nun? Mit dem "X" ist auch das Icon (und damit auch das Menü zum Verschieben/Schließen) verschwunden. Aber es gibt noch die fünfte Möglichkeit: Alt+F4. Das ist der bekannte Tastatur-Befehl zum Schließen von Windows-Anwendungen.

Die Datei DialogEins.rc sieht jetzt so aus:

IDD_DIALOGEINS_DIALOG DIALOGEX 0, 0, 320, 200
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION
EXSTYLE WS_EX_APPWINDOW
CAPTION "Neuer Titel"
FONT 8, "MS Sans Serif"
BEGIN
CTEXT "Hallo Welt !!!",IDC_STATIC,50,90,200,8
END

Wie Sie sehen ist nur WS_SYSMENU verschwunden. Jetzt entfernen Sie auch noch WS_CAPTION: Im Ressourcen-Editor (an bereits bekannter Stelle) deaktivieren Sie jetzt noch die Titelleiste. Nach dem Kompilieren und Starten verbleibt, wie erwartet, ein ziemlich trostloses "Hallo Welt"-Fenster:

Abb. 1.10: Dialog-Window ohne Titelleiste mit statischem Textfeld

Dieses Fenster können Sie mit Alt+F4 schließen. Jetzt haben Sie bereits eine Menge über den Aufbau von Fenstern gelernt. Aus Interesse ein erneuter Blick in DialogEins.rc:

IDD_DIALOGEINS_DIALOG DIALOGEX 0, 0, 320, 200
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE
EXSTYLE WS_EX_APPWINDOW
...

Trotz des bereits autistischen Fensters finden wir noch den Eintrag "STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE". Zunächst benutzen wir wieder den Ressourcen-Editor. Unter Dialog-Eigenschaften / Weitere Formate können wir noch "Sichtbar" deaktivieren. Auf geht’s. Strg + S und Strg + F5.

Wir stellen keine Veränderung fest. Das Fenster startet nach wie vor sichtbar (visible). WS_VISIBLE legt fest, ob ein bestimmtes Fenster von Anfang an sichtbar ist oder nicht. Ist dies nicht der Fall, muß man das Fenster im Programm mit ShowWindow(...) bzw. bei Dialogen mit DoModal() explizit sichtbar machen. Da es sich bei unserem Dialogfeld gleichzeitig um das Hauptfenster handelt erledigt der Assistent dies für uns:

BOOL CDialogEinsApp::InitInstance()
{
...
CDialogEinsDlg dlg;
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();
...
}

Hinweis:
Bitte beachten Sie die objektorientierte Programmierung. Man erstellt ein Objekt der Klasse CDialogEinsDlg namens dlg mittels:
CDialogEinsDlg dlg;
Die eigentliche Darstellung dieses Objektes erfolgt durch die Member-Funktion (Methode) CDialog::DoModal() :
dlg.DoModal();

Nun nehmen wir dem Fenster auch noch den Rahmen. Unter Eigenschaften / Formate in der Auswahlliste Rand stellen wir "Keine" ein. Jetzt sind alle Möglichkeiten der Deaktivierung verbraucht. Nach dem Starten sieht man, es geht noch primitiver, nämlich ohne Rand.

Der Blick mit dem Texteditor in DialogEins.rc:

IDD_DIALOGEINS_DIALOG DIALOGEX 0, 0, 320, 200
STYLE WS_POPUP
EXSTYLE WS_EX_APPWINDOW
...

"DS_MODALFRAME" wurde im Ressourcenskript entfernt. Als letzter Rest bleibt "WS_POPUP" und "EXSTYLE WS_EX_APPWINDOW". Wenn Sie diese beiden Styles im Ressourcenskript streichen würden und erneut starten, sehen Sie keine Veränderung.

Nachdem Sie das Dialog-Fenster auf eine graue Fläche ohne Rand reduziert haben, öffnen Sie DialogEins.rc mit Hilfe des Texteditors und verändern die Dimensionen direkt im Texteditor auf "IDD_DIALOGEINS_DIALOG DIALOGEX 0,0,150,150". Das heißt, Sie programmieren übungshalber direkt im Ressourcenscript. Bitte speichern. Bei der Rückkehr zu VC++ empfängt Sie dann folgende Abfrage:

Abb. 1.11: Abfrage nach externen Änderungen von Dateien

Sie sehen, daß "Microsoft Developer Studio" sorgsam über die Dateien unseres Projektes wacht. Wir wollen, daß unsere manuellen Änderungen übernommen werden. Daher antworten wir mit ja.

Nachdem Sie das vom Assistenten erzeugte Window systematisch "abdekoriert" und hierbei gesehen haben, wie externe Änderungen des Ressourcenscriptes vom Microsoft Developer Studio behandelt werden, wechseln wir wieder in den Text-Editor, um im Ressourcenscript die Voraussetzungen für die kommenden Aufbauarbeiten zu leisten.
 

Wir bauen unseren Dialog völlig neu auf:

Wir werden jetzt das Dialogfenster über das Ressourcenskript komplett neu aufbauen. Hierbei verwenden wir nicht DIALOGEX, sondern DIALOG. Wir verändern die Schriftgröße auf 10. Ändern Sie das Ressourcenscript (nur im Bereich Dialog) mit dem Texteditor komplett wie folgt ab (achten Sie bitte auf die Großschrift):

IDD_DIALOGEINS_DIALOG DIALOG 0, 0, 150, 150
STYLE WS_POPUP
FONT 10, "MS Sans Serif"
BEGIN
END

Die Angabe STYLE WS_POPUP ist hier nötig, da ansonsten automatisch der Kombi-Typ WS_POPUPWINDOW (= WS_POPUP | WS_BORDER | WS_SYSMENU) erzeugt wird. Das Systemmenü wird dann nur nicht angezeigt, solange WS_CAPTION noch fehlt. WS_BORDER ergibt einen dünnen Rand. Ebenso dürfen Sie BEGIN und END nicht weglassen. Ansonsten hagelt es Fehlermeldungen.

Beim Abspeichern bitte den Namen nicht verändern. Es muß bei "DialogEins.rc" bleiben. Nach Übernahme in unser Projekt und Kompilieren/Linken/Starten stellt diese einfache Dialog-Ressource jetzt ein quadratisches, rahmenloses Fenster ohne jede Dekoration dar. Schließen des Fensters ist nur mit Alt+F4 möglich:

Abb. 1.12: Eine sehr einfache Dialog-Ressource

Diese Ressource ist nun wie ein reines Betonfundament (die graue Farbe paßt gut!) ohne Schnörkel. Sie werden nun ausgehend hiervon Aufbauarbeit leisten. Als Werkzeug benutzen Sie von nun an natürlich den grafischen Ressourcen-Editor. Den Texteditor werden wir nur noch zur Analyse des Ressourcenscripts verwenden.

Der Neuaufbau beginnt: Zunächst ein Klick der rechten Maustaste nach Eigenschaften / Dialog Eigenschaften / Formate:

Geben Sie für Stil "Überlappend", für Rand "Dialogfeldrahmen" ein und aktivieren Sie Systemmenü, Minimieren- und Maximieren-Schaltfläche (Abb. 1.13):

Abb. 1.13: Der Neuaufbau der Dialog-Ressource beginnt

Nach Strg + S zeigt uns der Texteditor folgendes Bild im Ressourcenscript:

IDD_DIALOGEINS_DIALOG DIALOG DISCARDABLE 0, 0, 150, 150
STYLE DS_MODALFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_CAPTION | WS_SYSMENU
FONT 10, "MS Sans Serif"
BEGIN
END

DISCARDABLE ist ein Attribut der Ressource DIALOG. Es erlaubt Windows, die Ressource bei Platzproblemen aus dem Arbeitsspeicher zu entfernen. Dieses Attribut ist ein Überbleibsel aus der 16-bit-Zeit. Für moderne 32-bit-Anwendungen ist DISCARDABLE bedeutungslos. Sie könnten es bedenkenlos mit dem Texteditor löschen.

Im nächsten Schritt wechseln wir nach "Eigenschaften / Dialog Eigenschaften / Allgemein" und geben einen neuen Titel ein. Den Schriftnamen (Font) belassen wir bei MS Sans Serif, ebenso den Schriftgrad (Font Size) bei 10:

Abb. 1.14: Hier können wir einen neuen Titel (Caption) für unser Dialogfenster eingeben

Jetzt wechseln wir nach "Eigenschaften / Dialog Eigenschaften / Erweiterte Formate" und aktivieren die Auswahl "Client-Kante".
Mit Strg + S und Strg + F5 erhalten wir einen Eindruck von unserer Anwendung:

Abb. 1.15: Der neugeschaffene Dialog mit Client-Kante

Ein Blick mit dem Texteditor in das Ressourcenscript zeigt folgendes:

IDD_DIALOGEINS_DIALOG DIALOGEX 0, 0, 150, 150
STYLE DS_MODALFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_CLIENTEDGE
CAPTION "Neuaufgebauter eigener Dialog "
FONT 10, "MS Sans Serif"
BEGIN
END

Sie sehen jetzt auch, was sich hinter "Erweiterte Formate" verbirgt. Dort finden sich erweiterte (= neue) Window Styles wie das ausgewählte "WS_EX_CLIENTEDGE".

Nachfolgend finden Sie für eigene Experimente eine Auswahl von Windows Styles und ausgewählte WS_EX Styles (hier finden Sie z.B. die von uns verwendete "Client-Kante" = CLIENTEDGE). Sie finden weitere Styles in der Hilfe (MSDN):

Sie müssen diese Begriffe natürlich nicht auswendig lernen, sollten sich aber an die englischen Begriffe gewöhnen,
da Sie diese in der Hilfe bzw. in der (englischen) Fachliteratur finden.

Hier geht's weiter Zum Nächsten Kapitel

Zurueck zum Inhaltsverzeichnis