{"id":21603,"date":"2008-07-16T10:00:00","date_gmt":"2008-07-16T10:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2008\/07\/16\/the-evolution-of-menu-templates-32-bit-extended-menus\/"},"modified":"2008-07-16T10:00:00","modified_gmt":"2008-07-16T10:00:00","slug":"the-evolution-of-menu-templates-32-bit-extended-menus","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20080716-00\/?p=21603","title":{"rendered":"The evolution of menu templates: 32-bit extended menus"},"content":{"rendered":"<p><P>\nAt last we reach the 32-bit extended menu template.\nIntroduced in Windows&nbsp;95, this remains the\nmost advanced menu template format through Windows&nbsp;Vista.\nAs you might expect, the 32-bit extended menu template is\njust a 32-bit version of the\n<A HREF=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2008\/07\/15\/8732375.aspx\">\n16-bit extended menu template<\/A>,\nso if you&#8217;ve been following along, you should find no real\nsurprises here;\nall the pieces have been telegraphed far in advance.\n<\/P>\n<P>\nThe header remains the same:\n<\/P>\n<PRE>\nstruct MENUHEADER32 {\n WORD wVersion;\n WORD cbHeaderSize;\n BYTE rgbExtra[cbHeaderSize-4];\n};\n<\/PRE>\n<P>\nThe differences here from the 32-bit classic menu template header\nare analogous to the changes between the 16-bit classic menu template\nand the 16-bit extended menu template.\nThe <CODE>wVersion<\/CODE> is set to one for extended templates,\nand the <CODE>cbHeaderSize<\/CODE> includes the <CODE>wVersion<\/CODE>\nand <CODE>cbHeaderSize<\/CODE> fields themselves,\nso the number of extra bytes is four less than the value specified\nin <CODE>cbHeaderSize<\/CODE>.\nThere is one additional constraint:\nThe <CODE>cbHeaderSize<\/CODE> must be a multiple of four\nbecause extended menu item templates must be aligned on <CODE>DWORD<\/CODE>\nboundaries.\nBut as with 32-bit classic templates, the\n<CODE>cbHeaderSize<\/CODE> must be four in order to avoid a bug\nin the Windows&nbsp;95 family of operating systems.\n<\/P>\n<P>\nAfter the header comes the menu itself,\nand like the 16-bit extended menu template,\nthere is a prefix structure that comes before the items\nand which serves the same purpose as in the 16-bit extended menu template:\n<\/P>\n<PRE>\nstruct MENUPREFIX32 {\n DWORD dwContextHelpID;\n};\n<\/PRE>\n<P>\nThe list of menu items is basically the same as the 16-bit version,\njust with some expanded fields.\n<\/P>\n<PRE>\nstruct MENUITEMEX32 {\n DWORD dwType;\n DWORD dwState;\n DWORD dwID;\n WORD  wFlags;\n WCHAR szText[]; \/\/ null terminated UNICODE string\n};\n<\/PRE>\n<P>\nAs we saw before when we studied the 16-bit extended menu template,\nthe big difference between classic and extended menu items\nis that classic menu items were designed for the\n<CODE>InsertMenu<\/CODE> function,\nwhereas extended menu items were designed for the\n<CODE>InsertMenuItem<\/CODE> function.\nThe <CODE>dwType<\/CODE>, <CODE>dwState<\/CODE>, and\n<CODE>dwID<\/CODE> members correspond to\nthe <CODE>fType<\/CODE>, <CODE>fState<\/CODE>, and\n<CODE>wID<\/CODE>\nmembers of the <CODE>MENUITEMINFO<\/CODE> structure,\nand the the <CODE>szText<\/CODE> goes into the\n<CODE>dwItemData<\/CODE> if the item requires a string.\n<\/P>\n<P>\nOne additional quirk of 32-bit extended menu item templates\nwhich the 16-bit version does not have is that 32-bit\nextended menu item templates must begin on a 32-bit boundary;\ntherefore, you must insert a <CODE>WORD<\/CODE> of padding\nafter the menu text if the text is an odd number of characters\nlong.\n(Fourteen bytes of the fixed-length part of the <CODE>MENUITEMEX32<\/CODE>\nplus an odd number of <CODE>WCHAR<\/CODE>s\nplus the null terminator <CODE>WCHAR<\/CODE> leaves a value that is\n2&nbsp;mod&nbsp;4; therefore, you need an additional <CODE>WORD<\/CODE>\nto return to a <CODE>DWORD<\/CODE> boundary.)\n<\/P>\n<P>\nThe <CODE>wFlags<\/CODE> field has the same values as in the\n16-bit extended menu item templates; the high byte is always zero.\nAnd, as before, if the bottom bit is set, then the menu item describes\na pop-up submenu, which is inserted directly after\nthe extended menu item template.\n<\/P>\n<P>\nThat&#8217;s all there is to it.\nLet&#8217;s see how our example menu resource looks when converted\nto a 32-bit extended menu template:\n<\/P>\n<PRE>\n1 MENUEX 1000\nBEGIN\n  POPUP &#8220;&amp;File&#8221;, 200,,, 1001\n  BEGIN\n    MENUITEM &#8220;&amp;Open\\tCtrl+O&#8221;, 100\n    MENUITEM &#8220;&#8221;, -1, MFT_SEPARATOR\n    MENUITEM &#8220;&amp;Exit\\tAlt+X&#8221;,  101\n  END\n  POPUP &#8220;&amp;View&#8221;, 201,,, 1002\n  BEGIN\n    MENUITEM &#8220;&amp;Status Bar&#8221;, 102,, MFS_CHECKED\n  END\nEND\n<\/PRE>\n<P>\nFirst comes the header, whose contents are fixed:\n<\/P>\n<PRE>\n0000  01 00          \/\/ wVersion = 1\n0002  04 00          \/\/ cbHeaderSize = 4\n<\/PRE>\n<P>\nBefore the list of extended menu item templates, we have the\ncontext help ID:\n<\/P>\n<PRE>\n0004  E8 03 00 00    \/\/ dwContextHelpID = 1000\n<\/PRE>\n<P>\nSince our first menu item is a pop-up submenu,\nthe <CODE>wFlags<\/CODE> will have the bottom bit set:\n<PRE>\n0008  00 00 00 00    \/\/ dwType = MFT_STRING\n000C  00 00 00 00    \/\/ dwState = 0\n0010  C8 00 00 00    \/\/ wID = 200\n0014  01 00          \/\/ wFlags = &#8220;pop-up submenu&#8221;\n0016  26 00 46 00 69 00 6C 00 65 00 00 00\n                     \/\/ &#8220;&amp;File&#8221; + null terminator\n0022  00 00          \/\/ Padding to restore alignment\n<\/PRE>\n<P>\nNotice the two bytes of padding so that we return to\n<CODE>DWORD<\/CODE> alignment.\n<\/P>\n<P>\nThe <CODE>wFlags<\/CODE> promised a pop-up submenu, so here it is.\n<\/P>\n<PRE>\n0024  E9 03 00 00    \/\/ dwContextHelpID = 1001<\/p>\n<p>\/\/ First item\n0028  00 00 00 00    \/\/ dwType = MFT_STRING\n002C  00 00 00 00    \/\/ dwState = 0\n0030  64 00 00 00    \/\/ dwID = 100\n0034  00 00          \/\/ wFlags = 0\n0036  26 00 4F 00 70 00 65 00 6E 00 09 00\n      43 00 74 00 72 00 6C 00 2B 00 4F 00 00 00\n                     \/\/ &#8220;&amp;Open\\tCtrl+O&#8221; + null terminator<\/p>\n<p>\/\/ Second item\n0050  00 08 00 00     \/\/ dwType = MFT_SEPARATOR\n0054  00 00 00 00     \/\/ dwState = 0\n0058  FF FF FF FF     \/\/ dwID = -1\n005C  00 00           \/\/ wFlags = 0\n005E  00 00           \/\/ &#8220;&#8221;<\/p>\n<p>\/\/ Third (final) item\n0060  00 00 00 00     \/\/ dwType = MFT_STRING\n0064  00 00 00 00     \/\/ dwState = 0\n0068  65 00 00 00     \/\/ dwID = 101\n006C  80 00           \/\/ wFlags = &#8220;this is the last menu item&#8221;\n0070  26 00 45 00 78 00 69 00 74 00 09 00\n      41 00 6C 00 74 00 2B 00 58 00 00 00\n                      \/\/ &#8220;&amp;Exit\\tAlt+X&#8221; + null terminator\n0086  00 00          \/\/ Padding to restore alignment\n<\/PRE>\n<P>\nWhen we see the &#8220;end&#8221; marker, we pop one level back to the main menu.\n<\/P>\n<PRE>\n0088  00 00 00 00     \/\/ dwType = MFT_STRING\n008C  00 00 00 00     \/\/ dwState = 0\n0090  C9 00 00 00     \/\/ dwID = 201\n0094  81 00           \/\/ wFlags = &#8220;pop-up submenu&#8221; |\n                      \/\/          &#8220;this is the last menu item&#8221;\n0096  26 00 56 00 69 00 65 00 77 00 00 00\n                      \/\/ &#8220;&amp;View&#8221; + null terminator\n00A2  00 00          \/\/ Padding to restore alignment\n<\/PRE>\n<P>\nThe set bottom bit in the <CODE>wFlags<\/CODE> indicates\nthat another pop-up submenu is coming,\nand the &#8220;end&#8221; marker means that once the submenu is finished,\nwe are done.\n<\/P>\n<PRE>\n00A4  EA 03 00 00    \/\/ dwContextHelpID = 1002<\/p>\n<p>00A8  00 00 00 00    \/\/ dwType = MFT_STRING\n00AC  08 00 00 00    \/\/ dwState = MFS_CHECKED\n00B0  66 00 00 00    \/\/ dwID = 102\n00B4  80 00          \/\/ wFlags = &#8220;this is the last menu item&#8221;\n00B6  26 00 53 00 74 00 61 00 74 00 75 00\n      73 00 20 00 42 00 61 00 72 00 00 00\n                     \/\/ &#8220;&amp;Status Bar&#8221; + null terminator\n00CE  00 00          \/\/ Padding to restore alignment\n<\/PRE>\n<P>\nSince the pop-up submenu has only one item, the first item is also\nthe last.\n<\/P>\n<P>\nThat&#8217;s it for the evolution of menu templates,\nstarting from a series of calls to the ANSI version of\n<CODE>InsertMenu<\/CODE>\nto a series of calls to the Unicode version of\n<CODE>InsertMenuItem<\/CODE>.\nMenu templates get much less attention than dialog templates,\nbut if you wanted to know how they work, well, there you have it.\n<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>At last we reach the 32-bit extended menu template. Introduced in Windows&nbsp;95, this remains the most advanced menu template format through Windows&nbsp;Vista. As you might expect, the 32-bit extended menu template is just a 32-bit version of the 16-bit extended menu template, so if you&#8217;ve been following along, you should find no real surprises here; [&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":[2],"class_list":["post-21603","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-history"],"acf":[],"blog_post_summary":"<p>At last we reach the 32-bit extended menu template. Introduced in Windows&nbsp;95, this remains the most advanced menu template format through Windows&nbsp;Vista. As you might expect, the 32-bit extended menu template is just a 32-bit version of the 16-bit extended menu template, so if you&#8217;ve been following along, you should find no real surprises here; [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/21603","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=21603"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/21603\/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=21603"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=21603"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=21603"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}