LoadMenuIndirect

本文介绍了一种使用特定的数据结构和函数创建菜单栏的方法。通过定义MENUITEMTEMPLATEHEADER和MENUITEMTEMPLATE结构体,配合menu_template数组,可以实现菜单项的创建与布局。使用LoadMenuIndirect函数加载菜单模板并创建菜单。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


// 菜单栏创建

HMENU LoadMenuIndirect(        
 CONST MENUTEMPLATE *lpMenuTemplate
);


typedef struct {
    WORD versionNumber;
    WORD offset;
} MENUITEMTEMPLATEHEADER, *PMENUITEMTEMPLATEHEADER;


typedef struct {
    WORD mtOption;
    WORD mtID;
    WCHAR mtString[1];
} MENUITEMTEMPLATE, *PMENUITEMTEMPLATE;


 const WORD menu_template[] =
 {
  0, // versionNumber   version number; must be zero
  0, // offset          offset first MENUITEMTEMPLATE structure
  //// MENUITEMTEMPLATE ////

  // 第一个菜单, 结尾需要加 MF_HILITE
  MF_POPUP | MF_STRING, L'F', L'i', L'l', L'e', L'(', L'&', L'F', L')', 0,
  MF_INSERT | MF_STRING, IDM_OPEN, L'&', L'O', L'p', L'e', L'n', 0,
  MF_INSERT | MF_STRING, IDM_SAVE, L'&', L'S', L'a', L'v', L'e', 0,
  MF_INSERT | MF_STRING, IDM_SAVE, L'&', L'S', L'a', L'v', L'e', 0,
  MF_INSERT | MF_STRING, IDM_SAVE, L'&', L'S', L'a', L'v', L'e', 0,
  MF_SEPARATOR, 0, 0,                                              
  MF_INSERT | MF_STRING | MF_HILITE, IDM_QUIT, L'終', L'了', L'(', L'&', L'Q', L')', 0, 
 
  
  // 第二个菜单, 结尾需要加上MF_HILITE
  MF_POPUP | MF_STRING , L'表', L'示', L'(', L'&', L'V', L')', 0,
  MF_INSERT | MF_STRING, IDM_SAVE, L'测', L'试', 0,
  MF_SEPARATOR, 0, 0,                         
  MF_INSERT | MF_STRING | MF_HILITE, IDM_FSCREEN,   L'全', L'画', L'面', L'表', L'示', 0,      


  // 开始和结尾都加上MF_HILITE, 标识最后一个菜单
  MF_POPUP | MF_STRING | MF_HILITE, L'表', L'示', L'(', L'&', L'V', L')', 0,               
  MF_INSERT | MF_STRING | MF_HILITE, IDM_FSCREEN,   L'全', L'画', L'面', L'表', L'示', 0,      
   
 }; 
 
 
 HMENU hMenu = ::LoadMenuIndirect(menu_template);

 

 

#include <windows.h> // 菜单项 ID(自定义) #define IDM_FILE_NEW 1001 #define IDM_FILE_OPEN 1002 #define IDM_FILE_SAVE 1003 #define IDM_FILE_EXIT 1004 #define IDM_HELP_ABOUT 1005 #define ID_VIEW_BIG 1006 #define ID_VIEW_SMALL 1007 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); HINSTANCE g_hInstance; int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { g_hInstance = hInstance; TCHAR CLASS_NAME[] = L"MyWindowClass"; WNDCLASS wc = { 0 }; wc.lpfnWndProc = WndProc; wc.hInstance = hInstance; wc.lpszClassName = CLASS_NAME; wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); if (!RegisterClass(&wc)) { MessageBox(NULL, L"注册窗口类失败!", L"错误", MB_OK | MB_ICONERROR); return 0; } HWND hWnd = CreateWindow( CLASS_NAME, L"我的应用程序", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 400, 300, NULL, NULL, // ✅ 绑定菜单资源 hInstance, NULL ); if (!hWnd) { MessageBox(NULL, L"创建窗口失败!", L"错误", MB_OK | MB_ICONERROR); return 0; } { // 菜单项 ID(自定义) #define IDM_FILE_NEW 1001 #define IDM_FILE_OPEN 1002 #define IDM_FILE_SAVE 1003 #define IDM_FILE_EXIT 1004 #define IDM_HELP_ABOUT 1005 // ✅ 使用 CreateMenu 和 AppendMenu 动态创建菜单 HMENU hMainMenu = CreateMenu(); // 创建主菜单(整个菜单栏) HMENU hFileMenu = CreateMenu(); // 创建“文件”下拉菜单 HMENU hHelpMenu = CreateMenu(); // 创建“帮助”下拉菜单 // 向“文件”菜单添加项 AppendMenu(hFileMenu, MF_STRING, IDM_FILE_NEW, L"新建(&N)"); AppendMenu(hFileMenu, MF_STRING, IDM_FILE_OPEN, L"打开(&O)"); AppendMenu(hFileMenu, MF_STRING, IDM_FILE_SAVE, L"保存(&S)"); AppendMenu(hFileMenu, MF_SEPARATOR, 0, NULL); // 分隔符 AppendMenu(hFileMenu, MF_STRING, IDM_FILE_EXIT, L"退出(&X)"); // 向“帮助”菜单添加项 AppendMenu(hHelpMenu, MF_STRING, IDM_HELP_ABOUT, L"关于(&A)"); // 将下拉菜单附加到主菜单栏 AppendMenu(hMainMenu, MF_POPUP, (UINT_PTR)hFileMenu, L"文件(&F)"); AppendMenu(hMainMenu, MF_POPUP, (UINT_PTR)hHelpMenu, L"帮助(&H)"); //HMENU hMenuPopup = CreateMenu(); // 弹出菜单句柄 //AppendMenu(hMenuPopup, MF_STRING, ID_VIEW_BIG, TEXT("大图标")); //AppendMenu(hMenuPopup, MF_STRING, ID_VIEW_SMALL, TEXT("小图标")); //AppendMenu(hMainMenu, MF_STRING | MF_POPUP | MF_RIGHTJUSTIFY, (UINT_PTR)hMenuPopup, TEXT("视图")); // 将主菜单绑定到窗口 SetMenu(hWnd, hMainMenu); } ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return (int)msg.wParam; } LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { HMENU hMenu; WORD arrMenuTemplate[] = { // MENUITEMTEMPLATEHEADER 结构 0, 0, // 多个 MENUITEMTEMPLATE 结构 MF_STRING | MF_POPUP, L'编', L'辑', 0, MF_STRING, 40030, L'剪', L'切', L'(', L'&', L'T', L')', L'\t', L'C', L't', L'r', L'l', L'+', L'X', 0, MF_STRING, 40031, L'复', L'制', L'(', L'&', L'C', L')', L'\t', L'C', L't', L'r', L'l', L'+', L'C', 0, MF_STRING, 40032, L'粘', L'贴', L'(', L'&', L'P', L')', L'\t', L'C', L't', L'r', L'l', L'+', L'V', 0, MF_SEPARATOR, 0, 0, MF_STRING, 40033, L'红', L'色', L'(', L'&', L'R', L')', 0, MF_STRING, 40034, L'绿', L'色', L'(', L'&', L'G', L')', 0, MF_STRING | MF_HILITE, 40035, L'蓝', L'色', L'(', L'&', L'B', L')', 0, // 第 2 个弹出菜单,最后一个子菜单项需要 MF_HILITE 标志 MF_STRING | MF_POPUP, L'视', L'图', 0, MF_STRING, 40036, L'大', L'图', L'标', L'(', L'&', L'D', L')', 0, MF_STRING | MF_HILITE, 40037, L'小', L'图', L'标', L'(', L'&', L'S', L')', 0, // 第 3 个弹出菜单,开始和结束都需要 MF_HILITE 标志,说明这是最后一个弹出菜单 MF_STRING | MF_POPUP | MF_HELP | MF_HILITE, L'帮', L'助', 0, MF_STRING | MF_HILITE, 40038, L'关', L'于', L'H', L'e', L'l', L'l', L'o', L'W', L'i', L'n', L'd', L'o', L'w', L's', L'(', L'&', L'A', L')', 0 }; switch (message) { case WM_CREATE: { HMENU hMenu = GetMenu(hWnd); // 前面讲过,GetMenu 函数用于获取一个窗口的菜单句柄 HMENU hMenuPopup = CreateMenu(); // 弹出菜单句柄 AppendMenu(hMenuPopup, MF_STRING, ID_VIEW_BIG, TEXT("大图标")); AppendMenu(hMenuPopup, MF_STRING, ID_VIEW_SMALL, TEXT("小图标")); AppendMenu(hMenu, MF_STRING | MF_POPUP| MF_RIGHTJUSTIFY, (UINT_PTR)hMenuPopup, TEXT("视图")); DrawMenuBar(hWnd); return 0; } break; case WM_CHAR: // 从内存中动态加载菜单资源(菜单模板) hMenu = LoadMenuIndirect(arrMenuTemplate); SetMenu(hWnd, hMenu); return 0; case WM_COMMAND: { WORD wmId = LOWORD(wParam); switch (wmId) { case 40030: MessageBox(hWnd, TEXT("按下了剪切"), TEXT("提示"), MB_OK); break; case 40036: MessageBox(hWnd, TEXT("按下了大图标"), TEXT("提示"), MB_OK); break; case 40038: MessageBox(hWnd, TEXT("按下了关于 HelloWindows"), TEXT("提示"), MB_OK); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } break; } case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } 我放在WM_CREATE中依然没有什么用
最新发布
08-19
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值