{"id":97785,"date":"2018-01-12T07:00:00","date_gmt":"2018-01-12T22:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/?p=97785"},"modified":"2019-03-13T01:02:30","modified_gmt":"2019-03-13T08:02:30","slug":"20180112-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20180112-00\/?p=97785","title":{"rendered":"Why don&#8217;t context menus respect the UI state for keyboard accelerators?"},"content":{"rendered":"<p>The <code>WM_<\/code><code>CHANGE&shy;UI&shy;STATE<\/code> message lets you manipulate the UI state of a window, which controls whether keyboard accelerators and other UI affordances are shown. Let&#8217;s use it to try to control the mnemonics of a window. Start with <a HREF=\"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/20030723-00\/?p=43073\">the scratch program<\/a> and make these changes: <\/p>\n<pre>\nBOOL\nOnCreate(HWND hwnd, LPCREATESTRUCT lpcs)\n{\n  <font COLOR=\"blue\">CreateWindow(TEXT(\"button\"), TEXT(\"&amp;Button!\"),\n    WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX,\n    0, 0, 200, 50, hwnd, (HMENU)100, g_hinst, 0);<\/font>\n  return TRUE;\n}\n\n<font COLOR=\"blue\">void OnContextMenu(HWND hwnd, HWND hwndFrom, int x, int y)\n{\n  auto hmenu = GetSystemMenu(hwnd, false);\n  TrackPopupMenu(hmenu, TPM_RIGHTBUTTON, x, y, 0, hwnd, nullptr);\n}\n\nvoid OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)\n{\n  if (id == 100 &amp;&amp; codeNotify == BN_CLICKED) {\n    if (SendMessage(hwndCtl, BM_GETCHECK, 0, 0)) {\n      SendMessage(hwnd, WM_CHANGEUISTATE,\n                  MAKELONG(UIS_CLEAR, UISF_HIDEACCEL), 0);\n    } else {\n      SendMessage(hwnd, WM_CHANGEUISTATE,\n                  MAKELONG(UIS_SET, UISF_HIDEACCEL), 0);\n    }\n  }\n}<\/font>\n\n\/\/ Add to WndProc\n    <font COLOR=\"blue\">HANDLE_MSG(hwnd, WM_COMMAND, OnCommand);\n    <a HREF=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/\">HANDLE_MSG(hwnd, WM_CONTEXTMENU<\/a>, OnContextMenu);<\/font>\n<\/pre>\n<p>This program lets you toggle the checkbox to turn keyboard cues on and off. The checkbox itself has an accelerator so you can verify the state. if you right-click anywhere or hit <kbd>Shift<\/kbd>+<kbd>F10<\/kbd>, the system menu appears as a context menu. (Note that this program doesn&#8217;t try to <a HREF=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/\">position the context menu anywhere interesting when invoked from the keyboard<\/a>.) <\/p>\n<p>Enable keyboard cues with the checkbox, and then right-click. Or disable keyboard cues and hit <kbd>Shift<\/kbd>+<kbd>F10<\/kbd>, The menu shows up and ignores your keyboard cues settings, instead taking its keyboard cue state based on whether you used the mouse or keyboard to display the menu. Same thing happens if you open the system menu by right-clicking the title bar or hitting <kbd>Alt<\/kbd>+<kbd>Space<\/kbd>. <\/p>\n<p>What&#8217;s going on? Why isn&#8217;t the menu picking up the UI cue state? <\/p>\n<p>Because the menu is in a separate top-level window tree, and keyboard cues apply to a top-level window tree. <\/p>\n<p>Menus, like dialog boxes, initialize their UI state based on the last input event.&sup1; So they will show keyboard cues if you invoked the menu from the keyboard, and won&#8217;t show them if you invoked the menu from the mouse. <\/p>\n<p>&sup1; The user&#8217;s keyboard cues preferences override this logic. If the preferences indicate that keyboard cues should always be shown, then they are always shown. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Well, technically, they&#8217;re a separate window.<\/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-97785","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Well, technically, they&#8217;re a separate window.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/97785","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=97785"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/97785\/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=97785"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=97785"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=97785"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}