TrackPopupMenu 是否“有害”?我的菜单?

发布于 2024-10-27 08:39:02 字数 1598 浏览 1 评论 0原文

嘿呀。最后,经过大量的摆弄,我得到了一个 .rc 加载的上下文菜单,可以让我的托盘通知图标正常工作。 (基于对话框的 Windows API 应用程序,无 MFC)。然而,在各种示例和用法演示中,我总是看到 HMENU 正在被创建(CreateMenu()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;
        }
        ...
    }
    ...
}

Heya. Finally, after a lot of fiddling, I got a .rc-loaded context menu for my tray notify icon working. (Dialog based Windows API application, no MFC). However, in the various examples and usage demonstrations I always saw that the HMENU is being created (CreateMenu(), LoadMenu()) and destroyed (DestroyMenu()) right before/right after the call to TrackPopupMenu(). Popup menus for notify icons are, like, not at all documented on MSDN (at least I haven't found more than a single paragraph about them).

Intuitively, I put the LoadMenu() in the message handling for WM_INITDIALOG and store the HMENU, so I don't have to create and destroy the menu every time. As I said, I haven't found any examples where this is done similarly, which I find a bit intriguing. Is it possible that my HMENU would ever get "corrupted" while using the menu or the application? Or is it safe to go for the (well, marginal) extra performance as I do?

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;
        }
        ...
    }
    ...
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

夏尔 2024-11-03 08:39:02

这并不是说它被损坏了,而是您不希望持有 GDI 资源的时间超过绝对必要的时间。你可以很容易地用完它们,看看 Chrome 几个月来一直在与 GDI 资源限制作斗争,最后才找到解决办法。

对于现代处理器来说,除了加载菜单十几次并销毁它之外,这没什么。不要过早地优化程序,尤其不要为了那么一点点的收益。

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

It's not that it gets corrupted, it's more that you don't want to hold GDI resources longer than absolutely necessary. You can easily run out of them, just look at Chrome that struggled with GDI resource limits for months before finally finding a work around.

Besides loading a menu a dozen times and destroying it is nothing for a modern day processor. Don't prematurely optimize programs, especially not for so little gain.

As to why you haven't found any MSDN pages dealing specifically with notification icons' menus, that's because they're two separate things. A menu is a menu, whether it's on top of a dialog, popping up when you right click a textbox or when you right click a notification icon. You don't need special advice or code for either.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文