困惑
曾经对UpdateData()的参数是传入TRUE还是传入FALSE迷惑过,每次调用的时候就会去MSDN一遍。现在就彻底解惑一下。
规则
规则
在使用ClassWizard建立了控件和变量之间的映射关系之后:
- 变量的值变化了,需要更新到UI上面,就调用UpdateData(FALSE);
- 界面上用户输入了一些数据,希望更新到变量中(或者说获取用户输入的数据),则调用UpdateData(TRUE)。
理解
UpdateData()这个函数的名称可以这样子理解:Update member Data?,就是把这个函数调用当作一个疑问句来思考:是否希望更新成员数据?
- Yes/TRUE? 那么就传TRUE。
- 否则,就传FALSE。即不是要更新成员数据,而是反过来,数据变了,希望更新的是界面。
MSDN
MFC的定义:
BOOL UpdateData(BOOL bSaveAndValidate = TRUE);
save and validate.
注意形式参数意为save and validate, 保存用户输入的数据,并对用户输入的数据进行校验。比如要求某个控件只能输出数字,结果用户输入了其他的字符,那么UpdateData(TRUE)的时候,就会检查出错误,这个函数就会返回FALSE。
所以,UpdateData(TRUE)实际上是有两个职责的:1. 保存用户的数据;2. 校验用户的数据。其返回值BOOL则是针对第二点所言的。
示例
比如下面这个例子的代码是:
UpdateData(TRUE); //先把用户的输入更新到成员数据
m_sFirst = m_sSecond; //修改其他的成员数据
UpdateData(FALSE); //把这个修改结果更新到UI上,知会用户。
对话框:
功能:
其中一个编辑框中的内容变化后,另外一个编辑框自动同步更新。
.rc文件:
IDD_TAB_INDEX_DIALOG DIALOGEX 0, 0, 202, 103
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_APPWINDOW
CAPTION "Example"
FONT 9, "宋体"
BEGIN
LTEXT "First:",IDC_STATIC_FIRST,17,19,32,12
EDITTEXT IDC_EDIT_FIRST,51,17,126,17,ES_AUTOHSCROLL
LTEXT "Second:",IDC_STATIC_SECOND,15,43,30,12
EDITTEXT IDC_EDIT_SECOND,53,41,124,19,ES_AUTOHSCROLL
DEFPUSHBUTTON "确定",IDOK,15,72,50,14
PUSHBUTTON "取消",IDCANCEL,115,71,50,14
END
.h文件:
// Dialog Data
//{{AFX_DATA(CTab_indexDlg)
enum { IDD = IDD_TAB_INDEX_DIALOG };
CString m_sFirst;
CString m_sSecond;
//}}AFX_DATA
// Implementation
protected:
HICON m_hIcon;
// Generated message map functions
//{{AFX_MSG(CTab_indexDlg)
afx_msg void OnChangeEditSecond();
afx_msg void OnChangeEditFirst();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
.cpp文件:
void CTab_indexDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CTab_indexDlg)
DDX_Text(pDX, IDC_EDIT_FIRST, m_sFirst);
DDX_Text(pDX, IDC_EDIT_SECOND, m_sSecond);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CTab_indexDlg, CDialog)
//{{AFX_MSG_MAP(CTab_indexDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_EN_CHANGE(IDC_EDIT_SECOND, OnChangeEditSecond)
ON_EN_CHANGE(IDC_EDIT_FIRST, OnChangeEditFirst)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
void CTab_indexDlg::OnChangeEditSecond()
{
UpdateData(TRUE);
m_sFirst = m_sSecond;
UpdateData(FALSE);
}
void CTab_indexDlg::OnChangeEditFirst()
{
UpdateData(TRUE);
m_sSecond = m_sFirst;
UpdateData(FALSE);
}
数据校验
还可以用UpdateData(TRUE)实现数据校验的功能。比如,一个Edit Control需要输入整数,那么可以在这个Edit Control失去焦点的时候,调用UpdateData(TRUE);。如果用户输入的不是整数,那么系统就会自动弹出错误提示框,且焦点仍然在该Edit Control中。
如果为该控件设置了最小值最大值范围、或者该控件映射为double类型,等等,UpdateData(TRUE);都会自动去校验。