HitTest没有按预期工作

时间:2010-01-14 04:31:54

标签: c++ mfc clistctrl

当用户右键单击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_ONITEMSTATEICONLVHT_ABOVE都是#define d为0x08 - 为什么会这样?这可能是我误解的关键。

2 个答案:

答案 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)) {
...
    }
}