winapi - 何时绘制(和隐藏)所有者绘制菜单栏的下划线

标签 winapi menu

在下面的帖子中

Menu Accelerator Keys (underline) for Owner-Draw menu items

我问了一个关于当用户使用 Alt 键导航系统菜单时“如何”绘制下划线的问题,如果菜单栏是所有者绘制的。完成了(感谢 Hans Passant)。

但现在又出现了另一个问题:“何时”绘制(和隐藏)下划线。

Alt 按下后,WM_DRAWITEM 消息生成(针对所有项目),然后是 WM_SYSCOMMAND with wParam == SC_KEYMENU,以及最后 WM_DRAWITEM 用于所选项目。

消息列表见文末

因为在 WM_SYSCOMMAND 之后,其他项目没有 WM_DRAWITEM,我必须使用 WM_SYSKEYDOWN 和 VK_MENU 来指示用户正在使用该键导航系统菜单。于是得到如下代码:(这里byKey是一个静态bool变量)

    case WM_SYSKEYDOWN:
    {
        if (wParam == VK_MENU)
            byKey = true;
        return DefWindowProc(hwnd, msg, wParam, lParam);
    }

    case WM_EXITMENULOOP:
    {
        if (wParam == 0)
            byKey = false;
        return DefWindowProc(hwnd, msg, wParam, lParam);
    }

我的问题是:是否有更好的方法来了解“何时”绘制(和隐藏)下划线??

<00686> 000B0444 P WM_SYSKEYDOWN nVirtKey:VK_MENU cRepeat:1 ScanCode:38 fExtended:0 fAltDown:1 fRepeat:0 fUp:0 [wParam:00000012 lParam:20380001]
<00687> 000B0444 S WM_DRAWITEM idCtl:0 lpdis:003EF080 [wParam:00000000 lParam:003EF080]
<00688> 000B0444 R WM_DRAWITEM fProcessed:True [lResult:00000001]
<00689> 000B0444 S WM_DRAWITEM idCtl:0 lpdis:003EF080 [wParam:00000000 lParam:003EF080]
<00690> 000B0444 R WM_DRAWITEM fProcessed:True [lResult:00000001]
<00691> 000B0444 S WM_DRAWITEM idCtl:0 lpdis:003EF080 [wParam:00000000 lParam:003EF080]
<00692> 000B0444 R WM_DRAWITEM fProcessed:True [lResult:00000001]
<00693> 000B0444 S WM_DRAWITEM idCtl:0 lpdis:003EF080 [wParam:00000000 lParam:003EF080]
<00694> 000B0444 R WM_DRAWITEM fProcessed:True [lResult:00000001]
<00695> 000B0444 S WM_DRAWITEM idCtl:0 lpdis:003EF080 [wParam:00000000 lParam:003EF080]
<00696> 000B0444 R WM_DRAWITEM fProcessed:True [lResult:00000001]
<00697> 000B0444 S WM_DRAWITEM idCtl:0 lpdis:003EF080 [wParam:00000000 lParam:003EF080]
<00698> 000B0444 R WM_DRAWITEM fProcessed:True [lResult:00000001]
<00699> 000B0444 S WM_DRAWITEM idCtl:0 lpdis:003EF080 [wParam:00000000 lParam:003EF080]
<00700> 000B0444 R WM_DRAWITEM fProcessed:True [lResult:00000001]
<00701> 000B0444 S WM_DRAWITEM idCtl:0 lpdis:003EF080 [wParam:00000000 lParam:003EF080]
<00702> 000B0444 R WM_DRAWITEM fProcessed:True [lResult:00000001]
....
<00708> 000B0444 P WM_SYSKEYUP nVirtKey:VK_MENU cRepeat:1 ScanCode:38 fExtended:0 fAltDown:0 fRepeat:1 fUp:1 [wParam:00000012 lParam:C0380001]
<00709> 000B0444 S WM_SYSCOMMAND uCmdType:SC_KEYMENU xPos:0 yPos:0 (used mnemonic) [wParam:0000F100 lParam:00000000]
<00710> 000B0444 S WM_ENTERMENULOOP fIsTrackPopupMenu:False [wParam:00000000 lParam:00000000]
<00711> 000B0444 R WM_ENTERMENULOOP lResult:00000000
....

<00714> 000B0444 S WM_INITMENU hmenuInit:01B10471 [wParam:01B10471 lParam:00000000]
<00715> 000B0444 R WM_INITMENU lResult:00000000
    <00716> 000B0444 S WM_DRAWITEM idCtl:0 lpdis:003EECE8 [wParam:00000000 lParam:003EECE8]
<00717> 000B0444 R WM_DRAWITEM fProcessed:True [lResult:00000001]
<00718> 000B0444 S WM_MENUSELECT uItem:0 fuFlags:MF_POPUP | MF_HILITE | MF_OWNERDRAW hmenu:01B10471 [wParam:01900000 lParam:01B10471]
<00719> 000B0444 R WM_MENUSELECT lResult:00000000

最佳答案

您的WM_DRAWITEM 消息包含指向DRAWITEMSTRUCT 的指针。在该结构中,如果应隐藏下划线,则将在 itemState 中设置 ODS_NOACCEL 标志。

关于winapi - 何时绘制(和隐藏)所有者绘制菜单栏的下划线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14920364/

相关文章:

c++ - 串口ReadFile接收重复数据

html - 为什么对齐 ="right"不起作用?

android - 制作安卓游戏

android - 硬件菜单按钮未在 Samsung galaxy tab 3 中打开

c++ - Windows 日记本播放 Hook (WH_JOURNALPLAYBACK) 忽略 EVENTMSG HWND 参数

c# - 获取桌面/外壳窗口的句柄

C/C++ Windows 10 x64 (17763) 企业 DACL 问题

c++ - 没有 aero 对话框无法正确显示

jquery - 做一个容器显示:none when the content of <a> is empty

html - 背景图片分隔符不会显示在我的 CSS 菜单中