{"id":100045,"date":"2018-10-24T07:00:00","date_gmt":"2018-10-24T21:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/?p=100045"},"modified":"2019-03-13T00:22:31","modified_gmt":"2019-03-13T07:22:31","slug":"20181024-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20181024-00\/?p=100045","title":{"rendered":"Adding a Ctrl+arrow accelerator for moving the trackbar by just one unit, part 2: Second try"},"content":{"rendered":"<p>Last time, we looked at how we could add support to the trackbar so that <kbd>Ctrl<\/kbd>+arrow moved the thumb by one unit, even if the line size was set to a larger value. We tried doing this by subclassing the control and adding additional keyboard handling, but this turned into a bit of a mess because of all the special cases in the trackbar to accommodate various usage patterns. <\/p>\n<p>What we really want to do is let the trackbar do all its keyboard processing, and step in just before it moves the thumb, so we can move it by a different amount if the <kbd>Ctrl<\/kbd> key is held down. <\/p>\n<p>Fortunately, there&#8217;s a notification for this. <\/p>\n<p>Unfortunately, it requires version 6 of the common controls. <\/p>\n<p>Fortunately, version 6 of the common controls is included in all versions of Windows still in support. <\/p>\n<p>Take our program from last time, but stop before we added the <code>Trackbar&shy;Key&shy;Proc<\/code>. (Delete the <code>Trackbar&shy;Key&shy;Proc<\/code> and the calls to <code>Set&shy;Window&shy;Subclass<\/code> and <code>Remove&shy;Window&shy;Subclass<\/code>.) <\/p>\n<p>Instead, add this code: <\/p>\n<pre>\n<font COLOR=\"blue\">#pragma comment(linker, \\\n    \"\\\"\/manifestdependency:type='win32' \\\n    name='Microsoft.Windows.Common-Controls' \\\n    version='6.0.0.0' \\\n    processorArchitecture='*' \\\n    publicKeyToken='6595b64144ccf1df' \\\n    language='*'\\\"\")<\/font>\n<\/pre>\n<p>This <code>#pragma<\/code> is <a HREF=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/\">a quick way to enable version 6 of the common controls<\/a>. <\/p>\n<pre>\nBOOL\nOnCreate(HWND hwnd, LPCREATESTRUCT lpcs)\n{\n g_hwndChild = CreateWindow(TRACKBAR_CLASS, TEXT(\"\"),\n    WS_CHILD | WS_VISIBLE <font COLOR=\"blue\">| TBS_NOTIFYBEFOREMOVE<\/font>,\n   0, 0, 100, 100,\n    hwnd, (HMENU)100, g_hinst, 0);\n\n  SendMessage(g_hwndChild, TBM_SETLINESIZE, 0, 5);\n  SendMessage(g_hwndChild, TBM_SETPAGESIZE, 0, 20);<\/font>\n\n  return TRUE;\n}\n<\/pre>\n<p>The <code>TBS_<\/code><code>NOTIFY&shy;BEFORE&shy;MOVE<\/code> style enables the <code>TRBN_<\/code><code>THUMB&shy;POS&shy;CHANGING<\/code> notification, which we will take advantage of below. <\/p>\n<pre>\n<font COLOR=\"blue\">LRESULT OnNotify(HWND hwnd, int idCtl, NMHDR* pnm)\n{\n if (pnm-&gt;hwndFrom == g_hwndChild &amp;&amp;\n     pnm-&gt;code == TRBN_THUMBPOSCHANGING &amp;&amp;\n     GetKeyState(VK_CONTROL) &lt; 0) {\n  auto ptpc = (NMTRBTHUMBPOSCHANGING*)pnm;\n  switch (ptpc-&gt;nReason) {\n  case TB_LINEUP:\n  case TB_LINEDOWN:\n    int pos = (int)SendMessage(pnm-&gt;hwndFrom, TBM_GETPOS, 0, 0);\n    pos += (ptpc-&gt;nReason == TB_LINEUP) ? -1 : +1;\n    SendMessage(pnm-&gt;hwndFrom, TBM_SETPOS, TRUE, pos);\n    return TRUE; \/\/ we moved the thumb, so the control doesn't have to\n  }\n }\n return 0;\n}\n    HANDLE_MSG(hwnd, WM_NOTIFY, OnNotify);<\/font>\n<\/pre>\n<p>The <code>TRBN_<\/code><code>THUMB&shy;POS&shy;CHANGING<\/code> notification is sent before the trackbar moves the thumb. and the <code>nReason<\/code> tells you why the trackbar wants to move the thumb.&sup1; If the <kbd>Ctrl<\/kbd> key is held down, and the reason is either a line-up or a line-down, then we fetch the current trackbar position, adjust it by one unit, and set that as the new trackbar position. We then return <code>TRUE<\/code> to tell the trackbar that it shouldn&#8217;t move the trackbar thumb (because we moved it). <\/p>\n<p>(Don&#8217;t forget that if this is happening in a dialog box, you need to use <code>DWLP_<\/code><code>MSG&shy;RESULT<\/code> to make the dialog box return a nonzero value from its window procedure.) <\/p>\n<p>Responding to the notification leaves the trackbar to deal with recognizing the keyboard keys and taking the various trackbar configuration settings into account in order to convert them to scroll actions. We then detect the <i>change position by one line<\/i> action and apply our special thumb motion if the <kbd>Ctrl<\/kbd> key is held down, leaving the trackbar to manage the keyboard cues and other accessibility states. <\/p>\n<p>&sup1; There&#8217;s also a <code>dwPos<\/code> that tells you where the thumb is moving <i>to<\/i>, but we are more interested in where the thumb is moving <i>from<\/i>. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Intercepting the thumb motion.<\/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-100045","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Intercepting the thumb motion.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/100045","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=100045"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/100045\/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=100045"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=100045"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=100045"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}