TN026: DDX- und DDV-Routinen
Hinweis |
---|
Der folgende technische Hinweis wurde nicht aktualisiert, seitdem er zuerst in der Onlinedokumentation enthalten war.Daher können einige Prozeduren und Themen veraltet oder falsch.So fügen Sie der neuesten Informationen wird empfohlen, für das Thema im Onlinedokumentationsindex suchen. |
Dieser Hinweis beschreibt die Architektur des Dialogdatenaustausch (DDX) und der Dialogfelddatenvalidierung (DDV).Es beschreibt auch, wie Sie eine DDX_- oder DDV_-Prozedur schreiben und wie Sie Klassen-Assistent erweitern können, um die Routinen zu verwenden.
Übersicht des Dialogdatenaustauschs
Alle Dialogfelddatenfunktionen sind mit C++-Code ausgeführt.Es gibt keine besonderen Ressourcen oder Magic Makros.Das innerhalb des Mechanismus ist eine virtuelle Funktion, die in jeder Dialogfeldklasse überschrieben wird, die Dialogdatenaustausch und Validierung ausführt.Es wird immer in dieser Form gefunden:
void CMyDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX); // call base class
//{{AFX_DATA_MAP(CMyDialog)
<data_exchange_function_call>
<data_validation_function_call>
//}}AFX_DATA_MAP
}
Die besonderen Format AFX-Kommentare ermöglichen Klassen-Assistent, um den Code innerhalb dieser Funktion zu suchen und zu bearbeiten.Code, der nicht mit Klassen-Assistent sollte außerhalb der speziellen Formatkommentare platziert werden kompatibel ist.
Im obigen Beispiel ist <data_exchange_function_call> in der Form:
DDX_Custom(pDX, nIDC, field);
und <data_validation_function_call> ist optional und in der Form:
DDV_Custom(pDX, field, ...);
Mehr als ein DDX_-/DDV_paar möglicherweise wird in jeder DoDataExchange-Funktion enthalten.
Siehe "afxdd_.h" für eine Liste aller Dialogdatenaustauschroutinen und dialogieren Sie die Datenvalidierungsroutinen, die mit MFC bereitgestellt werden.
Dialogfelddaten sind nur das: Memberdaten in der CMyDialog-Klasse.Sie wird in einer Struktur gespeichert, die oder nichts ähneln.
Hinweise
Auch wenn diese "Dialogfelddaten aufrufen," sind alle Funktionen in einer Klasse verfügbar, die von CWnd abgeleitet ist und nicht auf die momentan Dialogfeldern beschränkt.
Anfangswerte von Daten werden im Standard-C++-Konstruktor, normalerweise in einem Block mit //{{AFX_DATA_INIT und //}}AFX_DATA_INIT Kommentaren festgelegt.
CWnd::UpdateData ist der Vorgang, der die Initialisierung und die Fehlerbehandlung um den Aufruf DoDataExchange ausführt.
Sie können CWnd::UpdateData jederzeit aufrufen, um Datenaustausch und Validierung auszuführen.Standardmäßig wird UpdateData(TRUE) im Standard CDialog::OnOK-Handler aufgerufen und UpdateData(FALSE) ist in standardmäßig CDialog::OnInitDialog aufgerufen.
Die DDV_-Routine sollte der DDX_-Routine für dieses Feld unmittelbar nach.
Wie funktioniert sie?
Sie müssen nicht, um Folgendes zu verstehen, um Dialogfelddaten zu verwenden.Jedoch hilft das Verständnis, wie dieses hinter den Kulissen funktioniert, Ihnen, eine Prozedur der eigenen Vermittlungsstelle oder der Validierung zu schreiben.
Die DoDataExchange-Memberfunktion ist ähnlich wie die - Memberfunktion Serialize sie ist zum Abrufen oder Festlegen von Daten zur/von der einem externen Formular (in diesem Fall Steuerelemente in einem Dialogfeld) von/nach Memberdaten in der Klasse zuständig.Der pDX-Parameter ist der Kontext für die Variante des Datenaustausches an und CArchive-Parameter zu CObject::Serialize ähnlich.pDX (ein CDataExchange-Objekt) weist ein Richtungsflag ähnlich wie CArchive hat ein Richtungsflag:
Wenn !m_bSaveAndValidate, dann den Datenzustand in die Steuerelemente laden.
Wenn m_bSaveAndValidate, dann den Datenzustand von Steuerelementen fest.
Validierung tritt nur auf, wenn m_bSaveAndValidate festgelegt ist.Der Wert von m_bSaveAndValidate wird durch den BOOL-Parameter zu CWnd::UpdateData bestimmt.
Es gibt drei weitere interessante CDataExchange-Member:
m_pDlgWnd: Das Fenster (normalerweise ein Dialogfeld) das die Steuerelemente enthält.Dies ist, Aufrufer des DDX_ und des DDV_ zu verhindern, die globale Funktionen von dieses der übergibt" zu jeder DDX-/DDVroutine müssen.
PrepareCtrl und PrepareEditCtrl: Bereitet für ein Dialogfeld-Steuerelement Datenaustausch vor.Speicher die dieses Handle des Steuerelements zum Festlegen des Fokus, wenn eine Validierung fehlschlägt.PrepareCtrl wird für nonedit Steuerelemente verwendet und PrepareEditCtrl wird für Bearbeitungssteuerelemente verwendet.
Fehler: Aufgerufen, nach oben ein Meldungsfeld geholt wurde, das den Benutzer zum Eingabefehler werden.Diese Routine stellt den Fokus auf das letzte Steuerelement (der letzte Aufruf von PrepareCtrl/PrepareEditCtrl) wieder her und löst eine Ausnahme aus.Diese Memberfunktion wird von DDX_- und DDV_-Routinen aufgerufen werden.
Benutzer-Erweiterungen
Es gibt mehrere Möglichkeiten, den Mechanismus des Standards DDX/DDV zu erweitern.Sie haben folgende Möglichkeiten:
Fügen Sie neue Datentypen hinzu.
CTime
Fügen Sie neue Austauschprozeduren hinzu (DDX_???).
void PASCAL DDX_Time(CDataExchange* pDX, int nIDC, CTime& tm);
Fügen Sie neue Validierungsprozeduren hinzu (DDV_???).
void PASCAL DDV_TimeFuture(CDataExchange* pDX, CTime tm, BOOL bFuture); // make sure time is in the future or past
Führen Sie beliebige Ausdrücke zu den Validierungsprozeduren.
DDV_MinMax(pDX, age, 0, m_maxAge);
Hinweis Solche beliebiger Ausdrücke können nicht von Klassen-Assistent bearbeitet und sollten außerhalb der speziellen Formatkommentare daher verschoben werden (// {{AFX_DATA_MAP (CMyClass)).
Lassen Sie die DoDialogExchange-Memberfunktionseinschließung Bedingungen oder alle anderen gültigen C++-Anweisungen mit vermischten Austausch- und Validierungsfunktionsaufrufen.
//{{AFX_DATA_MAP(CMyClass)
DDX_Check(pDX, IDC_SEX, m_bFemale);
DDX_Text(pDX, IDC_EDIT1, m_age);
//}}AFX_DATA_MAP
if (m_bFemale)
DDV_MinMax(pDX, age, 0, m_maxFemaleAge);
else
DDV_MinMax(pDX, age, 0, m_maxMaleAge);
Hinweis |
---|
Wie oben gezeigt, kann dieser Code nicht von Klassen-Assistent bearbeitet und sollte nur außerhalb der speziellen Formatkommentare verwendet werden. |
ClassWizard-Unterstützung
Klassen-Assistent unterstützt eine Teilmenge DDX-/DDVanpassungen, indem es Ihnen ermöglicht, eigene DDX_- und DDV_-Routinen in die ClassWizard-Benutzeroberfläche zu integrieren.Auf diese Weise wird nur nützliches anfallen, wenn Sie vorhaben, bestimmte DDX und DDV-Routinen in einem Projekt oder in vielen Projekten wiederverwenden.
Um dies zu erreichen, werden spezielle Einträge in DDX.CLW (frühere Versionen von Visual C++ gespeichert haben diese Informationen in APSTUDIO.INI) oder in das .CLW-Datei des Projekts ausgeführt.Die speziellen Einträge können entweder in den Abschnitt [Allgemeine Informationen] der .CLW-Datei des Projekts oder in den Abschnitt [ExtraDDX] in der Datei DDX.CLW im Verzeichnis \Programme\Microsoft Visual Studio\Visual C++\bin eingegeben werden.Sie müssen möglicherweise die DDX.CLW-Datei erstellen, wenn sie nicht bereits vorhanden ist.Wenn Sie planen, die Routinen der benutzerdefinierten DDX_/DDV_ nur in einem bestimmten Projekt zu verwenden, fügen Sie die Einträge dem Abschnitt [der allgemeinen Informationen] der Datei des Projekts .CLW stattdessen hinzu.Wenn Sie planen, die Routinen auf vielen Projekten zu verwenden, fügen Sie die Einträge dem Abschnitt [ExtraDDX] von DDX.CLW hinzu.
Das Muster dieser speziellen Einträge ist:
ExtraDDXCount=n
wobei n ist die Anzahl der ExtraDDX?Zeilen zu folgen
ExtraDDX?=<keys>;<vb-keys>; <prompt>; <type>; <initValue>; <DDX_Proc>
[;<DDV_Proc>; <prompt1>; <arg1>; [<prompt2>; <fmt2>]]
wobei?ist eine Zahl. 1 - n-Angeben, dem DDX die Liste eingeben, die definiert wird.
Jedes Feld wird durch "getrennt; " Zeichen.Die Felder und deren Zweck sind unten beschrieben.
<keys>
= wird Liste aus einzelnen Zeichen, die angeben, welche Dialogfeld, für diesen Variablentyp steuert, zulässig.E = Bearbeitung
C = ZweiZustandskontrollkästchen
= c Tristatekontrollkästchen
R = zuerst Optionsfeld in einer Gruppe
L = nonsorted Listenfeld
L = sortiertes Listenfeld
M = Kombinationsfeld (mit Bearbeitungselement)
N = nonsorted Ablagenliste
n = sortierte Ablagenliste
1 =, wenn die DDX-Einfügung hinzugefügt den Anfang der Liste (Standard, hinzufügen Ende ist), das dieses im Allgemeinen für DDX-Routinen verwendet wird, die die Eigenschaft "Steuer" übertragen.
<vb-keys>
Dieses Feld wird nur im 16-Bit-Produkt für VBX-Kontrollen verwendet (VBX-Kontrollen werden nicht in das 32-Bit-Produkt unterstützt)<prompt>
In das Eigenschaftkombinationsfeld (keine Anführungszeichen) zu legen, Zeichenfolge<type>
Einzelner Bezeichner, damit Typ in der Headerdatei ausgibt.In unserem Beispiel oben mit DDX_Time, würde dies zu CTime festgelegt.<vb-keys>
Wird in dieser Version nicht und sollte immer leer sein<initValue>
Anfangswert - 0 oder Leerzeichen.Wenn er leer ist, wird keine Initialisierungszeile in //geschrieben {{AFX_DATA_INIT-Abschnitt der Implementierungsdatei.Ein leerer Eintrag sollte für C++-Objekte verwendet werden (z CString, CTime, usw.). die Konstruktoren verfügen, die richtiger Initialisierung sicherstellen.<DDX_Proc>
Einzelner Bezeichner für die DDX_-Prozedur.Der C++-Funktionsname muss mit "DDX_ beginnen," umfasst jedoch "DDX_" nicht im <DDX_Proc> Bezeichner.Im Beispiel oben, würde der <DDX_Proc> Bezeichner Zeit sein.Wenn Klassen-Assistent den Funktionsaufruf zur Implementierungsdatei in schreibt {{AFX_DATA_MAP-Abschnitt, fügt er diesen Namen zu DDX_ an und so wird bei DDX_Time an.<comment>
Kommentieren Sie, um im Dialogfeld für Variable mit diesem DDX zeigen.Fügen Sie einen beliebigen Text, den Sie hier möchten, und stellen Sie normalerweise einige bereit, das den Vorgang beschreibt, der durch die DDX-/DDVpaare ausgeführt wird.<DDV_Proc>
Der DDV-Teil des Eintrags ist optional.Nicht alle DDX-Routinen sind entsprechende DDV-Routinen.Häufig ist es einfacher, die Validierungsphase als integraler Bestandteil der Übertragung einzuschließen.Dies ist häufig der Fall, wenn die DDV-Routine keine Parameter benötigt, da Klassen-Assistent DDV-Routinen nicht ohne Parameter unterstützt.<arg>
Einzelner Bezeichner für die DDV_-Prozedur.Der C++-Funktionsname muss mit "DDV_" beginnen, aber umfasst "DDX_" nicht im <DDX_Proc> Bezeichner.
gefolgt von 1 oder 2 DDV-args:
<promptX>
zum Bearbeitungselement zu platzieren, Zeichenfolge (mit & für Zugriffstaste).<fmtX>
Formatzeichen für den Typ, der ein Argumentd = int
u = unsigned
D = lang int (das heißt, long)
U = lang ohne Vorzeichen (das heißt, DWORD)
f = float
F = Double
s = string