C++
und MFC
Dr. Erhard
Henkes
(Stand: 02.08.2001)
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++ |
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.rc --- Ressourcen-Compiler --> xxx.res xxx.obj
|
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:
#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:
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):