Beispiel 3: Splitter-Window
Inhalt:
Schritt 1: Anwendungsgerüst
Schritt 2: Zweite FormView zufügen
Schritt 3: Splitter anpassen
Schritt 4: Code für Verschieben von Daten zwischen Views
Dieses Beispiel zeigt die Verwendung einer Splitter-Window mit zwei Form-Views.
Hier gibt es das Beispiel zum Download: Splitter.zip
Schritt 1: Anwendungsgerüst
Das Erstellen des Anwendungsgerüsts (SDI-Anwendung) erfolgt wie in den bisherige Beispielen,
das Projekt heißt "Splitter".
Im Schritt "Benutzeroberflächenfeatures" aktivieren wir die Checkbox "Geteiltes Fenster":
Im letzten Schritt "Generierte Klassen" wählen wir als View-Basisklasse "CFormView" und benennen sie in
"CSplitterLeftView" um (Zusatz "Left", da wir auch eine rechte FormView anlegen).
Beim Umbenennen auch die .h- und .cpp-Datei umbenennen !
Um dem Styleguide zu folgen sollten auch die Dateien zu Document- und MainFrame-Klasse mit dem Präfix "C" versehen werden !
Dummerweise gibt Visual Studio der Resource als Default den Projekt-Namen statt des Datei-Namens.
Deshalb wählen wir die Ressource in der Ressourcenansicht
und gehen in die Eigenschaften. Hier ändern wir den Namen auf "IDD_SPLITTERLEFTVIEW".
In "CSplitterLeftView.h" ändern wir den Namen der enum für den Dialogfeld-Namen:
public:
enum{ IDD = IDD_SPLITTERLEFTVIEW };
Schritt 2: Zweite FormView zufügen
Im "Projektmappen-Explorer" dem Projekt eine neue Klasse zufügen ("Hinzufügen -> Klasse...").
Als Typ der Klasse wird "MFC-Klasse" gewählt.
Eine neue FormView namens "CSplitterRightView" zufügen. Dateinamen werden wieder mit dem Präfix "C" versehen.
Schritt 3: Splitter anpassen
In MainFrm.cpp wechseln, Methode "OnCreateClient". Hier wird der Befehl "return m_wndSplitter.Create ..." entfernt und
durch folgendes ersetzt:
BOOL bolReturn = TRUE;
bolReturn = this->m_wndSplitter.CreateStatic (this, 1, 2);
SIZE size;
size.cx = 300;
size.cy = 300;
bolReturn = bolReturn && this->m_wndSplitter.CreateView (0, 0, RUNTIME_CLASS (CSplitterLeftView), size, pContext);
bolReturn = bolReturn && this->m_wndSplitter.CreateView (0, 1, RUNTIME_CLASS (CSplitterRightView), size, pContext);
return bolReturn;
Außerdem müssen die Headerdateien der Views eingebunden werden:
#include "CSplitterRightView.h"
#include "CSplitterLeftView.h"
Aus mir unbekannten Gründen trat nach diesem Schritt in "CSplitterLeftView" ein Compilefehler auf,
ich mußte noch in "CSplitterLeftView.h" (also in der Header-Datei der vom Anwendungsassistenten generierten View-Klasse)
die Header-Datei des Documents einbinden:
#include "SplitterDoc.h"
Schritt 4: Code für Verschieben von Daten zwischen Views
Auf den beiden FormViews jeweils ein Textfeld IDC_EDIT_LEFT bzw. IDC_EDIT_RIGHT und einen
Button "Nach rechts verschieben" (IDC_BUTTON_LEFT) bzw. "Nach links verschieben" (IDC_BUTTON_RIGHT).
In "CSplitterDoc" eine Membervariable "m_sText" sowie Get- und Set-Methode dafür zufügen (siehe Beispiel "MFCBasics").
Achtung, hier könnte der Visual-Studio-Bug mal wieder zuschlagen, der dafür sorgt dass die Variable sowie die beiden
Funktionen private werden obwohl letztere im Assistenten als "public" gewählt wurden.
Wir benutzen in beiden Views den DataExchange-Mechanismus für das Setzen/Auslesen der Textfelder.
Deshalb in jeder View das Textfeld anklicken und im Contextmenü "Add Variable..." wählen.
In beiden Views ein BN_CLICKED-Event für den "Nach xyz"-Button zufügen. In der linken View mit diesem Code:
//Text auslesen:
this->UpdateData (TRUE);
//In Document schreiben:
this->GetDocument()->SetText (this->m_sText);
//Sich selbst vom Update-Event ausschließen:
this->GetDocument()->UpdateAllViews(this);
Für die rechte View (die nachträglich zugefügte) gibt es keine automatisch generierte typsichere Methode "GetDocument",
deshalb müssen wir hier die Rückgabe von "GetDocument" auf "CSplitterDoc" casten.
//Text auslesen:
this->UpdateData (TRUE);
//In Document schreiben:
((CSplitterDoc*) this->GetDocument() )->SetText (this->m_sText);
//Sich selbst vom Update-Event ausschließen:
this->GetDocument()->UpdateAllViews(this);
Außerdem muss der Header der Document-Klasse eingebunden werden:
#include "CSplitterDoc.h"
Abschließend in beiden FormViews die Methode "OnUpdate" überladen und folgenden Code einfügen:
//Aktuellen Text aus Document holen und in Membervariable packen.
this->m_sText = this->GetDocument ()->GetText();
//Jetzt in Textfeld schreiben:
this->UpdateData (FALSE);
In der rechten View muss das Document auf "CSplitterDoc" gecastet werden.
Version 1.0.0.1, Stand 15.05.2006
Historie:
1.0.0.0 (23.04.2005) Beispiel zugefügt.
1.0.0.1 (14.05.2006) Kleine Ergänzung in Abschnitt 3.