Uwaga
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Uwaga / Notatka
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 dialogowych (DDV). Opisuje również, jak napisać procedurę DDX_ lub DDV_ oraz jak rozszerzyć ClassWizard w celu korzystania z rutyn.
Przegląd wymiany danych dialogowych
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ą ClassWizardowi lokalizowanie i edytowanie kodu w tej funkcji. Kod niekompatybilny z ClassWizard powinien być umieszczony poza specjalnymi komentarzami formatowymi.
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_/DDV_.
Zobacz „afxdd_.h”, aby uzyskać listę wszystkich rutyn wymiany danych w oknach dialogowych oraz rutyn weryfikacji danych dialogowych dostępnych w MFC.
Dane dialogu to właśnie te dane członkowskie w klasie CMyDialog
. Nie jest przechowywany w strukturze ani w nic podobnego.
Notatki
Chociaż nazywamy to "danymi dialogowymi", wszystkie funkcje są dostępne w dowolnej klasie pochodnej CWnd
i 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 DDV_ powinna natychmiast postępować zgodnie 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 podobna do Serialize
funkcji składowej — jest odpowiedzialna za pobieranie lub ustawianie danych z/do formy zewnętrznej (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
do CObject::Serialize
.
PDX (CDataExchange
obiekt) ma flagę kierunku, podobnie jak CArchive
ma flagę kierunku.
Jeśli
!m_bSaveAndValidate
, wczytaj stan danych do kontrolek.Jeśli
m_bSaveAndValidate
jest spełnione, ustaw stan danych z elementów sterujących.
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 inni interesujący CDataExchange
członkowie.
m_pDlgWnd
: okno (zazwyczaj okno dialogowe), które zawiera kontrolki. Zapobiega to temu, aby wywołania funkcji globalnych DDX_ i DDV_ nie musiały przekazywać wskaźnika 'this' do każdej operacji DDX/DDV.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 procedura przywróci fokus do ostatniej kontrolki (ostatnie wywołanie metodyPrepareCtrl
lubPrepareEditCtrl
), a następnie zgłosi wyjątek. Ta funkcja składowa może być wywoływana zarówno z procedur DDX_, jak i DDV_.
Rozszerzenia użytkownika
Istnieje kilka sposobów rozszerzenia domyślnego mechanizmu DDX/DDV. 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 (DDV_).
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 / Notatka
Takie dowolne wyrażenia nie mogą być edytowane przez ClassWizard i dlatego powinny być przenoszone poza specjalne komentarze formatu (//{{AFX_DATA_MAP(CMyClass)).
Niech funkcja składowa DoDataExchange
zawiera instrukcje warunkowe lub inne prawidłowe instrukcje C++ z przeplatanymi 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 / Notatka
Jak pokazano powyżej, taki kod nie może być edytowany przez ClassWizard i powinien być używany tylko poza komentarzami o specjalnym formacie.
Wsparcie ClassWizard
ClassWizard obsługuje podzestaw dostosowań DDX/DDV, umożliwiając integrację własnych procedur DDX_ i DDV_ z interfejsem użytkownika ClassWizard. Jest to opłacalne tylko wtedy, gdy planujesz ponownie używać określonych procedur DDX i DDV w projekcie lub w wielu projektach.
W tym celu w pliku DDX.CLW są tworzone specjalne wpisy (poprzednie wersje Visual C++ przechowywały te informacje w pliku APSTUDIO.INI) lub w pliku .CLW twojego projektu. Wpisy specjalne można wprowadzić w sekcji [Informacje ogólne] pliku projektu .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_/DDV_ tylko w określonym projekcie, zamiast tego dodaj wpisy do sekcji [Informacje ogólne] w pliku projektu .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 jest liczbą wierszy ExtraDDX? do wprowadzenia
ExtraDDX?=keys; vb-keys; monit; typ; initValue; DDX_Proc [; DDV_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.
Klucze
Lista pojedynczych znaków wskazująca, dla którego okno dialogowe steruje tym typem zmiennej, jest dozwolona.
Charakter Dozwolona kontrola E Edytuj… C pole wyboru dwustanowe Bez kontekstu nie można zapewnić adekwatnego tłumaczenia litery "c". pole wyboru trzy-stanowe R pierwszy przycisk radiowy w grupie L pole listy niesortowanej l okno listy posortowanej M pole kombi (z elementem edycji) N lista rozwijana bez sortowania 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)
zachęta
Ciąg do umieszczenia w polu rozwijanym Właściwości (bez cudzysłowów)
typ
Pojedynczy identyfikator typu do umieszczenia w pliku nagłówkowym. W naszym przykładzie powyżej z DDX_Time, będzie to ustawione na 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 zawieraj "DDX_" w identyfikatorze <DDX_Proc>. W powyższym przykładzie identyfikator <DDX_Proc> to Czas. 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świetlenia w oknie dialogowym dla zmiennej z tym DDX. Umieść tutaj dowolny tekst i zazwyczaj podaj coś, co opisuje operację wykonywaną przez parę DDX/DDV.
DDV_Proc
Część DDV wpisu jest opcjonalna. Nie wszystkie procedury DDX mają odpowiednie procedury DDV. Często bardziej wygodne jest uwzględnienie fazy weryfikacji jako integralnej części transferu. Jest to często przypadek, gdy rutyna DDV nie wymaga żadnych parametrów, ponieważ KlasaWizard nie obsługuje procedur DDV bez żadnych parametrów.
Arg
Pojedynczy identyfikator procedury DDV_. Nazwa funkcji języka C++ musi zaczynać się od "DDV_", ale nie należy dołączać "DDX_" w identyfikatorze <DDX_Proc> .
arg następuje 1 lub 2 args DDV:
promptN
Ciąg do umieszczenia nad elementem edycji (ze znakiem & jako skrót).
fmtN
Formatuj znak dla typu arg, jeden z:
Charakter Typ d int (integer) u niepodpisane int D długi int (czyli długi) U long unsigned (czyli DWORD) f unoszenie się F podwójny s sznurek
Zobacz także
Uwagi techniczne według numeru
Uwagi techniczne według kategorii