更新时间:2016-02-21 22:21:49浏览次数:1+次
CWnd::UpdateData方法还有一个额外的好处就是支持数据验证,其实也就是断言(assert)在这里就不说这个方面了。我们看看UpdateData的实现细节:
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; }
从实现代码可以看出,数据交换与验证主要用到数据交换对象CDataExchange,并以该对象为参数调用DoDataExchange。也就是说呢,我们调用UpdateData函数其实是调用DoDateDataExchange函数。CDataExchange对象的m_nSaveAndValidate指示数据交换方向。m_pDlgWnd表示进行数据交换与验证的目标对话框。那么接下来我们看看DoDataExchange函数:
_AFXWIN_INLINE void CWnd::DoDataExchange(CDataExchange*) { } // default does nothing看到这里,你也就应该懂了,DoDataExchange函数又是调用了DDX_Text函数,那么,我们右键查看头文件,就能看到一系列的DDX_XXX函数了:
接下来我们看看DDX_Text函数的源代码:
void AFXAPI DDX_Text(CDataExchange* pDX, int nIDC, CString& value) { HWND hWndCtrl = pDX->PrepareEditCtrl(nIDC); if (pDX->m_bSaveAndValidate) { int nLen = ::GetWindowTextLength(hWndCtrl); ::GetWindowText(hWndCtrl, value.GetBufferSetLength(nLen), nLen+1); value.ReleaseBuffer(); } else { AfxSetWindowText(hWndCtrl, value); } }这代码实现可谓是一目了然。因此,看到这里,我们应该秒懂了,我们用UpdateData函数来实现数据交换,其实就是DDX_XXX函数来帮我们做的,而代码实现则是非常简单。
相关资讯