This post has been republished via RSS; it originally appeared at: MSDN Blogs.
The ES_
NUMBER
edit control style
limits typed input to digits,
but what if you also want to accept negative numbers?
How can we extend¹ ES_
NUMBER
to
accept the minus sign?
The ES_
NUMBER
edit control style
works by altering the behavior of the edit control when
it receives a WM_
CHAR
.
You can do that too!
Subclass the edit control and handle the
WM_
CHAR
message by checking whether the character is a digit
or a minus sign.
If not, then beep and return.
Otherwise, let the message through.
LRESULT CALLBACK SignedIntegerSubclassProc(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam,
UINT_PTR uIdSubclass,
DWORD_PTR dwRefData)
{
switch (uMsg) {
case WM_NCDESTROY:
RemoveWindowSubclass(hwnd, SignedIntegerSubclassProc, uIdSubclass);
break;case WM_CHAR:
{
wchar_t ch = (wchar_t)wParam;
if (ch < L' ') break; // let control character through
else if (ch == L'-') break; // let hyphen-minus through
else if (ch == L'x2212') break; // let Unicode minus sign through
else if (IsUnicodeDigit(ch)) break; // let digit through
MessageBeep(0); // otherwise invalid
return 0;
}
}return DefSubclassProc(hwnd, uMsg, wParam, lParam);
}BOOL EnforceSignedIntegerEdit(HWND hwnd)
{
return SetWindowSubclass(hwnd, SignedIntegerSubclassProc, 0, 0);
}
If the user entered a character, then we let it through
if it is one of the following:
- A control character, to permit Ctrl+A,
Ctrl+C, Bksp, Tab,
and so on. - Unicode character U+002D HYPHEN-MINUS, which is what
most people think of as a minus sign. - Unicode character U+2212 MINUS SIGN, which is a true
minus sign.
¹
As noted in the documentation,
the ES_
NUMBER
edit control style
doesn't prevent the user
from putting non-digits into the edit control by other means,
like pasting with Ctrl+V.
The exercise is to extend the existing behavior of the
ES_
NUMBER
style,
not to fix it to cover all the other scenarios.
Our technique has the same defects as
ES_
NUMBER
,
but at least it's the same defects.