【问题标题】:How do I create a right-click menu in a list control?如何在列表控件中创建右键菜单?
【发布时间】:2018-02-07 06:03:26
【问题描述】:

(IDE:Visual C++ 6.0)

我想使用列表控件来创建一个类似 Windows 任务管理器的程序。

添加通过api接收到的进程信息(item),并通过列表控件显示出来。

我要做的是右键单击特定项目,然后会出现一个对话框,就像真正的任务管理器一样。

搜索的结果好像是使用了OnContextMenu(CWnd*, CPoint)函数,但是不明白是怎么工作的。

我希望你提供一个简单的例子。

谢谢你:)

【问题讨论】:

    标签: c++ mfc contextmenu right-click listcontrol


    【解决方案1】:

    这是从我的一个项目中提取的工作示例。 请注意,此代码适用于 VS'15,可能也适用于 VS'10。我没有 1998 年的版本……已经 20 年了。

    我在代码中留下了一些 cmets。请仔细阅读这些内容。

    CMenu m_Menu; //Class member
    
    m_Menu.CreateMenu(); //Call this once only (I do it in PreSubclassWindow)
    
    //class CMenuListCtrl : public CListCtrl
    void CMenuListCtrl::OnContextMenu(CWnd *pWnd, CPoint ptMousePos)
    {
        //Some people might use a keyboard and not the mouse
        if (ptMousePos.x == -1 && ptMousePos.y == -1)
        {
            auto nSelectedItem = GetSelectionMark(); //Get the selected item in the CListCtrl
            if (nSelectedItem == -1)
                return;
    
            //Find the position
            CRect itemRect;
            GetItemRect(nSelectedItem, &itemRect, LVIR_BOUNDS);
            ClientToScreen(&itemRect);
            ptMousePos.x = itemRect.left + (itemRect.Width() / 10); //Some offset to display the menu user-friendly
            ptMousePos.y = itemRect.top + itemRect.Height() / 2;
        }
    
        CPoint hitPoint = ptMousePos;
        ScreenToClient(&hitPoint);
    
        //Fix header pop-up bug
        CHeaderCtrl *pHeader = GetHeaderCtrl();
        HDHITTESTINFO hitTestHeader = {0};
        hitTestHeader.pt = hitPoint;
    
        //The header doesn't need a context-menu, the item does
        if (pHeader->HitTest(&hitTestHeader) != -1)
            return;
    
        UINT uFlags = 0;
        HitTest(hitPoint, &uFlags);
        if (uFlags & LVHT_NOWHERE)
            return;
    
        //Get the previously created menu
        CMenu *pPopUp = nullptr;
        pPopUp = m_Menu.GetSubMenu(0);
    
        if (pPopUp)
            pPopUp->TrackPopupMenu(TPM_LEFTALIGN, ptMousePos.x, ptMousePos.y, this);
    }
    

    为了显示菜单,你必须先创建一个。

    CMenu submenu;
    submenu.CreatePopupMenu();
    submenu.AppendMenuW(MF_STRING, IDC_COPY_POPUP,          L"&Copy");
    submenu.AppendMenuW(MF_SEPARATOR);
    submenu.AppendMenuW(MF_STRING, IDC_DELETE_POPUP,        L"&Delete");
    m_Menu.AppendMenuW(MF_POPUP, reinterpret_cast<UINT_PTR>(submenu.m_hMenu), L"");
    
    submenu.Detach();
    

    【讨论】:

    • +1 只是因为你让我发现: 1. 当用户按下键盘上下文菜单键时,我有一个错误,菜单出现在主屏幕的左上角,而不是它应该出现的位置。 2.我的header也有显示弹窗的行为。
    猜你喜欢
    • 2019-09-13
    • 2012-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-03
    • 2010-10-20
    • 2021-05-31
    • 1970-01-01
    相关资源
    最近更新 更多