HitTest按预期工作
我想在用户右键单击CListCtrl中的项目时显示上下文菜单。我的代码如下:HitTest按预期工作
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()需要在客户端坐标中的位置。自从我上次做这件事以来已经有一段时间了,但将屏幕坐标传递到客户端窗口命中测试例程是没有意义的。在hitTestInfo.pt = pos;
之前加m_itemList.ScreenToClient(&pos);
,看看是否有帮助。
此外,请注意OnContextMenu()可能不是您正在寻找的调用。它被调用以响应(默认)shift-f10。 WM_CONTEXTMENU的文档(在对角地阅读它时,我不记得它是如何工作的,从我上次做的时候开始)不太清楚在这种情况下'pos'的内容是什么;你可能需要做一个明确的GetCursorPos()
来处理这种情况。或者只是在WM_RBUTTONDOWN中显示你的上下文。
我有类似的问题,HitTest
列表控制。 即使在标题上发生点击,它也会影响返回项目0和LVHT_ONITEM
标志 。对于一个标志,人们可以预期项目 index和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)) {
...
}
}
非常感谢!我还会研究WM_RBUTTONDOWN事情 - 你说得对,它导致上下文菜单显示不正确。 – Smashery 2010-01-15 00:42:35
如果只有我可以投你两次:-) – Smashery 2010-01-15 00:54:54
Pos的传递给OnContextMenu将(-1,-1)我相信,在Shift-F10或专用菜单键的情况下。 – 2013-12-17 22:00:09