VC++中的DDX和DDV
DDX/DDV
通過使用ClassWizard向對話類添加成員變量,你可以利用ClassWizard所提供的高效特征,為對話數據交換和對話數據驗證自動生成源代碼,也就是人們所熟知的DDX/DDV。
數據交換和驗證僅僅應用于為之選定了Value類別的成員變量。也就是CString,BOOL,數字,COleDateTime或COLeCurrency。
對話數據交換負責數據在控件中的進出。當對話首次出現的時候,每個控件窗口自動用相應的成員變量的值進行初始化。當用戶通過單擊OK按鈕,或通過按Enter鍵關閉對話的時候,該控件無論是包含哪一個值或文本,都將被復制回該變量。
對話數據驗證可以確保值落在規定的限制之內。交換和驗證機制都是由MFC框架提供的。每個函數都有一個前綴DDX_或DDV_,來把它作為數據交換或數據驗證函數來標識。
1. 對話數據交換(DDX)
常見的對話數據交換函數
(1)交換函數:DDX_CBIndex, 獲得/設置的數據類型:int, 應用于控件:Combobox
(2)交換函數:DDX_CBString, 獲得/設置的數據類型:Cstring, 應用于控件:Combobox
(3)交換函數:DDX_CBStringExact,獲得/設置的數據類型:Cstring, 應用于控件:Combobox
(4)交換函數:DDX_Check, 獲得/設置的數據類型:intCheck, 應用于控件:box
(5)交換函數:DDX_DateTimeCtrl, 獲得/設置的數據類型:Ctime, 應用于控件:Datetimepicker
(6)交換函數:DDX_LBIndex, 獲得/設置的數據類型:int, 應用于控件:List box
(7)交換函數:DDX_LBString, 獲得/設置的數據類型:CString, 應用于控件:Listbox
(8)交換函數:DDX_LBStringExact,獲得/設置的數據類型:CString, 應用于控件:List box
(9)交換函數:DDX_MonthCalCtrl,獲得/設置的數據類型:Ctime, 應用于控件:Month calendar
(10)交換函數:DDX_Radio, 獲得/設置的數據類型:int, 應用于控件:Radio button
(11)交換函數:DDX_Scroll, 獲得/設置的數據類型:int, 應用于控件:Scroll bar
(12)交換函數:DDX_Text, 獲得/設置的數據類型:CStringor numerical(BYTE,short,int,UINT,long,etc.),應用于控件:Edit control
在所有的數據交換函數之中,該函數是獨一無二的,它只應用于一組控件,而不是一個控件。DDX_Radio返回一個int值用來指示用戶打開了組中的哪個按鈕:0代表組中的第一個按鈕,1代表第二個按鈕,以此類推。值-1的意思是小組中的所有按鈕都是清除的。你可以調用DDX_Radio來確定單個單選按鈕的狀態(假如它是組中的唯一一個按鈕)。在這種情況下,返回值0的意思是按鈕是打開的,值-1意為按鈕是關閉的。
建立一個單選按鈕通常在對話編輯器中進行,我們一會兒就能看到。
MFC提供了大量的對話數據交換函數,它們可以在對話類中的控件成員變量之間移動數據。除了所列的常見函數之外,還有用于記錄集數據和由ActiveX控件返回的數據的特殊交換函數。DDX_Control函數可以為幾種不同類型的控件傳輸數據,例如Animate和IPAddress。
2. 對話數據驗證(DDV)對話數據驗證函數,它們僅僅應用于接受用于從鍵盤輸入數據的控件成員變量。換言之,就是編輯控件和組合框。
對話數據驗證函數
(1)DDV_MinMaxByte指定限制范圍內的一個BYTE值。
(2)DDV_MinMaxInt指定限制范圍內的一個int值。
(3)DDV_MinMaxUInt指定限制范圍內的一個UNIT值。
(4)DDV_MinMaxLong指定限制范圍內的一個long值。
(5)DDV_MinMaxDWord指定限制范圍內的一個DWORD值。
(6)DDV_MinMaxFloat指定限制范圍內的一個float值。
(7)DDV_MinMaxDouble指定限制范圍內的一個double值。
(8)DDV_MaxCharsCString字符串的長度不能超過指定的最大長度。
當你為編輯控件或組合框添加成員變量,然后在Member Variable選項卡中的Control IDs框中選擇控件的時候,兩個提示之一將會出現在該選項卡的底部。究竟出現哪一個提示取決于變量所具有的是數字數據,還是文字數據;在任一種情況下,都要輸入用于驗證的變量限制值。
除了一個對話數據驗證函數之外,所有函數都監視數值數據,以確保由用戶輸入的值落在指定的上下限之間。
例外是DDV_MaxChars函數,它用來驗證鍵入到編輯控件或組合框中的字符數不超過給定的最大值。與交換函數不同,驗證函數僅僅在對話關閉的時候起作用,而不在它剛出現的時候起作用。
如果輸入到一個控件的值落到了指定的限制之外,那么,該控件的驗證函數將顯示一個消息框,以通知用戶出了問題。當消息框被關閉的時候,出問題的控件將具有一個焦點,提示用戶重新輸入數據。除非所有的數據驗證函數都滿足了,否則,用戶不能夠通過單擊OK來關閉對話。
-----------------------------------------------------------------------------
DDX:Dialog Data Exchange
如果使用DDX機制,一般會在OnInitDialog消息處理函數或Dialog構造函數中,為對話
框對象的成員變量設置了初始值。在對話框顯示前,框架的DDX機制將成員變量的值傳
給對話框中的控件,當調用DoModal或Create函數,對話框即將顯示時,這些值也就顯
示在相應的控件上。
CDialog類的成員函數OnInitDialog的默認實現中,調用CWnd類的UpdateData成員函數
來初始化對話框的控件。
當用戶單擊OK按鈕或調用成員函數UpdateData(TRUE),相同的機制會將控件值傳給成員
變量。
DDV:Dialog Data Validation
DDV機制會根據用戶指定的驗證規則來驗證數據
UpdateData函數創建一個CDataExchange對象,并調用CDialog類DoDataExchange 成員
函數的對話框重載函數:
BOOL CWnd::UpdateData(BOOL bSaveAndValidate)
{
ASSERT(::IsWindow(m_hWnd)); // calling UpdateData before DoModal?
CDataExchange dx(this, bSaveAndValidate);
// prevent control notifications from being dispatched during
UpdateData
_AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
HWND hWndOldLockout = pThreadState->m_hLockoutNotifyWindow;
ASSERT(hWndOldLockout != m_hWnd); // must not recurse
pThreadState->m_hLockoutNotifyWindow = m_hWnd;
BOOL bOK = FALSE; // assume failure
TRY
{
DoDataExchange(&dx);
bOK = TRUE; // it worked
}
CATCH(CUserException, e)
{
// validation failed - user already alerted, fall through
ASSERT(!bOK);
// Note: DELETE_EXCEPTION_(e) not required
}
AND_CATCH_ALL(e)
{
// validation failed due to OOM or other resource failure
e->ReportError(MB_ICONEXCLAMATION,
AFX_IDP_INTERNAL_FAILURE);
ASSERT(!bOK);
DELETE_EXCEPTION(e);
}
END_CATCH_ALL
pThreadState->m_hLockoutNotifyWindow = hWndOldLockout;
return bOK;
}
在對話框的重載函數DoDataExchange中,又調用CDialog::DoDataExchange(pDX)
void CSquare::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CSquare)
DDX_Text(pDX, IDC_LENGTH, m_length);
DDV_MinMaxInt(pDX, m_length, 10, 200);
//}}AFX_DATA_MAP
}
UpdateData(TRUE); // 更新數據為真,則表示控件->成員變量
UpdateData(FALSE);// 更新數據為假,則表示成員變量->控件
所以,在更新數據時我們只調用UpdateData函數就行了!
RFID管理系統集成商 RFID中間件 條碼系統中間層 物聯網軟件集成