高手能不能帮我彻底剖析下这个函数 和 UpDateData函数 我比较笨 最好能详细和通俗点

我对这个函数不是很了解 我明白是负责控件数据和内部某个变量的双向交换的函数 但是我实在不懂他的机理 似乎很神秘 而且是在UpDateData函数中调用的 程序员一般不怎么调用 就更神秘了 
小弟谢谢高手了

互换的青春
浏览 83回答 2
2回答

陪伴而非守候

关于对话框数据交换及验证&nbsp;对话框的数据交换和验证机制(DDX、DDV)可以使对话框上控件与对象数据成员间协调工作。&nbsp;包括控件窗口与控件对象间的连接,控件窗口与对话框数据成员间的连接,以及数据成员的合法性验证等等。&nbsp;在 virtual void DoDataExchange(CDataExchange* pDX);中记录了这些关系:&nbsp;例如:&nbsp;DDX_Control(pDX, IDC_BUTTON1, m_btn); //CButton对象到控件窗口IDC_BUTTON1的关联&nbsp;DDX_Text(pDX, IDC_EDIT1, m_int); //整型数据到编辑窗口的关联&nbsp;DDV_MinMaxInt(pDX, m_int, 0, 40); //整型数据的范围验证&nbsp;必要时,可以自己编写验证函数实现特定内容检验。&nbsp;相关的成员函数:&nbsp;CDialog::OnInitDialog();&nbsp;CWnd::DoDataExchange();&nbsp;CDialog::DoDataExchange();&nbsp;1 .控件关联&nbsp;DDX_Control实现控件窗口和C++控件对象的关联。&nbsp;由于对话框是以模板的方式建立的,故控件窗口都是事先建立好的。&nbsp;C++控件对象用SubClassWindow的方法附着在控件窗口上,管理窗口的行为。&nbsp;内部流程分析:&nbsp;①OnInitDialog 时调用基类CDialog::OnInitDialog();&nbsp;BOOL CDialog::OnInitDialog()&nbsp;{&nbsp;.....&nbsp;// 执行UpdateData(),参数为FALSE,表示初始化&nbsp;if (!UpdateData(FALSE))&nbsp;{&nbsp;....&nbsp;}&nbsp;.....&nbsp;}&nbsp;②UpdateData()&nbsp;BOOL CWnd::UpdateData(BOOL bSaveAndValidate)&nbsp;{&nbsp;....&nbsp;//调用虚函数DoDataExchange&nbsp;CDataExchange dx(this, bSaveAndValidate);&nbsp;....&nbsp;TRY&nbsp;{&nbsp;DoDataExchange(&dx);&nbsp;bOK = TRUE; // it worked&nbsp;}&nbsp;.....&nbsp;}&nbsp;③DoDataExchange&nbsp;void C????Dlg::DoDataExchange(CDataExchange* pDX)&nbsp;{&nbsp;....&nbsp;//对象到窗口的关联。&nbsp;DDX_Control(pDX, IDC_BUTTON1, m_btn);&nbsp;....&nbsp;}&nbsp;④DDX_Control void AFXAPI DDX_Control(CDataExchange* pDX, int nIDC, CWnd& rControl)&nbsp;{&nbsp;if (rControl.m_hWnd == NULL) //若还未关联&nbsp;{&nbsp;//窗口句柄&nbsp;HWND hWndCtrl = pDX->PrepareCtrl(nIDC);&nbsp;// SubclassWindow 实现关联。&nbsp;if (!rControl.SubclassWindow(hWndCtrl))&nbsp;{&nbsp;....&nbsp;}&nbsp;....&nbsp;}&nbsp;}&nbsp;至此,控件对象与对话框上的子窗口关联上了,可以通过对控件对象的操作来管理该子窗口。&nbsp;2 .数据关联&nbsp;大致流程与前相似。在对话框OnOK()时将调用Update(TRUE),参数TRUE表示读出及校验数据。&nbsp;另可根据需要,随时调用Update(TRUE)完成窗口内容到成员数据的校验及转换。&nbsp;流程分析(以编辑框到整数的关联为例)&nbsp;①DoDataExchange&nbsp;void C???Dlg::DoDataExchange(CDataExchange* pDX)&nbsp;{&nbsp;....&nbsp;DDX_Text(pDX, IDC_EDIT1, m_int);&nbsp;....&nbsp;}&nbsp;②DDX_Text&nbsp;void AFXAPI DDX_Text(CDataExchange* pDX, int nIDC, int& value)&nbsp;{&nbsp;if (pDX->m_bSaveAndValidate) //读取及校验&nbsp;_Afx_DDX_TextWithFormat(pDX, nIDC, _T("%d"), AFX_IDP_PARSE_INT, &value);&nbsp;else //初始化&nbsp;_Afx_DDX_TextWithFormat(pDX, nIDC, _T("%d"), AFX_IDP_PARSE_INT, value);&nbsp;}&nbsp;③_Afx_DDX_TextWithFormat&nbsp;在对话框初始化时,m_bSaveAndValidate参数为FALSE;&nbsp;在进行数据读取时,m_bSaveAndValidate参数为TRUE;&nbsp;AFX_STATIC void AFX_CDECL _Afx_DDX_TextWithFormat(CDataExchange* pDX, int nIDC,&nbsp;LPCTSTR lpszFormat, UINT nIDPrompt, ...)&nbsp;// only supports windows output formats - no floating point&nbsp;{&nbsp;....&nbsp;//窗口句柄&nbsp;HWND hWndCtrl = pDX->PrepareEditCtrl(nIDC);&nbsp;TCHAR szT[32];&nbsp;if (pDX->m_bSaveAndValidate)&nbsp;{&nbsp;//读取&nbsp;// the following works for %d, %u, %ld, %lu&nbsp;::GetWindowText(hWndCtrl, szT, _countof(szT));&nbsp;if (!_AfxSimpleScanf(szT, lpszFormat, pData))&nbsp;{&nbsp;AfxMessageBox(nIDPrompt);&nbsp;pDX->Fail(); // throws exception&nbsp;}&nbsp;}&nbsp;else //对话框初始化时,以成员数据内容初始窗口内容。&nbsp;{&nbsp;//初始化窗口内容。&nbsp;wvsprintf(szT, lpszFormat, pData);&nbsp;AfxSetWindowText(hWndCtrl, szT);&nbsp;}&nbsp;....&nbsp;}&nbsp;3. 数据验证&nbsp;流程分析(以整数数值范围验证为例)&nbsp;void C????Dlg::DoDataExchange(CDataExchange* pDX)&nbsp;{&nbsp;....&nbsp;DDV_MinMaxInt(pDX, m_int, 0, 40);&nbsp;....&nbsp;}&nbsp;void AFXAPI DDV_MinMaxInt(CDataExchange* pDX, int value, int minVal, int maxVal)&nbsp;{&nbsp;ASSERT(minVal <= maxVal);&nbsp;//验证&nbsp;if (value < minVal || value > maxVal)&nbsp;//报错返回&nbsp;_AfxFailMinMaxWithFormat(pDX, (long)minVal, (long)maxVal, _T("%ld"),&nbsp;AFX_IDP_PARSE_INT_RANGE);&nbsp;}&nbsp;

慕盖茨4494581

UpdateData函数内部以this和UpdateData的参数为参数,构造了一个CDataExchange变量,以类变量的形式保存传入构造的参数。然后调用DoDataExchange,传入上面的变量。由于DoDataExchange是虚函数,这就回到了你的类的DoDataExchange中了。DoDataExchange里面的宏很简单,简单看看就明白了。
打开App,查看更多内容
随时随地看视频慕课网APP