我想在用户右键单击CListCtrl中的项目时显示上下文菜单。我的代码如下:
void DatastoreDialog::OnContextMenu(CWnd *pWnd, CPoint pos)
{
// Find the rectangle around the list control
CRect rectMainArea;
m_itemList.GetWindowRect(&rectMainArea);
// Find out if the user right-clicked the list control
if( rectMainArea.PtInRect(pos) )
{
LVHITTESTINFO hitTestInfo;
hitTestInfo.pt = pos;
hitTestInfo.flags = LVHT_ONITEM;
m_itemList.HitTest(&hitTestInfo);
if (hitTestInfo.flags & LVHT_NOWHERE)
{
// No item was clicked
}
else
{
MyContextHandler(hitTestInfo)
}
}
}
当我实际运行代码时,无论单击何处;在项目上,在CListCtrl内的空白空间中,对话框上的其他任何位置(通过删除第一个if语句);
hitTestInfo.flags
设置为48,如果我正确阅读this,它的意思是“在整个CListCtrl的下方和右侧”。当我首先检查它是否在CListCtrl中时,这实际上没有任何意义。那我在某处有不正确的假设吗?我的代码不正确吗?我想念什么吗?
作为奖金问题可能相关的(或不相关的),
LVHT_ONITEMSTATEICON
和LVHT_ABOVE
都被#define
d表示为0x08-为什么?这可能是我误会的关键。 最佳答案
我认为HitTest()需要在客户坐标中定位。自从我上一次这样做以来已经有一段时间了,但是将屏幕坐标传递到客户端窗口点击测试例程对我来说没有任何意义。在m_itemList.ScreenToClient(&pos);
之前添加hitTestInfo.pt = pos;
,看看是否有帮助。
此外,请注意OnContextMenu()可能不是您要查找的 call 。 (默认情况下)shift-f10也被调用。 WM_CONTEXTMENU的文档(在对角线阅读时,我不记得它从上次执行时起是如何工作的),在这种情况下,“pos”的内容将不太清楚。您可能需要做一个明确的GetCursorPos()
来处理这种情况。或者只是在WM_RBUTTONDOWN中显示您的上下文。