亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

高手能不能幫我徹底剖析下這個函數 和 UpDateData函數 我比較笨 最好能詳細和通俗點

高手能不能幫我徹底剖析下這個函數 和 UpDateData函數 我比較笨 最好能詳細和通俗點

C++
互換的青春 2022-12-21 19:15:26
我對這個函數不是很了解 我明白是負責控件數據和內部某個變量的雙向交換的函數 但是我實在不懂他的機理 似乎很神秘 而且是在UpDateData函數中調用的 程序員一般不怎么調用 就更神秘了 小弟謝謝高手了
查看完整描述

2 回答

?
陪伴而非守候

TA貢獻1757條經驗 獲得超8個贊

關于對話框數據交換及驗證 

對話框的數據交換和驗證機制(DDX、DDV)可以使對話框上控件與對象數據成員間協調工作。 

包括控件窗口與控件對象間的連接,控件窗口與對話框數據成員間的連接,以及數據成員的合法性驗證等等。 

在 virtual void DoDataExchange(CDataExchange* pDX);中記錄了這些關系: 
例如: 

DDX_Control(pDX, IDC_BUTTON1, m_btn); //CButton對象到控件窗口IDC_BUTTON1的關聯 
DDX_Text(pDX, IDC_EDIT1, m_int); //整型數據到編輯窗口的關聯 
DDV_MinMaxInt(pDX, m_int, 0, 40); //整型數據的范圍驗證 

必要時,可以自己編寫驗證函數實現特定內容檢驗。 

相關的成員函數: 

CDialog::OnInitDialog(); 
CWnd::DoDataExchange(); 
CDialog::DoDataExchange(); 

1 .控件關聯 

DDX_Control實現控件窗口和C++控件對象的關聯。 
由于對話框是以模板的方式建立的,故控件窗口都是事先建立好的。 
C++控件對象用SubClassWindow的方法附著在控件窗口上,管理窗口的行為。 
內部流程分析: 

①OnInitDialog 時調用基類CDialog::OnInitDialog(); 

BOOL CDialog::OnInitDialog() 

..... 
// 執行UpdateData(),參數為FALSE,表示初始化 
if (!UpdateData(FALSE)) 

.... 

..... 


②UpdateData() 

BOOL CWnd::UpdateData(BOOL bSaveAndValidate) 

.... 

//調用虛函數DoDataExchange 
CDataExchange dx(this, bSaveAndValidate); 
.... 
TRY 

DoDataExchange(&dx); 
bOK = TRUE; // it worked 

..... 


③DoDataExchange 
void C????Dlg::DoDataExchange(CDataExchange* pDX) 

.... 
//對象到窗口的關聯。 
DDX_Control(pDX, IDC_BUTTON1, m_btn); 
.... 


④DDX_Control void AFXAPI DDX_Control(CDataExchange* pDX, int nIDC, CWnd& rControl) 

if (rControl.m_hWnd == NULL) //若還未關聯 

//窗口句柄 
HWND hWndCtrl = pDX->PrepareCtrl(nIDC); 
// SubclassWindow 實現關聯。 
if (!rControl.SubclassWindow(hWndCtrl)) 

.... 

.... 



至此,控件對象與對話框上的子窗口關聯上了,可以通過對控件對象的操作來管理該子窗口。 

2 .數據關聯 

大致流程與前相似。在對話框OnOK()時將調用Update(TRUE),參數TRUE表示讀出及校驗數據。 

另可根據需要,隨時調用Update(TRUE)完成窗口內容到成員數據的校驗及轉換。 

流程分析(以編輯框到整數的關聯為例) 

①DoDataExchange 

void C???Dlg::DoDataExchange(CDataExchange* pDX) 

.... 
DDX_Text(pDX, IDC_EDIT1, m_int); 
.... 


②DDX_Text 

void AFXAPI DDX_Text(CDataExchange* pDX, int nIDC, int& value) 


if (pDX->m_bSaveAndValidate) //讀取及校驗 
_Afx_DDX_TextWithFormat(pDX, nIDC, _T("%d"), AFX_IDP_PARSE_INT, &value); 
else //初始化 
_Afx_DDX_TextWithFormat(pDX, nIDC, _T("%d"), AFX_IDP_PARSE_INT, value); 


③_Afx_DDX_TextWithFormat 

在對話框初始化時,m_bSaveAndValidate參數為FALSE; 

在進行數據讀取時,m_bSaveAndValidate參數為TRUE; 

AFX_STATIC void AFX_CDECL _Afx_DDX_TextWithFormat(CDataExchange* pDX, int nIDC, 
LPCTSTR lpszFormat, UINT nIDPrompt, ...) 
// only supports windows output formats - no floating point 

.... 
//窗口句柄 
HWND hWndCtrl = pDX->PrepareEditCtrl(nIDC); 
TCHAR szT[32]; 
if (pDX->m_bSaveAndValidate) 

//讀取 
// the following works for %d, %u, %ld, %lu 
::GetWindowText(hWndCtrl, szT, _countof(szT)); 
if (!_AfxSimpleScanf(szT, lpszFormat, pData)) 

AfxMessageBox(nIDPrompt); 
pDX->Fail(); // throws exception 


else //對話框初始化時,以成員數據內容初始窗口內容。 


//初始化窗口內容。 
wvsprintf(szT, lpszFormat, pData); 
AfxSetWindowText(hWndCtrl, szT); 

.... 


3. 數據驗證 

流程分析(以整數數值范圍驗證為例) 

void C????Dlg::DoDataExchange(CDataExchange* pDX) 

.... 
DDV_MinMaxInt(pDX, m_int, 0, 40); 
.... 

void AFXAPI DDV_MinMaxInt(CDataExchange* pDX, int value, int minVal, int maxVal) 

ASSERT(minVal <= maxVal); 

//驗證 
if (value < minVal || value > maxVal) 
//報錯返回 
_AfxFailMinMaxWithFormat(pDX, (long)minVal, (long)maxVal, _T("%ld"), 
AFX_IDP_PARSE_INT_RANGE); 
}

 


查看完整回答
反對 回復 2022-12-25
?
慕蓋茨4494581

TA貢獻1850條經驗 獲得超11個贊

UpdateData函數內部以this和UpdateData的參數為參數,構造了一個CDataExchange變量,以類變量的形式保存傳入構造的參數。
然后調用DoDataExchange,傳入上面的變量。
由于DoDataExchange是虛函數,這就回到了你的類的DoDataExchange中了。
DoDataExchange里面的宏很簡單,簡單看看就明白了。

查看完整回答
反對 回復 2022-12-25
  • 2 回答
  • 0 關注
  • 105 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號