Windows API 编程之调整菜单宽度

好多年没碰 Windows API 编程了,这次写 Traymond 才发现:堂堂 Windows 竟然没有一个 API 能够用来调整菜单的宽度。

通常,在程序中使用的静态菜单都是直接从资源中载入的,而这次需要动态增删菜单项目。这时我才发现一个问题:当用 InsertMenuItem() 函数插入一个菜单项时,Windows 会根据菜单项文本自动增加菜单宽度;但是当使用 DeleteMenu() 函数删除菜单项后,Windows 却无法根据剩余的菜单项文本自动缩小菜单宽度。搜遍全网,也只找到两种解决方法。

方法一、自绘菜单

在创建菜单项时使用 MFT_OWNERDRAW 标志,在消息循环中处理 WM_MEASUREITEM 消息,根据菜单项文本计算出所占宽度,填充 MEASUREITEMSTRUCT 结构的 itemWidth 成员。

不过要注意的是,仅在菜单第一次弹出时才会发送 WM_MEASUREITEM 消息,在用 ModifyMenu() 函数动态修改菜单文本后,并不会再次发送 WM_MEASUREITEM 消息。如果要重新设置菜单宽度,需要再对菜单项调用一次 SetMenuItemInfo() 函数。

方法二、重建菜单

暴力但有效的解决方式。


参考资料:使用菜单 - Win32 apps | Microsoft Learn