检测在列表视图内单击并显示上下文菜单

Posted

技术标签:

【中文标题】检测在列表视图内单击并显示上下文菜单【英文标题】:Detect clicking inside listview and show context menu 【发布时间】:2012-09-29 13:49:23 【问题描述】:

我创建了一个列表视图作为资源并加载到对话框窗口中。我只想在单击列表视图中的项目时检测并显示上下文菜单。

 MESSAGE_HANDLER(WM_CONTEXTMENU,OnContextMenu)

        LRESULT OnContextMenu(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
            
                int iSelected = -1;
    int iFocusGroup = -1;
    iSelected = SendMessage((HWND)wParam, LVM_GETNEXTITEM, -1,LVNI_SELECTED);
    iFocusGroup = ListView_GetFocusedGroup((HWND)wParam);
    if( iSelected != -1 && iFocusGroup == -1) 
                    hPopupMenu = CreatePopupMenu();
                    Insert

Menu(hPopupMenu,  0,     MF_BYCOMMAND | MF_STRING | MF_ENABLED, ID_SHREDTASK_CTXMENU_DELETE, TEXT("Delete"));
                TrackPopupMenu(hPopupMenu, TPM_TOPALIGN | TPM_LEFTALIGN, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), 0, m_hWnd, NULL); 
            
            return 0;
        

好的,我已对其进行了编辑,它的工作方式与此处显示的方式相同,但问题仍然存在,有人可以向我解释这里焦点小组的问题以及为什么我在对话框中发送 LVM_GETNEXTITEM 消息返回!= -1?不是只针对 Listviews 吗?

编辑:

这是我根据您的回答制定的另一种选择:

LRESULT OnNotifyRClick(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
    
          switch (uMsg)
        
            case WM_NOTIFY:
                switch (((LPNMHDR)lParam)->code)
                
                case NM_RCLICK:
                    if (((LPNMHDR)lParam)->idFrom == IDC_LISTTASKFILES)
                                           
                         int iSelected = -1;
                         iSelected = SendMessage(GetDlgItem(IDC_LISTTASKFILES), LVM_GETNEXTITEM, -1,LVNI_SELECTED);

                        if( iSelected != -1 ) 
                            hPopupMenu = CreatePopupMenu();
                            InsertMenu(hPopupMenu,  0,     MF_BYCOMMAND | MF_STRING | MF_ENABLED, ID_SHREDTASK_CTXMENU_DELETE, TEXT("Delete"));
                            TrackPopupMenu(hPopupMenu, TPM_TOPALIGN | TPM_LEFTALIGN, ((CPoint)GetMessagePos()).x, ((CPoint)GetMessagePos()).y, 0, m_hWnd, NULL); 
                        
                         bHandled = true;

                        return TRUE;
                    
                    break; 

                break;
                

        
          return false;
    

【问题讨论】:

我不太明白:您将 MFC 和原始 WINAPI 混合在一起。重点是什么?首先尝试保持一致:要么全部 MFC 要么全部 WINAPI,但将两者混合不是一个好主意。 我根本不使用 MFC。我使用 WTL 和 winapi。 哎呀,对不起,我被看起来像 ON_MESSAGE MFC 宏的 MESSAGE_HANDLER 宏误导了......并且您将问题标记为 MFC!然后你应该删除这个标签 好吧,你可以把责任推给我,我只是以为 MFC 的人一般都会知道 winapi。无论如何,删除它。 【参考方案1】:

NM_RCLICK 是你的朋友。

但这并不能解决整个问题,例如当用户按下键盘上的 Windows 菜单键时显示上下文菜单。这个KB article 展示了如何组合 NM_RCLICK 和 WM_CONTEXTMENU。 (它适用于 CTreeCtrl,但将代码适应 CListView 是微不足道的)。

【讨论】:

【参考方案2】:

无论列表视图中的点击位置如何,您都将调用OnContextMenu 处理程序。现在您的任务是查看点击的确切位置并决定您想要的操作。

你的问题让我觉得你是从互联网上用ListView_GetFocusedGroup 获取代码的,而不是故意自己写的。但是,您需要做的是将“命中测试”消息发送回提供兴趣点(即点击点)的列表视图:ListView_HitTestListView_HitTestEx

完成此操作后,您将获得该位置的项目和/或子项目,然后您可以决定下一步要做什么。

【讨论】:

我没有从互联网上获取代码,只是他们认为它会起作用。我试图检测 Listview 何时成为焦点,并在搜索我发现的函数和属性时那个功能。但我不认为我真的做对了。 没关系。只是不太清楚你为什么要寻找专注的群体。相反,您想要的第一件事是查看点击的确切位置。手上有项目编号,您可以检查它是否已聚焦、已选中、是否属于某个组等。

以上是关于检测在列表视图内单击并显示上下文菜单的主要内容,如果未能解决你的问题,请参考以下文章

在列表视图的上下文菜单中实现复制和粘贴

右键单击列表视图以显示 contextmenustrip,但弹出菜单出现在屏幕的不相关点

为列表视图和列表视图项创建单独的上下文菜单

如何获取所选列表视图项中的id以打开上下文菜单并通过下一个活动来实现目标。

在窗口范围内限制/移动上下文菜单(右键单击)

当我生成上下文菜单时,在列表视图中选择一个项目