TN026: procedury DDX i DDV
Uwaga
Następująca uwaga techniczna nie została zaktualizowana, ponieważ została po raz pierwszy uwzględniona w dokumentacji online. W związku z tym niektóre procedury i tematy mogą być nieaktualne lub nieprawidłowe. Aby uzyskać najnowsze informacje, zaleca się wyszukanie interesującego tematu w indeksie dokumentacji online.
W tej notatce opisano architekturę wymiany danych okna dialogowego (DDX) i weryfikacji danych okna dialogowego (Przeglądarka danych diagnostycznych). W tym artykule opisano również sposób pisania procedury DDX_ lub Przeglądarka danych diagnostycznych_ oraz sposobu rozszerzania klasy ClassWizard w celu korzystania z procedur.
Omówienie wymiany danych okna dialogowego
Wszystkie funkcje danych okna dialogowego są wykonywane przy użyciu kodu C++. Brak specjalnych zasobów ani makr magicznych. Sercem mechanizmu jest funkcja wirtualna, która jest zastępowana w każdej klasie okna dialogowego, która wykonuje wymianę i walidację danych okna dialogowego. Zawsze można go znaleźć w tej formie:
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
}
Komentarze AFX w specjalnym formacie umożliwiają klasyWizard lokalizowanie i edytowanie kodu w tej funkcji. Kod niezgodny z klasą ClassWizard powinien zostać umieszczony poza specjalnymi komentarzami w formacie.
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żdej DoDataExchange
funkcji może znajdować się więcej niż jedna para DDX_/Przeglądarka danych diagnostycznych_.
Zobacz "afxdd_.h", aby uzyskać listę wszystkich procedur wymiany danych okna dialogowego i procedur weryfikacji danych dialogowych dostarczonych z MFC.
Dane okna dialogowego CMyDialog
to tylko te dane składowe w klasie. Nie jest on przechowywany w strukturę ani w niczym podobnym.
Uwagi
Chociaż nazywamy to "danymi okna dialogowego", wszystkie funkcje są dostępne w dowolnej klasie pochodnej i CWnd
nie są ograniczone tylko do okien dialogowych.
Początkowe wartości danych są ustawiane w standardowym konstruktorze języka C++, zwykle w bloku z komentarzami //{{AFX_DATA_INIT
i //}}AFX_DATA_INIT
.
CWnd::UpdateData
to operacja, która wykonuje inicjowanie i obsługę błędów wokół wywołania metody DoDataExchange
.
Możesz wywołać metodę CWnd::UpdateData
w dowolnym momencie, aby przeprowadzić wymianę i walidację danych. Domyślnie UpdateData
(TRUE) jest wywoływana w domyślnej CDialog::OnOK
procedurze obsługi i UpdateData
(FALSE) jest wywoływana w domyślnym CDialog::OnInitDialog
.
Rutyna Przeglądarka danych diagnostycznych_ powinna być natychmiast zgodna z procedurą DDX_ dla tego pola.
Jak to działa
Nie musisz rozumieć następujących informacji, aby użyć danych okna dialogowego. Jednak zrozumienie, jak to działa w tle, pomoże Ci napisać własną procedurę wymiany lub weryfikacji.
DoDataExchange
Funkcja składowa jest podobnie jak Serialize
funkcja składowa — jest odpowiedzialna za pobieranie lub ustawianie danych do/z formularza zewnętrznego (w tym przypadku kontrolek w oknie dialogowym) z/do danych składowych w klasie. Parametr pDX jest kontekstem do wymiany danych i jest podobny do parametru CArchive
.CObject::Serialize
PDX (CDataExchange
obiekt) ma flagę kierunku, podobnie jak CArchive
flaga kierunku:
Jeśli
!m_bSaveAndValidate
wartość , załaduj stan danych do kontrolek.Jeśli
m_bSaveAndValidate
wartość , ustaw stan danych z kontrolek.
Walidacja występuje tylko wtedy, gdy m_bSaveAndValidate
jest ustawiona. Wartość parametru m_bSaveAndValidate
jest określana przez parametr BOOL na CWnd::UpdateData
.
Istnieją trzy inne interesujące CDataExchange
elementy członkowskie:
m_pDlgWnd
: okno (zazwyczaj okno dialogowe), które zawiera kontrolki. Zapobiega to wywołaniom DDX_ i Przeglądarka danych diagnostycznych_ funkcji globalnych konieczności przekazywania "tego" do każdej procedury DDX/Przeglądarka danych diagnostycznych.PrepareCtrl
, iPrepareEditCtrl
: przygotowuje kontrolkę okna dialogowego do wymiany danych. Przechowuje uchwyt tej kontrolki do ustawiania fokusu, jeśli walidacja zakończy się niepowodzeniem.PrepareCtrl
jest używany w przypadku kontrolek nieedytacyjnych iPrepareEditCtrl
jest używany do edycji kontrolek.Fail
: wywoływana po wywołaniu pola komunikatu ostrzegającego użytkownika o błędzie wejściowym. Ta rutyna spowoduje przywrócenie fokusu do ostatniej kontrolki (ostatnie wywołanie metodyPrepareCtrl
lubPrepareEditCtrl
) i zgłoszenie wyjątku. Ta funkcja składowa może być wywoływana zarówno z procedur DDX_, jak i Przeglądarka danych diagnostycznych_.
Rozszerzenia użytkownika
Istnieje kilka sposobów rozszerzenia domyślnego mechanizmu DDX/Przeglądarka danych diagnostycznych. Masz następujące możliwości:
Dodaj nowe typy danych.
CTime
Dodaj nowe procedury wymiany (DDX_).
void PASCAL DDX_Time(CDataExchange* pDX, int nIDC, CTime& tm);
Dodaj nowe procedury weryfikacji (Przeglądarka danych diagnostycznych_).
void PASCAL DDV_TimeFuture(CDataExchange* pDX, CTime tm, BOOL bFuture); // make sure time is in the future or past
Przekaż dowolne wyrażenia do procedur walidacji.
DDV_MinMax(pDX, age, 0, m_maxAge);
Uwaga
Takie dowolne wyrażenia nie mogą być edytowane przez klasę ClassWizard i dlatego powinny być przenoszone poza specjalnymi komentarzami w formacie (//{{AFX_DATA_MAP(CMyClass)).
Funkcja składowa DoDataExchange
zawiera warunkowe lub inne prawidłowe instrukcje języka C++ z międzymieszkowymi wywołaniami funkcji wymiany i walidacji.
//{{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 pokazano powyżej, taki kod nie może być edytowany przez klasę ClassWizard i powinien być używany tylko poza specjalnymi komentarzami w formacie.
Obsługa klasyWizard
KlasaWizard obsługuje podzbiór dostosowań DDX/Przeglądarka danych diagnostycznych, umożliwiając integrację własnych procedur DDX_ i Przeglądarka danych diagnostycznych_ z interfejsem użytkownika ClassWizard. Jest to opłacalne tylko wtedy, gdy planujesz ponownie używać określonych procedur DDX i Przeglądarka danych diagnostycznych w projekcie lub w wielu projektach.
W tym celu w pliku DDX.CLW są tworzone specjalne wpisy (poprzednie wersje języka Visual C++ przechowywane te informacje w programie APSTUDIO). INI) lub w projekcie . Plik CLW. Wpisy specjalne można wprowadzić w sekcji [Informacje ogólne] projektu . Plik CLW lub w sekcji [ExtraDDX] pliku DDX.CLW w katalogu \Program Files\Microsoft Visual Studio\Visual C++\bin. Może być konieczne utworzenie pliku DDX.CLW, jeśli jeszcze nie istnieje. Jeśli planujesz używać niestandardowych procedur DDX_/Przeglądarka danych diagnostycznych_ tylko w określonym projekcie, dodaj wpisy do sekcji [Informacje ogólne] projektu . Zamiast tego plik CLW. Jeśli planujesz używać procedur w wielu projektach, dodaj wpisy do sekcji [ExtraDDX] DDX.CLW.
Ogólny format tych wpisów specjalnych to:
ExtraDDXCount=n
gdzie n to liczba wierszy ExtraDDX do naśladowania, formularza
ExtraDDX?=keys; vb-keys; monit; typ; initValue; DDX_Proc [; Przeglądarka danych diagnostycznych_Proc; prompt1; arg1 [; prompt2; fmt2]]
Gdzie? jest liczbą 1 — n wskazującą typ DDX na zdefiniowanej liście.
Każde pole jest rozdzielane znakiem ";". Pola i ich przeznaczenie zostały opisane poniżej.
keys
Lista pojedynczych znaków wskazująca, dla którego okno dialogowe steruje tym typem zmiennej, jest dozwolona.
Znak Dozwolona kontrolka E Edytuj… C pole wyboru dwustanowe c pole wyboru tri-state R pierwszy przycisk radiowy w grupie L pole listy niesortowanej l pole listy posortowanej M pole kombi (z elementem edycji) N niesortowana lista rozwijana n posortowana lista rozwijana 1 Jeśli wstawka DDX powinna zostać dodana do nagłówka listy (domyślnie jest dodawana do końca) Jest to zwykle używane w przypadku procedur DDX, które przenoszą właściwość "Control". vb-keys
To pole jest używane tylko w 16-bitowym produkcie dla kontrolek VBX (kontrolki VBX nie są obsługiwane w produkcie 32-bitowym)
Wierszu
Ciąg do umieszczenia w polu kombi Właściwości (bez cudzysłowów)
type
Pojedynczy identyfikator typu do emitowania w pliku nagłówka. W naszym przykładzie powyżej z DDX_Time zostanie ustawiona wartość CTime.
vb-keys
Nieużytne w tej wersji i zawsze powinny być puste
initValue
Wartość początkowa — 0 lub pusta. Jeśli jest on pusty, w sekcji //{{AFX_DATA_INIT pliku implementacji nie zostanie zapisany wiersz inicjowania. Pusty wpis powinien być używany dla obiektów języka C++ (takich jak
CString
,CTime
i tak dalej), które mają konstruktory, które gwarantują poprawną inicjację.DDX_Proc
Pojedynczy identyfikator procedury DDX_. Nazwa funkcji języka C++ musi zaczynać się od ciągu "DDX_", ale nie zawiera "DDX_" w identyfikatorze <DDX_Proc> . W powyższym <przykładzie identyfikator DDX_Proc> to Time. Gdy klasa ClassWizard zapisuje wywołanie funkcji do pliku implementacji w sekcji {{AFX_DATA_MAP, dołącza tę nazwę do DDX_, w ten sposób docierając do DDX_Time.
Komentarz
Komentarz do wyświetlania w oknie dialogowym dla zmiennej z tym DDX. Umieść dowolny tekst w tym miejscu i zazwyczaj podaj coś, co opisuje operację wykonywaną przez parę DDX/Przeglądarka danych diagnostycznych.
Przeglądarka danych diagnostycznych_Proc
Część Przeglądarka danych diagnostycznych wpisu jest opcjonalna. Nie wszystkie procedury DDX mają odpowiednie procedury Przeglądarka danych diagnostycznych. Często bardziej wygodne jest uwzględnienie fazy weryfikacji jako integralnej części transferu. Jest to często przypadek, gdy rutyna Przeglądarka danych diagnostycznych nie wymaga żadnych parametrów, ponieważ KlasaWizard nie obsługuje procedur Przeglądarka danych diagnostycznych bez żadnych parametrów.
Arg
Pojedynczy identyfikator procedury Przeglądarka danych diagnostycznych_. Nazwa funkcji języka C++ musi zaczynać się od "Przeglądarka danych diagnostycznych_", ale nie należy dołączać ciągu "DDX_" w identyfikatorze <DDX_Proc>.
arg następuje 1 lub 2 Przeglądarka danych diagnostycznych args:
promptN
Ciąg do umieszczenia nad elementem edycji (z elementem i akceleratorem).
fmtN
Formatuj znak dla typu arg, jeden z:
Znak Typ d int u unsigned int D długa int (czyli długa) U long unsigned (czyli DWORD) f liczba zmiennoprzecinkowa F double s string
Zobacz też
Uwagi techniczne według numerów
Uwagi techniczne według kategorii