《Windows游戏编程大师技巧》学习笔记(五)
创建菜单
菜单的配置与前述各类资源一样,编写在.RC
资源脚本中,同时,和字符串资源相似,菜单各项的标识符也必须是整数ID,而不能是名称字符串;
一个简单的菜单配置如下:
1 | // 在头文件 RESOURCES.H 中 |
1 | // 在资源脚本 xxx.RC 中 |
上述代码可以生成如下图所示的菜单栏:
作者在书中写道“关键字DISCARDABLE是过时了但还是必须的”,但是实测在VisualStudio2019环境下此声明是不需要的;
与其他资源的定义相同,花括号可以被替换为BEGIN...END
对;
如果需要设置热键或配合Alt触发的快捷键,只需要在POPUP菜单或MENUITEM字符串中将&
放到想要标识的快捷键字符前面,如下:
1 | // 使 x 成为热键 |
装载菜单
装载菜单的方式有如下三种:
1. 初始化Windows类时指定菜单名
前文中所定义的菜单资源,就可以通过如下方式加载:
1 | winclass.lpszMenuName = "MainMenu"; |
与其他资源同理,如果”MainMenu”被定义为了整数ID时,则需要使用MAKEINTRESOURCE
宏进行处理,后文不再赘述;
在初始化Windows类时指定菜单名,如果使用当前类创建了多个窗口,则这些窗口具有相同的菜单;
2. 创建窗口时指定菜单句柄
可以使用LoadMenu
函数动态加载资源中的菜单,在非Unicode环境下函数原型如下:
1 | HMENU WINAPI LoadMenuA( |
函数加载返回的菜单句柄,可以传入CreateWindowEx
函数中,在创建窗口时指定菜单;
3. 动态设置菜单
可以使用SetMenu
函数动态设置已存在窗口的菜单,函数原型如下:
1 | BOOL WINAPI SetMenu( |
使用此方式设置的菜单优先级是最高的,可以覆盖替换在初始化时指定的菜单;
响应菜单事件消息
当菜单项被点击时,消息依然是被事件回调函数进行处理,如下图所示:
参数对应关系如下:
msg
:一定为WM_COMMAND
;lparam
:发出消息的窗口句柄;wparam
:选中的菜单项ID;
使用LOWORD
宏从wparam
中提取低位的WORD
再进行处理更安全;
剩下的操作便是用switch
语句来处理wparam
的低位值就可以了,参考前文中定义的菜单项,一个可能的事件回调函数如下所示:
1 | LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) |
上述代码仅展示了菜单项被选中时的常见处理操作,还有其他用于操作一级菜单和菜单项本身的消息,更多内容见Win32SDK - 菜单通知。
《Windows游戏编程大师技巧》学习笔记(五)