To reduce the chances of error even further, I lock out an characters that are not actually valid. So for my floating-point control, I disallow all characters except the digits, plus and minus signs, decimal point, and the letters 'e' and 'E'. And backspace. Don't forget backspace!
A common piece of advice that appears is to "put this in the PreTranslateMessage handler of your dialog". This doesn't make any sense to me; it violates any number of issues of abstraction and object orientation. It makes a lot more sense to me to put this in the control that wants to filter the characters. To do this, I write a handler like the one shown below, which appears in my subclassed dialog. This gets created when I add a WM_CHAR handler using ClassWizard, and all I do is fill in the code shown.
void CFloatingEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
switch(nChar)
{ /* validate */
case _T('+'):
case _T('-'):
case _T('.'):
case _T('E'):
case _T('e'):
case _T('0'):
case _T('1'):
case _T('2'):
case _T('3'):
case _T('4'):
case _T('5'):
case _T('6'):
case _T('7'):
case _T('8'):
case _T('9'):
case _T('\b'):
break;
default:
MessageBeep(0);
return;
} /* validate */
CEdit::OnChar(nChar, nRepCnt, nFlags);
}
All this does is accept the characters shown, and call the superclass handler, or simply issue a beep and return, thus discarding the character.
Summary
This article summarizes a set of techniques I use extensively in the applications I build. I've not seen this set of ideas documented elsewhere, so this seemed a good topic for an essay.
Comments