{"id":37733,"date":"2004-09-27T07:00:00","date_gmt":"2004-09-27T07:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2004\/09\/27\/how-to-host-an-icontextmenu-part-5-handling-menu-messages\/"},"modified":"2004-09-27T07:00:00","modified_gmt":"2004-09-27T07:00:00","slug":"how-to-host-an-icontextmenu-part-5-handling-menu-messages","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20040927-00\/?p=37733","title":{"rendered":"How to host an IContextMenu, part 5 &#8211; Handling menu messages"},"content":{"rendered":"<p><P>\nOne bug that was called out immediately in\n<A href=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2004\/09\/22\/232836.aspx\">\nour first attempt at displaying the context menu to the user<\/A>\nis that the Open With and Send To submenus don&#8217;t work.\n<\/P>\n<P>\nThe reason for this is that these submenus are delay-generated\n(which explains why they don&#8217;t contain anything interesting when\nyou expand them) and owner-drawn (which you can&#8217;t notice yet\nbecause of the first problem, but trust me, they are).\n<\/P>\n<P>\nThis is where the\n<A HREF=\"http:\/\/msdn.microsoft.com\/library\/en-us\/shellcc\/platform\/shell\/reference\/ifaces\/icontextmenu2\/handlemenumsg.asp\">\nIContextMenu2::HandleMenuMsg<\/A> and\n<A HREF=\"http:\/\/msdn.microsoft.com\/library\/en-us\/shellcc\/platform\/shell\/reference\/ifaces\/icontextmenu3\/handlemenumsg2.asp\">\nIContextMenu3::HandleMenuMsg2<\/A> methods\nare used.\n<\/P>\n<P>\nHistorical note:\nIContextMenu2::HandleMenuMessage\nis on its own interface rather than being merged with\nthe base interface\n<A HREF=\"http:\/\/msdn.microsoft.com\/library\/en-us\/shellcc\/platform\/shell\/reference\/ifaces\/icontextmenu\/icontextmenu.asp\">\nIContextMenu<\/A>\nbecause it was added late in Windows&nbsp;95 development,\nso it was considered safer to add a derived interface than\nto make everybody who had been writing Windows&nbsp;95 shell\nextensions go back and rewrite their code.\nIContextMenu3::HandleMenuMessage2\nwas added in Internet Explorer&nbsp;4 (I think)\nwhen it became clear that the ability for a context menu extension\nto override the default message return value was necessary\nin order to support keyboard accessibility in owner-drawn context menus.\n<\/P>\n<P>\nIn a &#8220;real program&#8221;, these two variables would be class members\nassociated with the window, but this is just a sample program,\nso they are globals.\n<STRONG>When you write your own programs, don&#8217;t use global variables\nhere<\/STRONG> because they will result in mass mayhem once you get\na second window, since both of them will try to talk to the interface\neven though only the window displaying the context menu should be\ndoing so.\n<\/P>\n<PRE>\n<FONT COLOR=\"blue\">IContextMenu2 *g_pcm2;\nIContextMenu3 *g_pcm3;<\/FONT>\n<\/PRE>\n<P>\nThese two new variables track the IContextMenu2 and IContextMenu3\ninterfaces of the active tracked popup menu.  We need to initialize\nand uninitalize them around our call to TrackPopupMenuEx:\n<\/P>\n<PRE>\n      <FONT COLOR=\"blue\">pcm-&gt;QueryInterface(IID_IContextMenu2, (void**)&amp;g_pcm2);\n      pcm-&gt;QueryInterface(IID_IContextMenu3, (void**)&amp;g_pcm3);<\/FONT>\n      int iCmd = TrackPopupMenuEx(hmenu, TPM_RETURNCMD, pt.x, pt.y, hwnd, NULL);\n      <FONT COLOR=\"blue\">if (g_pcm2) {\n        g_pcm2-&gt;Release();\n        g_pcm2 = NULL;\n      }\n      if (g_pcm3) {\n        g_pcm3-&gt;Release();\n        g_pcm3 = NULL;\n      }<\/FONT>\n<\/PRE>\n<P>\nAnd finally we need to invoke the HandleMenuMessage\/HandleMenuMessage\nmethods in the window procedure:\n<\/P>\n<PRE>\nLRESULT CALLBACK\nWndProc(HWND hwnd, UINT uiMsg, WPARAM wParam, LPARAM lParam)\n{\n    <FONT COLOR=\"blue\">if (g_pcm3) {\n        LRESULT lres;\n        if (SUCCEEDED(g_pcm3-&gt;HandleMenuMsg2(uiMsg, wParam, lParam, &amp;lres))) {\n          return lres;\n        }\n    } else if (g_pcm2) {\n        if (SUCCEEDED(g_pcm2-&gt;HandleMenuMsg(uiMsg, wParam, lParam))) {\n          return 0;\n        }\n    }<\/FONT><\/p>\n<p>    switch (uiMsg) {\n    &#8230;.\n<\/PRE>\n<P>\nIn the window procedure, we ask the context menu whether it\nwishes to handle the menu message.  If so, then we stop and\nreturn the desired value (if HandleMenuMsg2) or just zero\n(if HandleMenuMsg).\n<\/P>\n<P>\nWith these changes, run the scratch program again and observe\nthat the Open With and Send To submenus now operate as expected.\n<\/P>\n<P>\n<A href=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2004\/09\/28\/235242.aspx\">\nNext time: Getting menu help text<\/A>.\n<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>One bug that was called out immediately in our first attempt at displaying the context menu to the user is that the Open With and Send To submenus don&#8217;t work. The reason for this is that these submenus are delay-generated (which explains why they don&#8217;t contain anything interesting when you expand them) and owner-drawn (which [&hellip;]<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-37733","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>One bug that was called out immediately in our first attempt at displaying the context menu to the user is that the Open With and Send To submenus don&#8217;t work. The reason for this is that these submenus are delay-generated (which explains why they don&#8217;t contain anything interesting when you expand them) and owner-drawn (which [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/37733","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=37733"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/37733\/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=37733"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=37733"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=37733"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}