神奇的特性都是由 CRegexForm 自己实现的。你只需使用它即可,使用方法相当直白,首先你得定义一个自己窗体。下面是 TestForm 的窗体内容,这些定义位于 MainDlg.cpp:
// 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() 这个宏定义了一个静态表格,表格描述每个编辑控制域。大多数情况下你只需要控制 ID,还要有地方放标志和 RegexOptions。例如,在 TestForm 中,邮政编码是必输域(RGXF_REQUIRED),质数(Prime Number)输入域使用回调(稍后会详细讨论),最喜爱的专栏作家(IDC_FAVCOL)指定 CMRegex::IgnoreCase,它使得大小写 不敏感。
 Figure 3 Pietrek I Think Not!
看着表格你可能想知道正则表达式在哪。回答是:在资源文件中。对于每个域/控制ID,CRegexForm 都期望有一个具有相同ID的资源串。资源串由五个子串组成,子串之间用新行符( )分隔。一般格式为:
“Name Regex LegalChars Hint ErrMsg”。以下是 IDC_ZIP 所用的串:
"Zip Code ^\d{5}(-\d{4}) $ [\d-] ##### or #####-####" 第一个子串“Zip Code”是域名。第二个“^d{5}(-d{4}) $”,是用于验证邮编的正则表达式。(在资源串中必须敲入两个反斜线,目的是转义正则表达式中反斜线)。第三个子串是另外一个正则表达式,用来描述合法字符。对于邮编来说,即是“[d-]”,意思是允许数字和连字符(hyphen)。如果输入域无字符限制,你可以通过敲入两个连续的新行符(“ ”意思是空子串)省略 LegalChars 检查。第四个子串全部为工具提示串。最后你可以提供第五个子串,如果该输入域无效则显示错误信息。对于邮编来说,它没有错误信息,所以 CRegexForm 产生一个默认的信息,形式为“Should be xxx”,xxx 被工具提示替代。“Should be”本身即是另一个资源串(稍后还要说到)。这些子串中,只有第一个域是必输域。
为什么用资源串来保存所有信息,而不直接在域映射中编码处理呢?首先,将它放在映射中使得代码很笨拙。把这些乱七八糟的字符串放在不显眼的地方有利于代码更整洁。此外宏无法处理可选参数,根据你所用参数的多少,你需要多个宏,如:RGXFIELD3、RGXFIELD4 和 RGXFIELD5。这样不是太笨拙了嘛?使用资源串真正的好处在于容易本地化
|