当用户右键单击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 - 为什么会这样?这可能是我误解的关键。
答案 0 :(得分:4)
我认为HitTest()在客户端坐标中需要一个位置。自从我上次这样做以来已经有一段时间了,但是将屏幕坐标传递到客户端窗口命中测试程序是没有意义的。在m_itemList.ScreenToClient(&pos);
之前添加hitTestInfo.pt = pos;
,看看是否有帮助。
此外,请注意OnContextMenu()可能不是您正在寻找的呼叫。响应(默认情况下)shift-f10也会调用它。 WM_CONTEXTMENU的文档是(在对角线阅读时,我不记得它从我上次这样做起的时候是如何工作的)在这种情况下“pos”的内容不是很清楚;你可能需要做一个明确的GetCursorPos()
来处理这种情况。或者只是在WM_RBUTTONDOWN中显示您的上下文。
答案 1 :(得分:1)
我对HitTest
的列表控件有类似的问题。
它具有返回项0和LVHT_ONITEM
标志的模糊效果
即使标题上发生了点击。人们会期望-1为项目
索引和LVHT_NOWHERE
标志。
我通过使用HitTest
标头控件解决了这个问题。方法如下:
UINT uFlags = 0;
CHeaderCtrl* pHdr = m_list.GetHeaderCtrl();
if (!pHdr) return; // sanity
HDHITTESTINFO hitTestInfo = {0};
hitTestInfo.pt = ptClient;
int iItem = pHdr->HitTest(&hitTestInfo);
if ((iItem != -1) && ((HHT_ONHEADER | HHT_ONDIVIDER) & hitTestInfo.flags)) {
// this is header control menu
CWnd::OnContextMenu(pWnd, point);
}
else if (HHT_BELOW & hitTestInfo.flags) {
CXTMenu Menu;
// this is list view control menu
if (Menu.LoadMenu(IDR_LIST_CONTEXT)) {
...
}
}