{"id":101062,"date":"2019-02-21T07:00:00","date_gmt":"2019-02-21T22:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=101062"},"modified":"2019-03-12T23:57:32","modified_gmt":"2019-03-13T06:57:32","slug":"20190221-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20190221-00\/?p=101062","title":{"rendered":"How do I allow negative numbers with the <CODE>ES_NUMBER<\/CODE> edit control style?"},"content":{"rendered":"<p>The <code>ES_<\/code><code>NUMBER<\/code> edit control style limits typed input to digits, but what if you also want to accept negative numbers? How can we extend&sup1; <code>ES_<\/code><code>NUMBER<\/code> to accept the minus sign? <\/p>\n<p>The <code>ES_<\/code><code>NUMBER<\/code> edit control style works by altering the behavior of the edit control when it receives a <code>WM_<\/code><code>CHAR<\/code>. You can do that too! <\/p>\n<p>Subclass the edit control and handle the <code>WM_<\/code><code>CHAR<\/code> message by checking whether the character is a digit or a minus sign. If not, then beep and return. Otherwise, let the message through. <\/p>\n<pre>\nLRESULT CALLBACK SignedIntegerSubclassProc(\n    HWND hwnd,\n    UINT uMsg,\n    WPARAM wParam,\n    LPARAM lParam,\n    UINT_PTR uIdSubclass,\n    DWORD_PTR dwRefData)\n{\n switch (uMsg) {\n case WM_NCDESTROY:\n  RemoveWindowSubclass(hwnd, SignedIntegerSubclassProc, uIdSubclass);\n  break;\n\n <font COLOR=\"blue\">case WM_CHAR:\n  {\n   wchar_t ch = (wchar_t)wParam;\n   if (ch &lt; L' ') break;                \/\/ let control character through\n   else if (ch == L'-') break;          \/\/ let hyphen-minus through\n   else if (ch == L'\\x2212') break;     \/\/ let Unicode minus sign through\n   else if (<!-- backref: How can I check in Win32 whether a Unicode character is any kind of digit? -->IsUnicodeDigit<\/a>(ch)) break;  \/\/ let digit through\n   MessageBeep(0);                      \/\/ otherwise invalid\n   return 0;\n  }<\/font>\n }\n\n return DefSubclassProc(hwnd, uMsg, wParam, lParam);\n}\n\nBOOL EnforceSignedIntegerEdit(HWND hwnd)\n{\n return SetWindowSubclass(hwnd, SignedIntegerSubclassProc, 0, 0);\n}\n<\/pre>\n<p>If the user entered a character, then we let it through if it is one of the following: <\/p>\n<ul>\n<li>A control character, to permit <kbd>Ctrl+A<\/kbd>,     <kbd>Ctrl+C<\/kbd>, <kbd>Bksp<\/kbd>, <kbd>Tab<\/kbd>,     and so on.<\/li>\n<li>Unicode character U+002D HYPHEN-MINUS, which is what     most people think of as a minus sign.<\/li>\n<li>Unicode character U+2212 MINUS SIGN, which is a true     minus sign.<\/li>\n<\/ul>\n<p>&sup1; As noted in the documentation, the <code>ES_<\/code><code>NUMBER<\/code> edit control style doesn&#8217;t prevent the user from putting non-digits into the edit control by other means, like pasting with <kbd>Ctrl<\/kbd>+<kbd>V<\/kbd>. The exercise is to extend the existing behavior of the <code>ES_<\/code><code>NUMBER<\/code> style, not to fix it to cover all the other scenarios. Our technique has the same defects as <code>ES_<\/code><code>NUMBER<\/code>, but at least it&#8217;s the same defects. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>You&#8217;ll have to roll your own.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-101062","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>You&#8217;ll have to roll your own.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/101062","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=101062"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/101062\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=101062"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=101062"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=101062"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}