// user PRessed OK:
void CMyDialog::OnOK() {
UpdateData(TRUE); // 获得对话框数据
...
}
void CMyDialog::DoDataExchange(CDataExchange* pDX) {
CDialog::DoDataExchange(pDX);
DDX_Text(pDX, IDC_NAME, m_name);
DDX_Text(pDX, IDC_AGE, m_age);
...
// etc.
}
// in CMyDialog::DoDataExchange
DDX_Text(pDX, IDC_NAME, m_sName); // 获得/设置值
DDV_MaxChars(pDX, m_sName, 35); // 验证
// m_age is int
DDX_Text(pDX, IDC_AGE, m_age);
DDV_MinMaxInt(pDX, m_age, 1, 120);
void DDV_Regex(CDataExchange* pDX, CString& val,
LPCTSTR pszRegex)
{
if (pDX->m_bSaveAndValidate) {
CMRegex r(pszRegex);
if (!r.Match(val).SUCcess()) {
pDX->Fail(); // throws exception
}
}
}
// in CMyDialog::DoDataExchange
DDX_Text(pDX, IDC_Zip, m_zip);
DDV_Regex(pDX, m_zip,_T("^//d{5}(-//d{4})?$"));
DDX_Text(pDX, IDC_FOO,...);
DDV_Mumble(pDX, ...)
DDX_Text(pDX, IDC_BAR,...);
DDV_Bletch(...)
... // etc for 14 lines
// form/field map
BEGIN_REGEX_FORM(MyRegexForm)
RGXFIELD(IDC_ZIP,RGXF_REQUIRED,0)
RGXFIELD(IDC_SSN,0,0)
RGXFIELD(IDC_PHONE,0,0)
RGXFIELD(IDC_TOKEN,0,0)
RGXFIELD(IDC_PRIME,RGXF_CALLBACK,0)
RGXFIELD(IDC_FAVCOL,0,CMRegex::IgnoreCase)
END_REGEX_FORM()
"Zip Code/n^//d{5}(-//d{4})?$/n[//d-]/n##### or #####-####"
CString str;
str.LoadString(nID);
vector<CString> substrs = CMRegex::Split(str, _T("/n"));
// in OnInitDialog
m_rgxForm.Init(MyRegexForm, this, IDS_MYREGEXFORM, MYWM_RGXFORM_MESSAGE);
Figure 4 Procedural Validation Using Callback Message //////////////////
// Handle notification from Regex Form Manager:
// Do custom validation for Prime Number.
//
LRESULT CMainDlg::OnRgxFormMessage(WPARAM wp, LPARAM lp)
{
UINT nID = LOWord(wp);
UINT nCode = HIWORD(wp);
if (nCode==RGXNM_VALIDATEFIELD) { // custom validation:
if (nID==IDC_PRIME) {
const CString& val = *(CString*)lp;
if (val.IsEmpty())
return RGXERR_OK;
int p = _tstoi(val);
return IsPrime(p) ? RGXERR_OK : RGXERR_NOMATCH;
}
ASSERT(FALSE); // shouldn't happen
}
return 0;
}
void CMyDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
m_rgxForm.DoDataExchange(pDX);
}
m_rgxForm.SetFieldValue(IDC_ZIP,_T("10025"));
void CMyDialog::OnOK()
{
UpdateData(TRUE); // 拷贝屏幕输入->对话框
int nBad = m_rgxForm.Validate();
if (nBad>0) {
m_badFields = m_rgxForm.GetBadFields();
...
}
Figure 6 CMainDlg::OnOK //////////////////
// User pressed OK: validate form and display results: error message
// or field values—but don't call base class to end dialog.
//
void CMainDlg::OnOK()
{
UpdateData(TRUE); // get dialog data int nBad = m_rgxForm.Validate(); // validate
CString msg;
if (nBad>0) {
vector<UINT> badFields = m_rgxForm.GetBadFields();
BOOL beep = TRUE;
if (nBad>1) {
// Multiple bad fields: show message box with bad fields.
msg = _T("The following fields are bad:/n/n");
vector<UINT>::iterator it;
for (it = badFields.begin(); it!=badFields.end(); it++) {
UINT nID = *it;
CString s;
s.Format(_T("%s: %s/n"), m_rgxForm.GetFieldName(nID),m_rgxForm.GetFieldErrorMsg(nID));
msg += s;
}
MessageBox(msg,_T("Oops—Some fields are bad."),MB_ICONEXCLAMATION);
beep = FALSE; // message box already beeped; don't beep again
}
// to highlight first bad field whether one or many
UINT nID = badFields[0];
m_rgxForm.ShowBadField(nID, beep, TRUE); } else {
// all fields OK: show feeback
msg = _T("You Entered:/n/n");
for (int i=0; MyRegexForm[i].id; i++) {
CString name = m_rgxForm.GetFieldName(MyRegexForm[i].id);
CString val = m_rgxForm.GetFieldValue(MyRegexForm[i].id);
if (val.IsEmpty())
val = _T("(nothing)");
CString temp;
temp.Format(_T("%s = %s/n"), name, val);
msg += temp;
}
MessageBox(msg,_T("Congratulations! All fields OK."),MB_OK);
m_rgxForm.Feedback(_T(" All fields OK or empty!"));
}
}
新闻热点
疑难解答