static auto const menu =
EMPTY_MENUITEMTEMPLATEHEADER
NEXT_POPUP(L"first")
NEXT_STRING(0123, L"1st sub 0")
NEXT_STRING(0124, L"1st sub 1")
NEXT_SEPERATOR
LAST_POPUP(L"1st sub 2")
LAST_STRING(0125, L"sub sub 1")
NEXT_POPUP(L"second")
NEXT_STRING(0126, L"2nd sub 0")
LAST_STRING(0127, L"2nd sub 1")
LAST_STRING(0128, L"last")
;
SetMenu(hwnd, LoadMenuIndirectW((MENUTEMPLATEW*)menu));
erzeugt dieses Menü: Die dazu nötigen Präprozessordefinitionen:
Code: Alles auswählen
#define MAKE_UTF16_LITERAL(x) L###x
// Expresses an empty 'MENUITEMTEMPLATEHEADER' instance as a UTF-16 literal.
#define EMPTY_MENUITEMTEMPLATEHEADER L"\x0000\x0000"
// Expresses a string entry of the given hexadecimal ID (without the '0x' prefix) and the given name (with the 'L' prefix) as a
// UTF-16 literal.
#define NEXT_STRING(hexID_noPefix, title_UTF16Prefixd) L"\x0000" MAKE_UTF16_LITERAL(\x##hexID_noPefix) title_UTF16Prefixd L"\0"
#define LAST_STRING(hexID_noPefix, title_UTF16Prefixd) L"\x0080" MAKE_UTF16_LITERAL(\x##hexID_noPefix) title_UTF16Prefixd L"\0"
// Expresses a popup entry of the given name (with the 'L' prefix!) as a UTF-16 literal.
//
// "The other type of menu item template is the pop-up submenu.
//
// struct POPUPMENUITEM16 {
// WORD wFlags; // menu item flags (MFT_*, MFS_*)
// CHAR szText[]; // null terminated ANSI string
// };
//
// The pop-up item template doesn't have an ID, the MF_POPUP flag must be set in the flags (naturally), the MFS_HILITE
// flag must not be set, and it is immediately followed by... another menu resource, minus the resource header, which
// describes the pop-up submenu itself. (This is the recursive part.)"
// (http://blogs.msdn.com/b/oldnewthing/archive/2008/07/09/8711897.aspx)
#define NEXT_POPUP(title_UTF16Prefixd) L"\x0010" title_UTF16Prefixd L"\0"
#define LAST_POPUP(title_UTF16Prefixd) L"\x0090" title_UTF16Prefixd L"\0"
// Expresses a seperator as a UTF-16 literal.
//
// "The next item of the pop-up menu is a separator. If you have been following the rules strictly, you would generate the
// separator like this:
//
// 001D 00 08 // wFlags = MFT_SEPARATOR
// 001F 00 00 // wID = 0
// 0021 00 // ""
//
// However, it turns out that there is an alternate form for separators, namely to pass all zeroes:
//
// 001D 00 00 // wFlags = 0
// 001F 00 00 // wID = 0
// 0021 00 // ""
//
// The existence of this alternate form is actually an artifact of history, which we'll look at next time. But for now,
// just realize that you can express a separator in two different ways, either the official way with MFT_SEPARATOR or the
// alternate way with wFlags = 0. Either works just fine."
// (http://blogs.msdn.com/b/oldnewthing/archive/2008/07/09/8711897.aspx)
#define NEXT_SEPERATOR L"\x0000\x0000\x0000"
#define LAST_SEPERATOR L"\x0080\x0000\x0000"
Nur mit Visual C++ 2012 getestet. Auf einigen Compilern wollt ihr vielleicht C++11s u""-Präfix statt L"" benutzen.
Viel Spaß!