TrackPopupMenu会“伤害”我的HMENU吗?

时间:2011-03-25 19:34:29

标签: windows winapi visual-c++ contextmenu trayicon

部屋。最后,经过大量的摆弄,我得到一个.rc加载的上下文菜单,我的托盘通知图标工作。 (基于对话框的Windows API应用程序,没有MFC)。但是,在各种示例和用法演示中,我总是看到正在创建HMENUCreateMenu()LoadMenu())并在之前/之前销毁(DestroyMenu()紧接着TrackPopupMenu()的调用。通知图标的弹出菜单就像在MSDN上没有记录一样(至少我没有找到关于它们的多个段落。)

直观地,我将LoadMenu()放在WM_INITDIALOG的消息处理中并存储HMENU,因此我不必每次都创建和销毁菜单。正如我所说,我没有找到任何类似的例子,我觉得有点有趣。使用菜单或应用程序时,HMENU可能会“损坏”吗?或者像我一样去(好的,边缘的)额外表现是否安全?

INT_PTR CALLBACK MainDlg(HWND ..., UINT, WPARAM, LPARAM)
{
    switch (message)
    {
    case WM_INITDIALOG:
        ...
        HMENU hMenuBar = LoadMenu(hInst, MAKEINTRESOURCE(IDR_NOTIFYMENU));
        hNotifyMenu = GetSubMenu(hMenuBar, 0);
        ...
        break;

    ...

    case WM_NOTIFYICON:
        switch (lParam)
        {
        case WM_RBUTTONUP:        // there is no WM_CONTEXTMENU for 
            {                     // nid.uVersion != NOTIFYICON_VERSION_4
            POINT CursorPos;
            GetCursorPos(&CursorPos);

            // this is where I saw LoadMenu and stuff in examples

            SetForegroundWindow(hDlg); // otherwise menu won't disappear
            TrackPopupMenu(hNotifyMenu, TPM_LEFTALIGN, CursorPos.x,
                           CursorPos.y, 0, hDlg, NULL);

            PostMessage(hDlg, WM_NULL, 0, 0); // otherwise menu locks hDlg

            // this is where I saw DestroyMenu in examples
            }

            return (INT_PTR)TRUE;
        }
        ...
    }
    ...
}

1 个答案:

答案 0 :(得分:2)

并不是说它被破坏了,更多的是你不想让GDI资源保持超过绝对必要的时间。你可以很容易地用完它们,只需看看几个月来一直在努力克服GDI资源限制的Chrome,然后再找到解决方法。

除了加载菜单十几次并且破坏它对于现代处理器来说也没什么。不要过早地优化程序,特别是不要获得如此少的收益。

至于为什么你没有找到专门处理通知图标菜单的MSDN页面,那是因为它们是两个独立的东西。菜单是一个菜单,无论是在对话框的顶部,右键单击文本框时弹出还是右键单击通知图标。您不需要特殊建议或代码。