C++调用Win32 API AppendMenuA创建菜单时报类型转换错误
问题根因
AppendMenuA的第三个参数uIDNewItem类型是UINT_PTR(和系统指针位宽一致的无符号整数),根据菜单项类型不同,这个参数传值规则不同:
- 普通命令菜单项(不带
MF_POPUP标记):传入菜单项对应的命令ID - 弹出式子菜单项(带
MF_POPUP标记):传入子菜单的句柄
你写的代码里直接传HMENU类型的hSubMenu,没有做显式类型转换,在64位编译环境下会出现句柄值截断:64位系统中HMENU是64位指针,隐式转换为整数类型时部分编译器会丢失高32位数据,最终系统拿到的是无效的子菜单句柄,点击"Tool"主菜单尝试展开子项时,系统访问非法内存就会触发运行时错误。32位环境下HMENU和UINT_PTR位宽都是32位,隐式转换不会丢数据,这也是很多老旧32位示例代码省略强转也能正常运行的原因。
另外你贴的代码里WM_CREATE分支处理完没有加break,会导致窗口过程的消息流程穿透到后续其他消息分支,也可能触发不可预期的错误。
修正后代码
case WM_CREATE: { HMENU hSubMenu = CreatePopupMenu(); AppendMenuA(hSubMenu, MF_STRING, 9002, "Do This"); HMENU hMenu = CreateMenu(); // 核心修正:将子菜单句柄显式转换为UINT_PTR类型,保证64位下值完整 AppendMenuA(hMenu, MF_STRING | MF_POPUP, (UINT_PTR)hSubMenu, "Tool"); SetMenu(hwnd, hMenu); } break; // 必须加,避免消息流程穿透
内容的提问来源于stack exchange,提问作者user2288650
相关产品推荐
相关产品推荐

