{"id":35943,"date":"2005-04-08T07:00:41","date_gmt":"2005-04-08T14:00:41","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2005\/04\/08\/the-dialog-manager-part-9-custom-accelerators-in-dialog-boxes\/"},"modified":"2020-02-08T10:26:02","modified_gmt":"2020-02-08T18:26:02","slug":"20050408-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20050408-41\/?p=35943","title":{"rendered":"The dialog manager, part 9: Custom accelerators in dialog boxes"},"content":{"rendered":"<p>Along lines similar to <a href=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2005\/04\/07\/406012.aspx\"> last time<\/a>, you can also add custom accelerators to your dialog box. (In a sense, this is a generalization of custom navigation, since you can make your navigation keys be accelerators.)<\/p>\n<p>So let&#8217;s use accelerators to navigate instead of picking off the keys manually. Our accelerator table might look like this:<\/p>\n<pre>IDA_PROPSHEET ACCELERATORS\r\nBEGIN\r\n    VK_TAB      ,IDC_NEXTPAGE       ,VIRTKEY,CONTROL\r\n    VK_TAB      ,IDC_PREVPAGE       ,VIRTKEY,CONTROL,SHIFT\r\nEND\r\n<\/pre>\n<p>Here you can see my comma placement convention for tables. I like to put commas at the far end of the field rather than jamming it up against the last word in the column. Doing this makes cut\/paste a lot easier, since you can cut a column and paste it somewhere else without having to go back and twiddle all the commas.<\/p>\n<p>Assuming you&#8217;ve loaded this accelerator table into the variable &#8220;hacc&#8221;, you can use that table in your custom dialog loop:<\/p>\n<pre>while (&lt;dialog still active&gt; &amp;&amp;\r\n       GetMessage(&amp;msg, NULL, 0, 0, 0)) {\r\n <span style=\"color: blue;\">if (!TranslateAccelerator(hdlg, hacc, &amp;msg) &amp;&amp;<\/span>\r\n     !IsDialogMessage(hdlg, &amp;msg)) {\r\n  TranslateMessage(&amp;msg);\r\n  DispatchMessage(&amp;msg);\r\n }\r\n}\r\n<\/pre>\n<p><a href=\"http:\/\/msdn.microsoft.com\/library\/en-us\/winui\/WinUI\/WindowsUserInterface\/UserInput\/KeyboardAccelerators\/KeyboardAcceleratorReference\/KeyboardAcceleratorFunctions\/TranslateAccelerator.asp\"> The <code>TranslateAccelerator<\/code> function<\/a> checks if the message matches any entries in the accelerator table. If so, then it posts a <code>WM_COMMAND<\/code> message to the window passed as its first parameter. In our case, we pass the dialog box handle. Not shown above is the <code>WM_COMMAND<\/code> handler in the dialog box that responds to <code>IDC_NEXTPAGE<\/code> and <code>IDC_PREVPAGE<\/code> by performing a navigation.<\/p>\n<p>The same as last time, if you think there might be modeless dialogs owned by this message loop, you will have to do filtering so that you don&#8217;t pick off somebody else&#8217;s navigation keys.<\/p>\n<pre>while (&lt;dialog still active&gt; &amp;&amp;\r\n       GetMessage(&amp;msg, NULL, 0, 0, 0)) {\r\n if (<span style=\"color: blue;\">!((hdlg == msg.hwnd || IsChild(hdlg, msg.hwnd)) &amp;&amp;<\/span>\r\n       !TranslateAccelerator(hdlg, hacc, &amp;msg)<span style=\"color: blue;\">)<\/span> &amp;&amp;\r\n     !IsDialogMessage(hdlg, &amp;msg)) {\r\n  TranslateMessage(&amp;msg);\r\n  DispatchMessage(&amp;msg);\r\n }\r\n}\r\n<\/pre>\n<p>Okay, I think that&#8217;s enough of dialog boxes for now.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Injecting accelerator keys into the dialog modal loop.        <\/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-35943","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Injecting accelerator keys into the dialog modal loop.        <\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/35943","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=35943"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/35943\/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=35943"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=35943"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=35943"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}