OnUpdate"
(da wir noch keine bestehende Methode haben).
Wir werden in den Codeeditor gesprungen und sehen eine neue Methode vor uns.
Folgende Codezeile wird eingefügt:
((CEdit *) this->GetDlgItem (IDC_EDIT_TEXT))->SetWindowText ( this->GetDocument ()->GetText());
Schritt 4: Dialog zufügen
Wir erzeugen eine Dialogklasse zum Eingeben eines Strings. Dazu z.B. im Contextmenü des "Projektmappen-Explorer"
die Option "Hinzufügen" -> "Klasse..." wählen. In dem Dialog wird in der Kategorie "MFC" die Option
"MFC-Klasse" gewählt.
Im nächsten Dialog folgende Einstellungen vornehmen:
Hier: wir geben einen Namen an und ändern die Basisklasse auf CDialog. Der Assistent schlägt automatisch
einen Namen für die Dialogfeld-Resource vor.
Wir plazieren ein Edit Control namens IDC_EDIT_TEXT im Dialog.
Dieses verknüpfen wir mit einer Membervariable, deren Wert automatisch von der MFC ins Textfeld
geschrieben wird. Hierzu Rechtsklick auf das Edit Control, im Contextmenü "Variable hinzufügen..." wählen.
In dem erscheinenden Assistenten gibt man links einen Variablen-Namen ein. Im rechten Teil
können wir wählen, mit welchem Control dieser Wert verknüpft werden soll. Da wir vom Textfeld
kommen, ist IDC_EDIT_TEXT bereits gewählt. Unter "Kategorie" müssen wir allerdings noch von
"Control" auf "Value" umschalten, da ansonsten nur eine Membervariable vom Typ "CEditControl"
angelegt würde. Durch Ändern der "Kategorie" wird links automatisch der "Variablentyp" geändert.
Aus Faulheit belassen wir die Variable auf "public".
Schritt 5: Dialog anzeigen
Auf der FormView einen Button "Edit" mit dem Namen IDC_BUTTON_EDIT plazieren. Einen
Handler für das Klick-Event zufügen. Hierzu gibt es verschiedene Möglichkeiten:
a) Rechtsklick auf den Button, "Ereignishandler hinzufügen...". Es erscheint folgender Dialog:
b) In den Eigenschaften auf den Button "Steuerelementereignisse" gehen und bei "BN_CLICKED" einen Handler zufügen.
In der so erzeugten Methode "OnBnClickedButtonEdit" folgendes einfügen:
MFCBasicsDialog* dialog = new MFCBasicsDialog(this);
dialog->m_Text = this->GetDocument()->GetText();
if (dialog->DoModal () == IDOK)
{
this->GetDocument()->SetText ( dialog->m_Text);
//Beim UpdateAllViews NULL übergeben, damit auch
//unser Fenster sein Update bekommt.
this->GetDocument()->UpdateAllViews (NULL);
}
//Speicher wieder freigeben.
delete dialog;
Natürlich muss vorher noch der Header des Dialogs eingebunden werden.
#include "MFCBasicsDialog.h"
Serialisierung
Hierzu die Methode "Serialize" unserer Document-Klasse so modifizieren:
void CMFCBasicsDoc::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
// TODO: Hier Code zum Speichern einfügen
ar << this->m_Text;
}
else
{
// TODO: Hier Code zum Laden einfügen
ar >> this->m_Text;
}
}
Fertisch !
Anmerkungen
Wenn man das Beispiel nicht mehr benötigt, sollte man die Registry ausmisten.
Welche Keys vom Programm erzeugt werden kann man in der Datei "MFCBasics.reg"
ablesen, die im Anwendungsverzeichnis liegt. Diese alle löschen !
Klassendiagramm
Hier gibt es das Klassendiagramm als Together-Architect-1.1-XML-Export (Default-Dateiformat-Option):
MFCBasics.xml
Es soll ein Unit-Test erfolgen, dieser soll einen ganzen Logikblock prüfen, nämlich ob das
Speichern und anschließende Laden des Documents korrekt implementiert ist.
Die Anleitung folgt im großen und ganzen den Anweisungen von Hr. Dreher. Es wird ein Projekt
namens "MFCBasicsTest" vom Anwendungstyp "Auf Dialogfeldern basierend" erstellt.
WICHTIGER HINWEIS: Im Gegensatz zu Hr. Drehers Anleitung habe
ich den Haken "Unicode-Bibliotheken verwenden", der im Default gesetzt ist, nicht entfernt.
Das bedeutet dass wir später eine andere Testrunner.dll referenzieren müssen !
Wie in Hr. Drehers Anleitung folgende Schritte erledigen:
- Falls noch nicht geschehen die Visual-Studio-Einstellungen vornehmen: Pfade zu den
CPPUnit-Includedateien, Bibliotheksdateien und Quelldateien angeben.
- Im Testprojekt den Verweis zu "MFCBasics" zufügen.
- Im Testprojekt die benötigten CPPUnit-Libraries und Object-Dateien konfigurieren.
Hier sind das:
C:\Temp\cppunit-1.11.6\lib\cppunitd.lib
C:\Temp\cppunit-1.11.6\lib\testrunnerud.lib
$(SolutionDir)\MFCBasics\$(ConfigurationName)\MFCBasicsDoc.obj
Wichtig: "trestrunnerud.lib", die Unicode-taugliche Library von CPPUnit !
Man beachte die etwas andere Notation des Pfads zur Object-Datei, durch das Verwenden des Makros
"($ConfigurationName)" funktioniert dieser Test auch im Release-Modus.
- Postbuild-Event eintragen. Auch hier die Unicode-Variante verwenden: trestrunnerud.dll
- Konstruktor von CMFCBasicsDoc public machen.
- In "CMFCBasicsTestApp" den Aufruf des Dialogs entfernen und stattdessen die
Initialisierung des Tests einbauen. CPPUnit-Headerdateien einbinden.
- Die Testfall-Klasse "CMFCBasicsTestCase" wird zugefügt, mit einer Membervariablen
CMFCBasicsDoc *fixture;
.
Die Implementierung sieht so aus:
CPPUNIT_TEST_SUITE_REGISTRATION(MFCBasicsTestCase);
void MFCBasicsTestCase::setUp()
{
this->fixture = new CMFCBasicsDoc();
}
void MFCBasicsTestCase::tearDown()
{
delete this->fixture;
}
void MFCBasicsTestCase::testSerialize()
{
//Datei zum Schreiben öffnen. Wenn nicht vorhanden dann
//soll sie erzeugt werden:
CString sFileName("Serialisiert.txt");
CFile file (sFileName, CFile::modeCreate | CFile::modeWrite);
//Ein CArchive zum Speichern erzeugen:
CArchive archiveStore (&file, CArchive::store);
//Testdaten ins Dokument:
CString sText("Hello World");
this->fixture->SetText (sText);
//Und Document speichern:
this->fixture->Serialize (archiveStore);
//Alles dicht machen:
archiveStore.Flush();
archiveStore.Close();
file.Close();
//Etwas anderes ins Document packen:
this->fixture->SetText(CString("Total anderes Zeug !"));
//Und Datei neu öffnen:
file.Open (sFileName, CFile::modeRead);
CArchive archiveLoad (&file, CArchive::load);
//Dokument laden:
this->fixture->Serialize (archiveLoad);
archiveLoad.Close();
file.Close();
//Inhalt prüfen:
//CPPUNIT_ASSERT(this->fixture->GetText() == sText);
//Inhalt prüfen mit individueller Fehlermeldung:
CPPUNIT_ASSERT_MESSAGE("Serialize/Deserialize failed", this->fixture->GetText() == sText);
}
- Jetzt können wir den Test laufen lassen. Einen fehlschlagenden Test erhält man wenn man im Serialize
der Document-Klasse zum Beispiel das Laden von "m_Text" aus dem CArchive entfernt.
Eine Übersicht über die CPPUnit-Prüfmakros findet man in der Doku übrigens in der Datei "group___assertions.html".
Version 1.2.1.0, Stand 16.04.2006
Historie:
1.0.0.0 Beispiel erstellt (02.04.2006).
1.1.0.0 Klassendiagramm (10.04.2006)
1.2.0.0 Unit-Test zugefügt (14.04.2006)
1.2.1.0 Alle Dateien mit DoxyGen-Kommentaren versehen (16.04.2006)