我将listview创建为资源并加载到对话框窗口中。我只想在点击列表视图中的项目时检测并显示上下文菜单。
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;
}
答案 0 :(得分:2)
无论listview中的点击位置如何,都会调用OnContextMenu
处理程序。现在您的任务是查看确切点击发生的位置并确定您想要的操作。
您的问题让我觉得您从互联网上抓取ListView_GetFocusedGroup
代码,而不是自己编写代码。但是,您需要做的是将“命中测试”消息发送回列表视图,提供兴趣点(即点击点):ListView_HitTest
,ListView_HitTestEx
。
完成此操作后,您将获得此位置的项目和/或子项目,您可以决定下一步该做什么。
答案 1 :(得分:2)
NM_RCLICK是你的朋友。
但它并没有解决整个问题,例如当用户点击键盘上的Windows菜单键时显示上下文菜单。这个KB article显示了如何组合NM_RCLICK和WM_CONTEXTMENU。 (这是针对CTreeCtrl但是将代码调整到CListView是微不足道的。)