TN026: DDX i DDV procedur
[!UWAGA]
Następujące Uwaga techniczna została zaktualizowana, ponieważ została ona uwzględniona w dokumentacji online programu.W rezultacie niektóre procedury i tematy może być nieaktualne lub nieprawidłowe.Aby uzyskać najnowsze informacje zalecane jest, wyszukać temat z indeksu dokumentacji online.
Uwaga ta opisuje okno Wymiana danych (DDX) i architektura sprawdzania poprawności (DDV) danych okno dialogowe.Opisano również, jak napisać procedurę DDX_ lub DDV_ i jak można rozszerzyć ClassWizard obsłudze swoje procedury.
Omówienie okna dialogowego wymiana danych
Wszystkie funkcje danych okno dialogowe są wykonane z kodu C++.Nie ma żadnych specjalnych zasobów lub magiczne makra.Serce mechanizmu jest wirtualny funkcja, która zostanie zastąpiona w każdej klasie okno dialogowe, że ma okno dialogowe wymiany danych i sprawdzania poprawności.Zawsze znajduje się w tym formularzu:
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
}
Specjalny format AFX komentarze pozwalają ClassWizard zlokalizować i edytować kod w ramach tej funkcji.Kod, który nie jest zgodny z ClassWizard powinny być umieszczone poza komentarze specjalny format.
W powyższym przykładzie, <data_exchange_function_call> ma postać:
DDX_Custom(pDX, nIDC, field);
i <data_validation_function_call> jest opcjonalny i ma postać:
DDV_Custom(pDX, field, ...);
W każdym może zawierać więcej niż jedną parę DDX_/DDV_ DoDataExchange funkcji.
Zobacz 'afxdd_.h', aby uzyskać listę wszystkich procedur wymiany danych okno dialogowe i procedur sprawdzania poprawności danych okno dialogowe z MFC.
Okno danych to po prostu: dane elementu członkowskiego w CMyDialog klasy.Nie jest przechowywana w struct lub coś podobnego.
Uwagi
Chociaż nazywamy to "dane okno", wszystkie funkcje są dostępne w dowolnej klasy pochodzące z CWnd i nie są ograniczone do tylko okna dialogowe.
Początkowe wartości danych mieszczą się w standardowych Konstruktor C++, zwykle w blok z //{{AFX_DATA_INIT i //}}AFX_DATA_INIT komentarze.
CWnd::UpdateDatajest operacją, która nie inicjacji i obsługi wokół wywołanie błędów DoDataExchange.
Można wywołać CWnd::UpdateData w dowolnym momencie przeprowadzić wymianę danych i sprawdzania poprawności.Domyślnie UpdateData(PRAWDA), jest nazywany w domyślnym CDialog::OnOK programu obsługi i UpdateData(FAŁSZ) jest nazywany w domyślnym CDialog::OnInitDialog.
Rutynowe DDV_ należy natychmiast wykonaj rutynowe DDX_ do tego field.
Jak działa?
Nie trzeba znać następujące, aby użyć danych okno dialogowe.Jednakże zrozumienia, jak to działa w tle pomoże Ci napisać swoje własne procedury wymiany lub sprawdzania poprawności.
DoDataExchange Funkcji składowej jest bardzo podobny do Serialize funkcji składowej - jest on odpowiedzialny za ustawianie ani pobieranie danych do/z zewnętrznych formularza (w tym przypadku kontroluje w oknie dialogowym) z/do danych elementu członkowskiego w klasie.pDX Parametr jest kontekstem, za to wymiana danych i jest podobna do CArchive parametru do CObject::Serialize.pDX ( CDataExchange Obiektu) ma kierunek oflagować podobnie jak CArchive ma flagę kierunku:
Jeśli ! m_bSaveAndValidate, następnie załadować Państwo dane do formantów.
Jeśli m_bSaveAndValidate, a następnie ustaw stan danych z formantów.
Sprawdzanie poprawności jest wykonywane tylko po m_bSaveAndValidate jest ustawiona.Wartość m_bSaveAndValidate jest określana przez parametr BOOL do CWnd::UpdateData.
Istnieją trzy inne ciekawe CDataExchange członków:
m_pDlgWnd: Oknie (zwykle okno dialogowe), które zawiera formanty.Ma to zapobiec wywołań funkcji globalnych DDX_ i DDV_ z o przekazywanie 'this' do każdej procedury DDX/DDV.
PrepareCtrl, a PrepareEditCtrl: przygotowuje dialog control do wymiany danych.Przechowuje uchwyt tego formantu do ustawiania fokusu, jeśli przy sprawdzaniu poprawności nie powiedzie się.PrepareCtrlSłuży do sterowania nonedit i PrepareEditCtrl jest używana dla formantów edycyjnych.
Niepowodzenie: o nazwie po ponownym przełączeniu się okno komunikatu ostrzegająca użytkownika, aby błąd danych wejściowych.Procedura ta spowoduje przywrócenie fokusu do ostatniego formantu (ostatnie wywołanie PrepareCtrl/PrepareEditCtrl) i zgłosić wyjątek.Ta funkcja składowa może być wywoływana z procedur DDX_ i DDV_.
Rozszerzeń użytkownika
Aby rozszerzyć domyślnego mechanizmu DDX/DDV na kilka sposobów.Możesz:
Dodaj nowe typy danych.
CTime
Dodawanie nowych procedur wymiany (DDX_???).
void PASCAL DDX_Time(CDataExchange* pDX, int nIDC, CTime& tm);
Dodaj nowe procedury sprawdzania poprawności (DDV_???).
void PASCAL DDV_TimeFuture(CDataExchange* pDX, CTime tm, BOOL bFuture); // make sure time is in the future or past
Do procedur sprawdzania poprawności, należy przekazać dowolnego wyrażenia.
DDV_MinMax(pDX, age, 0, m_maxAge);
[!UWAGA]
Takie dowolnego wyrażenia nie może być edytowany przez ClassWizard i powinny zostać przeniesione poza komentarze specjalny format (/ / {{AFX_DATA_MAP(CMyClass)).
Mają DoDialogExchange funkcji składowej obejmują warunkowe lub wszelkich innych prawidłowych instrukcji języka C++ z mieszaniny wywołań funkcji programu exchange i sprawdzania poprawności.
//{{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);
[!UWAGA]
Jak wykazano powyżej, taki kod nie może być edytowany przez ClassWizard i powinna być używana tylko poza komentarze specjalny format.
Obsługa ClassWizard
ClassWizard obsługuje podzbiór dostosowań DDX/DDV, umożliwiając integracji własne procedury DDX_ i DDV_ w interfejsie użytkownika ClassWizard.Jest to tylko koszt korzystna, gdyby istniejące szczególne procedury DDX i DDV w projekcie lub w wielu projektach.
W tym celu specjalne wpisów w DDX.CLW (poprzednie wersje Visual C++ przechowuje te informacje w APSTUDIO.INI) lub do projektu.Plik CLW.Specjalne wpisy mogą być wprowadzone w sekcji [General Info] projektu.Plik CLW lub w sekcji [ExtraDDX] DDX.Plik CLW w \Program Files\Microsoft Visual C++ Studio\Visual ++ katalogu \bin.Może być konieczne utworzenie DDX.Plik CLW, jeśli jeszcze nie istnieje.Jeśli zamierzasz używać niestandardowych procedur DDX_/DDV_ tylko w niektórych projektu, należy dodać wpisy do sekcji [General Info] projektu.CLW plików zamiast.Jeśli planujesz użyć procedury w wielu projektach, należy dodać wpisy do sekcji [ExtraDDX] DDX.CLW.
Jest ogólny format te specjalne wpisy:
ExtraDDXCount=n
gdzie n jest numerem ExtraDDX?wiersze, aby skorzystali z
ExtraDDX?=<keys>;<vb-keys>; <prompt>; <type>; <initValue>; <DDX_Proc>
[;<DDV_Proc>; <prompt1>; <arg1>; [<prompt2>; <fmt2>]]
gdzie?jest numer 1 — n wskazującą, które DDX typ z listy, który jest zdefiniowany.
Każde pole jest rozdzielany znakiem znaku ';'.Poniżej opisano pola i ich przeznaczenia.
<keys>
= Lista pojedyncze znaki, wskazującą, jakie formanty okna dialogowego tego typu zmienna jest dozwolona.E = Edycja
C = pole wyboru dwóch Państw
c = pole wyboru tri stan
R = pierwszy przycisk opcji w grupie
L = pole listy nonsorted
l = pole posortowanej listy
M = pole kombi (Edytuj element)
N = lista nonsorted upuszczania
n = spadek posortowanej listy
1 = if Wstaw DDX powinny zostać dodane do czele listy (domyślny jest dodać do ogona) jest to powszechnie używane dla procedur DDX, które przeniesienia własności "Kontrola".
< vb klucze >
To pole jest używane tylko w 16-bitowy produkt dla formantów VBX (VBX formanty nie są obsługiwane w produkcie 32-bitowe)<prompt>
Ciąg, aby umieścić w polu kombi właściwości (bez cudzysłowu)<type>
Pojedynczy identyfikator typu emitować w pliku nagłówkowym.W naszym przykładzie powyżej z DDX_Time to może być równa CTime.< vb klucze >
Nie używane w tej wersji i powinna zawsze być pusta<initValue>
Wartość początkowa — 0 lub pusty.Jeśli to jest puste, bez linii inicjowania zostaną zapisane w sekcji //{{AFX_DATA_INIT pliku implementacji.Pusty wpis powinna być używana do obiektów C++ (takie jak CString, CTimei tak dalej) które mają konstruktorów, które gwarantują prawidłowe inicjowania.<DDX_Proc>
Pojedynczy identyfikator dla procedury DDX_.Nazwa funkcji C++ musi zaczynać się od "DDX_", ale nie dołączaj "DDX_" w <DDX_Proc> identyfikator.W poniższym przykładzie, <DDX_Proc> Identyfikator byłby czas.Gdy ClassWizard pisze wywołanie funkcji do wykonania pliku w {{sekcji AFX_DATA_MAP, to dołącza tę nazwę do DDX_, w ten sposób dotarcia do DDX_Time.<comment>
Komentarz, aby pokazać w oknie dialogowym dla zmiennej z tym DDX.Umieścić dowolny tekst ma w tym miejscu i zwykle oferują coś, który opisuje operacji wykonywanych przez parę DDX/DDV.<DDV_Proc>
DDV część wpisu jest opcjonalne.Nie wszystkie procedury DDX mają odpowiednie procedury DDV.Często jest bardziej wygodne uwzględnić w fazie sprawdzania poprawności jako integralną część transferu.Jest często tak podczas rutynowych DDV nie wymaga żadnych parametrów, ponieważ ClassWizard nie obsługuje procedury DDV bez żadnych parametrów.<arg>
Pojedynczy identyfikator dla procedury DDV_.Nazwa funkcji C++ musi zaczynać się od "DDV_", ale nie zawierają "DDX_" w <DDX_Proc> identyfikator.
następnie args DDV 1 lub 2:
<promptX>
ciąg, aby umieścić powyżej obiektu edycji (z & dla accelerator)<fmtX>
Format znak dla typu arg, jeden zd = int
u = bez znaku
D = long int (to znaczy długo)
U = długo bez znaku (to znaczy DWORD)
f = pływaka
F = podwójne
s = ciąg