TN026: DDX ve DDV Rutinleri
Dekont
Aşağıdaki teknik not, çevrimiçi belgelere ilk kez eklendiğinden beri güncelleştirilmemiştir. Sonuç olarak, bazı yordamlar ve konular güncel olmayabilir veya yanlış olabilir. En son bilgiler için, çevrimiçi belge dizininde ilgilendiğiniz konuyu aramanız önerilir.
Bu not, iletişim kutusu veri değişimi (DDX) ve iletişim kutusu veri doğrulama (DDV) mimarisini açıklar. Ayrıca bir DDX_ veya DDV_ yordamı nasıl yazabileceğiniz ve ClassWizard'ı yordamlarınızı kullanacak şekilde nasıl genişletebileceğiniz açıklanır.
İletişim Kutusu Veri Değişimine Genel Bakış
Tüm iletişim kutusu veri işlevleri C++ koduyla gerçekleştirilir. Özel kaynaklar veya sihirli makrolar yoktur. Mekanizmanın kalbi, iletişim kutusu veri değişimi ve doğrulama işlemi yapılan her iletişim kutusu sınıfında geçersiz kılınan bir sanal işlevdir. Her zaman şu biçimde bulunur:
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
}
Özel biçimli AFX açıklamaları ClassWizard'ın bu işlev içindeki kodu bulmasına ve düzenlemesine olanak tanır. ClassWizard ile uyumlu olmayan kod, özel biçim açıklamalarının dışına yerleştirilmelidir.
Yukarıdaki örnekte, <data_exchange_function_call> formdadır:
DDX_Custom(pDX, nIDC, field);
ve <data_validation_function_call> isteğe bağlıdır ve şu biçimdedir:
DDV_Custom(pDX, field, ...);
Her DoDataExchange
işleve birden fazla DDX_/DDV_ çifti eklenebilir.
MFC ile sağlanan tüm iletişim kutusu veri değişimi yordamlarının ve iletişim kutusu veri doğrulama yordamlarının listesi için 'afxdd_.h' bölümüne bakın.
İletişim kutusu verileri yalnızca sınıftaki CMyDialog
üye verileridir. Bir yapıda veya benzer bir şeyde depolanmaz.
Notlar
Bu "iletişim kutusu verileri" olarak adlandırılsa da, tüm özellikler türetilen CWnd
tüm sınıflarda kullanılabilir ve yalnızca iletişim kutularıyla sınırlı değildir.
Verilerin ilk değerleri standart C++ oluşturucusunda, genellikle ve //}}AFX_DATA_INIT
açıklamalarıyla //{{AFX_DATA_INIT
bir blokta ayarlanır.
CWnd::UpdateData
, çağrısının DoDataExchange
çevresinde başlatma ve hata işleme işlemlerinin gerçekleştirildiği işlemdir.
Veri değişimi ve doğrulama gerçekleştirmek için istediğiniz zaman arayabilirsiniz CWnd::UpdateData
. Varsayılan olarak UpdateData
(TRUE) varsayılan CDialog::OnOK
işleyicide UpdateData
ve (FALSE) varsayılan CDialog::OnInitDialog
içinde çağrılır.
DDV_ yordamı, bu alanın DDX_ yordamını hemen izlemelidir.
Nasıl Çalışır?
İletişim kutusu verilerini kullanmak için aşağıdakileri anlamanız gerekmez. Ancak, bunun arka planda nasıl çalıştığını anlamak, kendi değişim veya doğrulama yordamınızı yazmanıza yardımcı olur.
DoDataExchange
Üye işlevi, üye işlevine Serialize
çok benzer; sınıftaki üye verilerinden dış forma/formdan (bu örnekte iletişim kutusundaki denetimler) veri almaktan veya ayarlamaktan sorumludur. pDX parametresi, veri değişiminin bağlamıdır ve parametresine CArchive
CObject::Serialize
benzer. pDX'in (nesneCDataExchange
) yön bayrağına çok benzer CArchive
bir yön bayrağı vardır:
ise
!m_bSaveAndValidate
, veri durumunu denetimlere yükleyin.ise
m_bSaveAndValidate
, denetimlerden veri durumunu ayarlayın.
Doğrulama yalnızca ayarlandığında gerçekleşir m_bSaveAndValidate
. değeri m_bSaveAndValidate
, bool parametresi tarafından olarak CWnd::UpdateData
belirlenir.
Üç ilginç CDataExchange
üye daha vardır:
m_pDlgWnd
: Denetimleri içeren pencere (genellikle bir iletişim kutusu). Bu, DDX_ ve DDV_ genel işlevleri çağıranların her DDX/DDV yordamına 'this' geçirmek zorunda olmasını önlemektir.PrepareCtrl
vePrepareEditCtrl
: Veri değişimi için bir iletişim kutusu denetimi hazırlar. Doğrulama başarısız olursa odağı ayarlamak için bu denetimin tutamacını depolar.PrepareCtrl
düzenleme dışı denetimler için kullanılır vePrepareEditCtrl
düzenleme denetimleri için kullanılır.Fail
: Kullanıcıyı giriş hatasına karşı uyaran bir ileti kutusu getirildikten sonra çağrılır. Bu yordam odağı son denetime (veyaPrepareEditCtrl
öğesine yapılan son çağrıPrepareCtrl
) geri yükler ve bir özel durum oluşturur. Bu üye işlevi hem DDX_ hem de DDV_ yordamlarından çağrılabilir.
Kullanıcı Uzantıları
Varsayılan DDX/DDV mekanizmasını genişletmenin çeşitli yolları vardır. Şunları yapabilirsiniz:
Yeni veri türleri ekleyin.
CTime
Yeni exchange yordamları ekleyin (DDX_).
void PASCAL DDX_Time(CDataExchange* pDX, int nIDC, CTime& tm);
Yeni doğrulama yordamları ekleyin (DDV_).
void PASCAL DDV_TimeFuture(CDataExchange* pDX, CTime tm, BOOL bFuture); // make sure time is in the future or past
Doğrulama yordamlarına rastgele ifadeler geçirin.
DDV_MinMax(pDX, age, 0, m_maxAge);
Dekont
Bu tür rastgele ifadeler ClassWizard tarafından düzenlenemez ve bu nedenle özel biçim açıklamalarının (//{{{AFX_DATA_MAP(CMyClass)) dışına taşınmalıdır.
Üye işlevinin DoDataExchange
karma değişim ve doğrulama işlevi çağrılarıyla koşullu veya diğer geçerli C++ deyimlerini içermesini sağlayın.
//{{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);
Dekont
Yukarıda gösterildiği gibi, bu tür kod ClassWizard tarafından düzenlenemez ve yalnızca özel biçim açıklamalarının dışında kullanılmalıdır.
ClassWizard Desteği
ClassWizard, kendi DDX_ ve DDV_ yordamlarınızı ClassWizard kullanıcı arabirimiyle tümleştirmenizi sağlayarak DDX/DDV özelleştirmelerinin bir alt kümesini destekler. Bunu yapmak yalnızca belirli DDX ve DDV yordamlarını bir projede veya birçok projede yeniden kullanmak istiyorsanız maliyet açısından faydalıdır.
Bunu yapmak için DDX.CLW dosyasında özel girişler yapılır (Visual C++'ın bu bilgileri APSTUDIO'da depolanmış önceki sürümleri). INI) veya projenizin içinde. CLW dosyası. Özel girdiler, projenizin [Genel Bilgi] bölümüne girilebilir. CLW dosyası veya \Program Files\Microsoft Visual Studio\Visual C++\bin dizinindeki DDX.CLW dosyasının [ExtraDDX] bölümünde. Henüz yoksa DDX.CLW dosyasını oluşturmanız gerekebilir. Özel DDX_/DDV_ yordamlarını yalnızca belirli bir projede kullanmayı planlıyorsanız, girdileri projenizin [Genel Bilgi] bölümüne ekleyin. Bunun yerine CLW dosyası. Yordamları birçok projede kullanmayı planlıyorsanız, girdileri DDX.CLW dosyasının [ExtraDDX] bölümüne ekleyin.
Bu özel girdilerin genel biçimi şunlardır:
ExtraDDXCount=n
burada n , formda izleyebileceğiniz ExtraDDX? satır sayısıdır
ExtraDDX?=tuşlar; vb tuşları; istemi; tür; initValue; DDX_Proc [; DDV_Proc; istem1; arg1 [; istem2; fmt2]]
Nerede? , tanımlanan listede hangi DDX türünü gösteren 1 - n sayısıdır.
Her alan bir ';' karakteriyle sınırlandırılır. Alanlar ve amaçları aşağıda açıklanmıştır.
keys
Bu değişken türü için hangi iletişim kutusu denetimlerine izin verildiğini gösteren tek karakterli bir liste.
Karakter İzin verilen denetim E Düzenle… C iki durumlu onay kutusu c üç durumlu onay kutusu R gruptaki ilk radyo düğmesi L sıralanmamış liste kutusu l sıralanmış liste kutusu M birleşik giriş kutusu (öğeyi düzenle ile) N sıralanmamış bırakma listesi n sıralanmış bırakma listesi 1 DDX eklemesinin listenin başına eklenmesi gerekiyorsa (varsayılan değer kuyruğa eklenir) Bu genellikle 'Control' özelliğini aktaran DDX yordamları için kullanılır. vb tuşları
Bu alan yalnızca VBX denetimleri için 16 bit üründe kullanılır (VBX denetimleri 32 bit üründe desteklenmez)
Istemi
Özellik birleşik giriş kutusuna yerleştirecek dize (tırnak işareti yok)
type
Üst bilgi dosyasında yaymak için tür için tek tanımlayıcı. Yukarıdaki DDX_Time örneğimizde bu, CTime olarak ayarlanır.
vb tuşları
Bu sürümde kullanılmaz ve her zaman boş olmalıdır
initValue
Başlangıç değeri — 0 veya boş. Boşsa, uygulama dosyasının //{{AFX_DATA_INIT bölümüne hiçbir başlatma satırı yazılamaz. Doğru başlatmayı garanti eden oluşturucuları olan C++ nesneleri (,
CString
CTime
vb.) için boş bir giriş kullanılmalıdır.DDX_Proc
DDX_ yordamı için tek tanımlayıcı. C++ işlev adı "DDX_" ile başlamalıdır, ancak DDX_Proc tanımlayıcısında <"DDX_> " içermez. Yukarıdaki örnekte DDX_Proc <> tanımlayıcısı Time olacaktır. ClassWizard işlev çağrısını {{AFX_DATA_MAP bölümündeki uygulama dosyasına yazdığında, bu adı DDX_ ekler ve böylece DDX_Time gelir.
Yorum
Bu DDX ile değişken için iletişim kutusunda gösterilecek açıklama. İstediğiniz metni buraya yerleştirin ve genellikle DDX/DDV çifti tarafından gerçekleştirilen işlemi açıklayan bir şey sağlayın.
DDV_Proc
Girdinin DDV bölümü isteğe bağlıdır. Tüm DDX yordamlarının karşılık gelen DDV yordamları yoktur. Genellikle, doğrulama aşamasını aktarımın ayrılmaz bir parçası olarak eklemek daha uygundur. Bu durum genellikle DDV yordamınız herhangi bir parametre gerektirmediğinde geçerlidir çünkü ClassWizard herhangi bir parametre olmadan DDV yordamlarını desteklemez.
Arg
DDV_ yordamı için tek tanımlayıcı. C++ işlev adı "DDV_" ile başlamalıdır, ancak DDX_Proc tanımlayıcısında <"DDX_> " içermemelidir.
arg ve ardından 1 veya 2 DDV args:
promptN
Düzenleme öğesinin üzerine yerleştirecek dize (hızlandırıcı için & ile).
fmtN
Arg türünün biçim karakteri, bunlardan biri:
Karakter Tür d int u unsigned int D long int (uzun) U uzun imzasız (yani DWORD) f kayan noktalı sayı F çift s Dize