HitTest 未按预期工作
我想在用户右键单击 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
为0x08 - 这是为什么?这可能是我误解的关键。
I am wanting to display a context menu when a user right-clicks on an item within a CListCtrl. My code is as follows:
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)
}
}
}
When I actually run the code, regardless of where I click; on an item, in empty space within the CListCtrl, anywhere else on the dialog (by removing the first if statement); hitTestInfo.flags
is set to 48, which, if I'm reading this correctly, means "Below, and to the right of the whole CListCtrl". Which doesn't really make sense when I'm first checking if it's within the CListCtrl.
So do I have an incorrect assumption somewhere? Is my code incorrect? Am I missing something?
As a possibly-related, or maybe not, BONUS QUESTION, both LVHT_ONITEMSTATEICON
and LVHT_ABOVE
are #define
d as 0x08 - why is this? This may be key to my misunderstanding.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为 HitTest() 需要客户端坐标中的位置。自从我上次这样做以来已经有一段时间了,但是将屏幕坐标传递到客户端窗口命中测试例程对我来说没有意义。在
hitTestInfo.pt = pos;
之前添加m_itemList.ScreenToClient(&pos);
并查看是否有帮助。此外,请注意 OnContextMenu() 可能不是您正在寻找的调用。它也被调用以响应(默认情况下)shift-f10。 WM_CONTEXTMENU 的文档(对角阅读它时,我不记得上次执行此操作时它是如何工作的)不太清楚在这种情况下“pos”的内容是什么;您可能需要执行显式的
GetCursorPos()
来处理这种情况。或者只是在 WM_RBUTTONDOWN 中显示您的上下文。I think HitTest() needs a position in client coordinates. It's been a while since I last did this, but it doesn't make sense to me to pass screen coordinates into a client window hit testing routine. Add
m_itemList.ScreenToClient(&pos);
beforehitTestInfo.pt = pos;
and see if that helps.Furthermore, note that OnContextMenu() may not be the call you're looking for. It is called in response to (by default) shift-f10 as well. The documentation of WM_CONTEXTMENU is (on reading it diagonally, I don't remember how it works from when I last did this) not very clear on what the content of 'pos' will be in that case; you may need to do an explicit
GetCursorPos()
to handle that case. Or just show your context in WM_RBUTTONDOWN.我对列表控制的
HitTest
遇到了类似的问题。它具有返回项目 0 和 LVHT_ONITEM 标志的模糊效果
即使点击发生在标题上。人们期望项目为 -1
索引和标志的
LVHT_NOWHERE
。我通过使用标头控件的
HitTest
解决了这个问题。具体方法如下:I had similar problem with
HitTest
for list control.It has obscure effect of returning item 0 and
LVHT_ONITEM
flageven if click occurs on the header. One would expect -1 for item
index and
LVHT_NOWHERE
for a flag.I resolved this by using
HitTest
of header control. Here is how: