{"id":3753,"date":"2013-07-22T07:00:00","date_gmt":"2013-07-22T07:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2013\/07\/22\/a-program-for-my-nieces-the-abcs-part-3\/"},"modified":"2013-07-22T07:00:00","modified_gmt":"2013-07-22T07:00:00","slug":"a-program-for-my-nieces-the-abcs-part-3","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20130722-00\/?p=3753","title":{"rendered":"A program for my nieces: The ABCs, part 3"},"content":{"rendered":"<p>\nOne problem I discovered when my nieces ran my initial\n<a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2013\/07\/08\/10432277.aspx\">\nABC program<\/a>\nwas that they had a habit of holding down a key,\nthereby triggering autorepeat.\nI had instructed them not to mash the keyboard but rather\nto press only one key at a time,\nand while they were good at adhering to the &#8220;one key at a time&#8221;\nrule,\nthey also interpreted it as\n&#8220;type really slowly&#8221;\nand ended up autorepeating a lot.\n<\/p>\n<p>\nSo let&#8217;s disable keyboard autorepeat.\n<\/p>\n<p>\nOf course, one way to do this would be to change the system\nkeyboard autorepeat setting,\nbut that would be\n<a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2008\/12\/11\/9193695.aspx\">\nusing global state to manage a local problem<\/a>.\nInstead, we just filter the autorepeats out of our edit control:\n<\/p>\n<pre>\n<font COLOR=\"blue\">LRESULT CALLBACK EditSubclassProc(\n    HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam,\n    UINT_PTR uIdSubclass, DWORD_PTR dwRefData)\n{\n  switch (uMsg) {\n  case WM_NCDESTROY:\n    RemoveWindowSubclass(hwnd, EditSubclassProc, uIdSubclass);\n    break;\n  case WM_CHAR:\n    if ((lParam &amp; 0x40000000) &amp;&amp; wParam != VK_BACK) return 0;\n    break;\n  }\n    return DefSubclassProc(hwnd, uMsg, wParam, lParam);\n}<\/font>\nBOOL\nOnCreate(HWND hwnd, LPCREATESTRUCT lpcs)\n{\n  ...\n  <font COLOR=\"blue\">SetWindowSubclass(g_hwndChild, EditSubclassProc, 0, 0);<\/font>\n  SetWindowFont(g_hwndChild, g_hfEdit, TRUE);\n  return TRUE;\n}\n<\/pre>\n<p>\nBit 30 in the <code>lParam<\/code> of a\n<code>WM_CHAR<\/code> message\nsays whether the key was already down.\nIf we see that bit set,\nthen we know that the message was an autorepeat\nand we throw the message away.\n(But I let the backspace key through because that lets me\nerase a lot of text quickly.)\n<\/p>\n<p>\nIt&#8217;s important that the subclass procedure be removed before\nthe window is destroyed.\nOne way of doing this is to remove the subclass procedure\nin the parent window&#8217;s\n<code>WM_DESTROY<\/code> handler,\nbut since I don&#8217;t have one,\nand I&#8217;m too lazy to make one,\nI go for the alternate method of doing just-in-time deregistration\nby removing the subclass procedure in the subclass procedure itself.\n<\/p>\n<p>\nThis version of the\nprogram managed to keep my nieces happy for quite some time.\nWe&#8217;ll tinker with it some more next week.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>One problem I discovered when my nieces ran my initial ABC program was that they had a habit of holding down a key, thereby triggering autorepeat. I had instructed them not to mash the keyboard but rather to press only one key at a time, and while they were good at adhering to the &#8220;one [&hellip;]<\/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-3753","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>One problem I discovered when my nieces ran my initial ABC program was that they had a habit of holding down a key, thereby triggering autorepeat. I had instructed them not to mash the keyboard but rather to press only one key at a time, and while they were good at adhering to the &#8220;one [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/3753","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=3753"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/3753\/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=3753"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=3753"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=3753"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}