一、知识准备:

菜单 ----- 每个菜单会有一个HMENU句柄
菜单项 ------ 每个菜单项会有一个ID号,可以根据这个ID执行不同的操作。

菜单一般分为三种:系统菜单顶层菜单弹出菜单(右键菜单)
系统菜单: 程序左上角的图标点击鼠标左键、或者在标题栏点击鼠标右键,出现的就是系统菜单。主要内容有:还原、移动、大小、最小化、最大化、关闭。
顶层菜单: 一般出现在程序左上角位置。
弹出菜单: 程序的窗口中点击鼠标右键(必要的时候左键也可以)弹出的菜单,或者顶层菜单点击后出现的菜单,都称为弹出式菜单(也称为右键菜单)。

菜单创建方式:
1.从资源中加载菜单。
2.自己通过API函数创建。


二、从资源中加载菜单

1.添加菜单资源

资源文件-----添加-----资源-----选择Menu-----导入或新建-----加载成功(出现IDR_MENU1)


2.添加成功后,使用资源菜单

API函数:

  • 加载菜单资源:LoadMenu函数
// 加载菜单资源HMENU hmenu = LoadMenu(hInstance,MAKEINTRESOURCE(IDR_MENU1));// 顶层菜单的创建方法1wc.lpszMenuName   = MAKEINTRESOURCEW(IDR_MENU1);
// 顶层菜单的创建 方法2hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, hmenu, hInstance, nullptr);

三、自己创建菜单

API函数:

  • 指定的菜单条、下拉式菜单、子菜单或快捷菜单的末尾追加一个新菜单项的函数:AppendMenu
    函数AppendMenu己被lnsertMenultem取代
BOOL AppendMenu(hMenu hMenu,// 将被修改的菜单条、下拉式菜单、子菜单、或快捷菜单的句柄。UINT uFlags,  // 控制新菜单项的外观和性能的标志UINT uIDNewltem,// 指定新菜单项的标识符,或者当uFlags设置为MF_POPUP时,表示下拉式菜单或子菜单的句柄。LPCTSTR lpNewltem); // 指定新菜单项的内容。如果第二个参数为MF_BITMAP,此参数表含有位图句柄;// 如果第二个参数为MF_STRING,此参数表以`\O’结束的字符串的指针;
uFlags参数 说明
MF_BYCOMMAND 基于id
MF_BYPOSITION 基于下标
MF_BITMAP 将一个位图用作菜单项。参数lpNewltem里含有该位图的句柄。
MF_CHECKED 在菜单项旁边放置一个选取标记。如果应用程序提供一个选取标记,位图(参见SetMenultemBitmaps),则将选取标记位图放置在菜单项旁边。
MF_DISABLED 使菜单项无效,使该项不能被选择,但不使菜单项变灰。
MF_ENABLED 使菜单项有效,使该项能被选择,并使其从变灰的状态恢复。
MF_GRAYED 使菜单项无效并变灰,使其不能被选择。
MF_MENUBARBREAK 对菜单条的功能同MF_MENUBREAK标志。对下拉式菜单、子菜单或快捷菜单,新列和旧列被垂直线分开。
MF_MENUBREAK 将菜单项放置于新行(对菜单条),或新列(对下拉式菜单、子菜单或快捷菜单)且无分割列。
MF_OWNERDRAW 指定该菜单项为自绘制菜单项。菜单第一次显示前,拥有菜单的窗口接收一个WM_MEASUREITEM消息来得到菜单项的宽和高。然后,只要菜单项被修改,都将发送WM_DRAWITEM消息给菜单拥有者的窗口程序。
MF_POPUP 指定菜单打开一个下拉式菜单或子菜单。参数uIDNewltem下拉式菜单或子菜单的句柄。此标志用来给菜单条、打开一个下拉式菜单或于菜单的菜单项、子菜单或快捷菜单加一个名字。
MF_SEPARATOR 画一条水平区分线。此标志只被下拉式菜单、子菜单或快捷菜单使用。此区分线不能被变灰、无效或加亮。参数IpNewltem和uIDNewltem无用。
MF_STRING 指定菜单项是一个正文字符串;参数lpNewltem指向该字符串。
MF_UNCHECKED 不放置选取标记在菜单项旁边(缺省)。如果应用程序提供一个选取标记位图(参见SetMenultemBitmaps),则将选取标记位图放置在菜单项旁边。

1.系统菜单

1、获取系统菜单:

HMENU hmenu = GetSystemMenu( HWND hWnd, BOOL bRevert);    // FALSE获取当前的系统菜单。                      // TRUE恢复到默认的系统菜单,将删除所有自己定义的系统菜单项。

2、添加系统菜单:

BOOL AppendMenuW( HMENU hMenu, UINT uFlags,    // 标志,常用的MF_STRING(字符串),MF_SEPARATOR(分割线)UINT_PTR uIDNewItem,    // 菜单IDLPCWSTR lpNewItem);     // 菜单名字

3、删除系统菜单:

BOOL DeleteMenu( HMENU hMenu, UINT uPosition,   // 菜单ID或者菜单position IndexUINT uFlags);  // 删除标志: MF_BYPOSITION —通过索引删除MF_BYCOMMAND–通过菜单id方式删除

4、获取菜单总数:

int GetMenuItemCount(HMENU hMenu);   // 注意,分隔符也会作为菜单项的

5、获取position Index位置的菜单项ID:

UINT GetMenuItemID( HMENU hMenu, int nPos);  // 一般情况下,分隔符菜单的ID设置为0

6、系统菜单的消息处理WM_SYSCOMMAND
系统菜单点击以后产生的消息是WM_SYSCOMMAND,wParam中存放的是菜单ID。


2.顶层菜单(下拉式菜单)

1、创建顶层菜单
HMENU hmenu = CreateMenu();

2、添加顶层菜单项(添加在后面)水平方向
AppendMenu函数,同样可以添加菜单项,同样通过WM_COMMAND消息响应。

AppendMenu(hMenu, 0, 1, _T("打开(&O)"));  // 按住alt + O键可打开快捷键
AppendMenu(hMenu, MF_BYCOMMAND, 2, _T("复制"));  // MF_BYCOMMAND 基于id ;MF_BYPOSITION基于下标

3、插入菜单项

BOOL InsertMenu(HMENU hMenu,UINT uPosition, // 插入位置,注意:这里可写位置也可写ID,必须和下面的uFlags配合使用,>MF_BYPOSITION或者MF_BYCOMMAND(默认是这个),会插入在该位置或该ID的前面。UINT uFlags, // 菜单项的标志UINT_PTR uIDNewItem, // 菜单项目IDLPCWSTR lpNewItem); // 菜单项的字符串

另外一个插入菜单项的函数:InsertMenuItem

4、修改菜单项(ModifyMenu)

BOOL ModifyMenu(HMENU hMnu,UINT uPosition,   // 位置或ID,与下面的uFlags配合使用UINT uFlags,   // MF_STRING MF_BYPOSITION MF_BYCOMMAND等等UINT_PTR uIDNewItem,  // 修改后的IDLPCWSTR lpNewItem);   // 修改后的字符串

另外一个修改菜单项的函数:SetMenuItemInfoW

5、设置顶层菜单(显示菜单)

BOOL WINAPI SetMenu(HWND hWnd, HMENU hMenu);

一般在窗口的WM_CREATE中使用,让顶层菜单显示在窗口的顶层。

6、刷新菜单(菜单项修改后重新显示)

BOOL WINAPI DrawMenuBar(HWND hWnd);

添加或者删除顶层菜单项以后,需要使用该函数及时地刷新菜单的显示。

7、创建弹出式菜单并添加弹出式菜单的菜单项。
同上,使用CreatePopupMenu和AppendMenu、InsertMenu。

8、关联顶层菜单和弹出式菜单。
还是使用AppendMenu,只不过参数有些不同。

AppendMenu(顶层菜单句柄,MF_POPUP,(UINT)弹出式菜单句柄,顶层菜单项字符串);

对于在弹出式菜单中再增加一个弹出式菜单,也是同样的方法。

9、获取菜单句柄

HMENU GetMenu(HWND hWnd); //获取窗口的顶层菜单

10、获取子菜单句柄

HMENU GetSubMenu(HMENU hMenu, int nPos); //获取子菜单的句柄

11、菜单项的勾选 CheckMenuItem
在添加菜单项的时候,可以用 MF_STRING | MF_CHECKED | MF_UNCHECKED 来设置是否勾选。

DWORD CheckMenuItem(HMENU hMenu,UINT uIDCheckItem,UINT uCheck);
CheckMenuItem(hMenu, 1, MF_UNCHECKED|MF_BYCOMMAND ); //设置不勾选
CheckMenuItem(hMenu, 2, MF_CHECKED|MF_BYPOSITION ); // 设置勾选

12、菜单项可用不可用设置 EnableMenuItem
在初始化的时候,假如需要该菜单项不能被点击,可以使用MF_STRING | MF_GRAYED设置为灰色(不能点击)。

EnableMenuItem(Hm, 3002, MF_ENABLED | MF_BYCOMMAND); //设置为可以点击
EnableMenuItem(Hm, 1, MF_DISABLED | MF_BYPOSITION); //设置为不可点击

13、菜单项前面加图标

在正常的添加菜单项的后面再加上一句:
BOOL SetMenuItemBitmaps(HMENU hMenu,UINT uPosition,  // 位置或者ID,配合uFlags使用UINT uFlags,     // MF_BYPOSITION MF_BYCOMMANDHBITMAP hBitmapUnchecked,   // 非选择HBITMAP hBitmapChecked);    // 选择

这个适合在弹出式菜单


3.弹出菜单(右键菜单)

1、创建弹出式菜单

HMENU CreatePopupMenu();   // 返回创建弹出式菜单的菜单句柄

2、添加、删除菜单项 ,同上面的系统菜单,AppendMenu,DeleteMenu。

AppendMenu(hMenu, MF_CHECKED, 5001, _T("新建"));   //添加菜单项
AppendMenu(hMenu, MF_POPUP, (UINT)hMenu1, _T("文件(&P)"));// MF_POPUP添加一个子菜单

3、销毁弹出式菜单

BOOL DestroyMenu(HMENU hMenu); // 弹出式菜单是自己创建的,所以在不需要的时候,使用DestroyMenu销毁菜单

4、显示弹出式菜单(一般响应WM_RBUTTONDOWN)

BOOL TrackPopupMenu(HMENU hMenu,UINT uFlags, //标志,比如TPM_LEFTALIGN,菜单左边在x的位置int x,int y, //注意:屏幕坐标x,yint nReserved,HWND hWnd,RECT *prcRect); //用屏幕坐标定义的一个矩形,如用户在这个矩形的范围内单击,则弹出式菜单不会关闭。如单击弹出式菜单之外的任何一个地方,则会关闭菜单。可以设为NULL。该函数为阻塞函数。

5、弹出式菜单的消息处理 WM_COMMAND
弹出式菜单点击以后,发送消息WM_COMMAND,wParam保存菜单项ID。


效果图:

部分代码:

   HMENU hMenu = CreatePopupMenu();  // 创建一个弹出式菜单AppendMenu(hMenu, MF_CHECKED, 3001, _T("第一个菜单项"));   // 添加第一个菜单项,打勾的HMENU hMenu1 = CreateMenu();     // 创建子菜单1AppendMenu(hMenu1, MF_CHECKED, 5001, _T("菜单1.1(&A)"));  // 菜单1的第1个项AppendMenu(hMenu1, 0, 5002, _T("菜单1.2(&B)"));       // 菜单1的第2个项AppendMenu(hMenu1, 0, 5003, _T("菜单1.3"));            // 菜单1的第3个项AppendMenu(hMenu, MF_POPUP, (UINT)hMenu1, _T("子菜单2(&P)"));// MF_POPUP,将菜单1作为弹出菜单的子菜单HMENU hMenu2 = CreateMenu();AppendMenu(hMenu2, MF_BYPOSITION | MF_CHECKED, 6001, _T("菜单2.1"));// 菜单2的第1个项AppendMenu(hMenu2, MF_BYPOSITION, 6002, _T("菜单2.2"));         // 菜单2的第2个项AppendMenu(hMenu2, MF_BYCOMMAND, 6003, _T("菜单2.3"));          // 菜单2的第3个项InsertMenu(hMenu2, 6003, MF_BYCOMMAND | MF_SEPARATOR, 6004, _T("-"));  // 一条水平区分线AppendMenu(hMenu, MF_POPUP, (UINT)hMenu2, _T("子菜单2(&E)"));// MF_POPUP,将菜单2作为弹出菜单的子菜单case WM_RBUTTONDOWN:{POINT pt;pt.x = LOWORD(lParam);pt.y = HIWORD(lParam);ClientToScreen(hWnd, &pt);  // 把客户区坐标转换为屏幕坐标//弹出右键菜单TrackPopupMenu(hMenu,//哪一个菜单TPM_LEFTALIGN | TPM_TOPALIGN,//菜单风格,对齐方式pt.x, pt.y,//鼠标点击的位置0,hWnd,nullptr);}break;

一个人一定要活出不一样的自己,不管别人怎么看待,你需要的是成为自己的英雄!

Win32创建菜单篇相关推荐

  1. win32创建控件的一些问题

    在我们使用CreateWindow();像一般控件建Windows扩展控件的时候我们会发现控件没有创建成功 这是因为我们没有对Windows扩展控件库进行初始化,这要我们使用InitCommonCon ...

  2. win32创建窗口及其消息循环

    转自:http://anyzixin.blog.163.com/blog/static/365289122007103031657355/ http://anyzixin.blog.163.com/b ...

  3. 转载:注册表修改--鼠标左右键菜单篇

    注册表修改--鼠标左右键菜单篇 加Apploc到右键中去: [HKEY_CLASSES_ROOT\exefile\shell\Apploc\command] 再修改其中的默认值为C:\windows\ ...

  4. win32 创建进程三种方式简单示例 - 使用CFree

    新建一个简单窗口工程: 语言在C和C++中选择C:构建配置默认,mingw5: #include <windows.h>int APIENTRY WinMain(HINSTANCE hIn ...

  5. 移动UI设计-菜单篇

    1.导航模式 导航类型 导航种类 主要导航模式 跳板式.列表菜单式.选项卡菜单式.陈列馆式.仪表式.隐喻式.超级菜单式 次级导航模式 页面轮盘式.图片轮盘式.扩展列表式 2.导航种类样式及场景说明 2 ...

  6. EXTJS学习系列提高篇:第二十五篇(转载)作者殷良胜,ext2.2打造全新功能grid系列--右键菜单篇...

    本文介绍如何在grid列表里 在某行上面单击右键弹出菜单的功能 先看看效果图: 如上图所示,具体菜单的功能没有去实现,这里和前几篇的后台都极为类似,有需要后台代码的朋友只需要浏览前几篇即可. 下面仅仅 ...

  7. 如何在WPF中通过XAML代码创建菜单项

    2019独角兽企业重金招聘Python工程师标准>>> 示例代码: 示例1: <Grid><Menu><MenuItem Header="Fi ...

  8. WIN32创建居中对话框

    这里给出的方法是在 WM_INITDIALOG 事件里实现居中处理. 下面是对话框窗口过程以及主函数: // EncryptMain.cpp : Defines the entry point for ...

  9. 跟我一起玩Win32开发(4):创建菜单

    跟我一起玩Win32开发(4):创建菜单 也不知道发生什么事情,CSDN把我的文章弄到首页,结果有不少说我在误人子弟,是啊,我去年就说过了,如果你要成为砖家级人物,请远离我的博客,我这个人没什么特长, ...

最新文章

  1. 学习利器:工欲善其事,必先利其器
  2. iOS之深入解析WKWebView的坑点收录和优化处理
  3. 分布式与人工智能课程(part16)--深度学习
  4. Java网络编程之SocketChannel和ServerSocketChannel
  5. opencv之图像边界填充-- copyMakeBorder
  6. 基于KMeans的指数择时策略
  7. Runtime 源码阅读
  8. 下载谷歌浏览器和谷歌驱动
  9. 詹姆斯·格雷克《信息简史》读后感记录
  10. 多益网络2022春笔试题记忆版
  11. 消防信号总线原理_消防联动工作原理
  12. 数据库建模 : 概念模型 , 逻辑模型和物理模型
  13. Linux主目录下的文件夹名称改为英文
  14. 性能效率(Performance efficient)弱点度量
  15. 打造海报视觉效果—利用图层模式调色
  16. 企业vi设计中服装服饰类设计原则
  17. protobuf_name_conflict问题解决
  18. 关键词分析工具-免费关键词分析软件
  19. MAN 手册各章节功能介绍及快捷键键位整理
  20. 制作Mac的U盘启动系统

热门文章

  1. 世界上最小的操作系统MenuetOS,仅有1.4M,安装运行全教程
  2. WebVTT字幕格式
  3. 拼多多超越阿里淘宝,黄峥辞任董事长;蚂蚁集团CEO宣布辞职,上市陷入迷途?...
  4. “绿多多”绿色资产资讯:良设板+“空间优造”亮相雄安 绿色生态进击!
  5. 分治法求数组最大最小数
  6. android查看显存大小,Shadow Size Computation 阴影大小计算
  7. 论文略读 | Pointing the Unknown Words
  8. WPF无边框窗体拖动
  9. 申请 icp经营性许可证/增值电信业务许可证
  10. 2015秋季腾讯【技术运营】岗位———在线笔试总结