listview hittesting不正确 [英] Incorrect listview hittesting

查看:89
本文介绍了listview hittesting不正确的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

简介:



我想确定用户是否点击了项目或上方/下方列表视图。



Listview处于报告模式,具有扩展样式全行选择和网格线。



问题:



我无法获得正确的结果,基于LVHITTESTINFO的文档。



我努力解决问题:



我的复选框的标题与我主窗口中LVHITTESTINFO的值相同。



这些是LVHT_ABOVE,LVHT_BELOW,LVHT_NOWHERE,LVHT_TOLEFT, LVHT_TORIGHT和LVHT_ONITEM。



我的目标是检查与测试结果相同的标题。



我已经在主窗口中捕获鼠标以响应WM_LBUTTONDOWN并在WM_LBUTTONUP处理程序中进行了测试。



这是最简单的方法我可以在这里编写最小的SSCCE /代码片段。



以下是相关代码:

INTRODUCTION:

I am trying to determine if user clicked on item or above/below listview.

Listview is in report mode, with extended styles full row select and grid lines.

PROBLEM:

I am not able to get correct results, based on the docs for LVHITTESTINFO.

MY EFFORTS TO SOLVE THE PROBLEM:

I have made checkboxes with same caption as the values in LVHITTESTINFO in my main window.

These are LVHT_ABOVE, LVHT_BELOW, LVHT_NOWHERE, LVHT_TOLEFT, LVHT_TORIGHT and LVHT_ONITEM.

My goal is to check the ones with same caption as returned result from hittesting.

I have captured the mouse in my main window in response to WM_LBUTTONDOWN and am doing the hittesting in WM_LBUTTONUP handler.

This was the easiest way for me to code the smallest SSCCE/code snippets that can be posted here.

Here is the relevant code:

case WM_LBUTTONDOWN:
    // reset checkboxes
    CheckDlgButton(hWnd, 3000, BST_UNCHECKED);
    CheckDlgButton(hWnd, 3100, BST_UNCHECKED);
    CheckDlgButton(hWnd, 3200, BST_UNCHECKED);
    CheckDlgButton(hWnd, 3300, BST_UNCHECKED);
    CheckDlgButton(hWnd, 3400, BST_UNCHECKED);
    CheckDlgButton(hWnd, 3500, BST_UNCHECKED);
    // capture the mouse
    SetCapture(hWnd);
    break;
case WM_LBUTTONUP:
{
    // extract coordinates
    POINT pt = { 0 };
    pt.x = GET_X_LPARAM(lParam);
    pt.y = GET_Y_LPARAM(lParam);
    // do the hittesting
    ClientToScreen(hWnd, &pt);
    ScreenToClient(GetDlgItem(hWnd, 2000), &pt);

    LVHITTESTINFO lvhti = { 0 };
    lvhti.pt = pt;

    ListView_HitTest(GetDlgItem(hWnd, 2000), &lvhti);
    // check appropriate checkboxes
    if ((lvhti.flags & LVHT_ABOVE) == LVHT_ABOVE)
        CheckDlgButton(hWnd, 3000, BST_CHECKED);
    if ((lvhti.flags & LVHT_BELOW) == LVHT_BELOW)
        CheckDlgButton(hWnd, 3100, BST_CHECKED);
    if ((lvhti.flags & LVHT_NOWHERE) == LVHT_NOWHERE)
        CheckDlgButton(hWnd, 3200, BST_CHECKED);
    if ((lvhti.flags & LVHT_ONITEM) == LVHT_ONITEM)
        CheckDlgButton(hWnd, 3300, BST_CHECKED);
    if ((lvhti.flags & LVHT_TOLEFT) == LVHT_TOLEFT)
        CheckDlgButton(hWnd, 3400, BST_CHECKED);
    if ((lvhti.flags & LVHT_TORIGHT) == LVHT_TORIGHT)
        CheckDlgButton(hWnd, 3500, BST_CHECKED);
    // release mouse capture
    ReleaseCapture();
}
    break;



测试原则:



测试按以下方式完成:我点击主窗口客户区,按住鼠标左键,然后将光标拖到项目/上方(或下方)列表视图上。然后我发布调用WM_LBUTTONUP消息的按钮,并检查相应的复选框。



测试结果:



< b>在Windows 7上测试



*在项目的第一个子项目上释放鼠标左键时,不会检查任何内容。



*当在项目的第二个(第三个等)子项目复选框上释放鼠标左键时,检查LVHT_ABOVE和LHVT_ONITEM。



*当释放按钮外listview我正确得到LVHT_NOWHERE。



*当在滚动条上释放按钮时我得到了LVHT_NOWHERE。



*当释放上面的标题控件的第一列我没有得到任何检查,但对于其他列我得到LVHT_ONITEM和LVHT_ABOVE。



在Windows XP上测试



*当在项目的第一个子项目上释放鼠标左键时,不会检查任何内容。



*释放鼠标左键时OV检查项目的第二个(第三个等)子项目复选框LVHT_ABOVE和LHVT_ONITEM。



*当在listview之外释放按钮时,我得到LVHT_ABOVE / LVHT_BELOW和LVHT_TOLEFT /的正确组合LVHT_TORIGHT。



*当在滚动条上释放按钮时,垂直方向的LVHT_TORIGHT和水平滚动条的LVHT_BELOW。



*当释放上面的标题控件时,我得到不一致的行为:当在标题项的最顶部释放时,我得到LVHT_NOWHERE,但在其他情况下,它的行为与我上面描述的相同(对于Windows 7)。



重要提示:



通过互联网搜索,我发现LVHT_ABOVE和LVHT_ONITEMSTATEICON已经有了相同的价值。这意味着我必须解释测试结果,其中LVHT_ABOVE和LVHT_ONITEM为LVHT_ONITEM。



调试时,我发现在第一列或第一列上方释放鼠标按钮时item给出了mask 4,意思是我得到LVHT_ONITEMLABEL而不是LVHTI_ONITEM。



问题:



如何调整上述代码以获得正确的测试结果?



如果我的问题的解决方案是复杂,需要太多的空间和精力让你发布,我会满意的说明和指导或至少一些链接指向我正确的方向。



如果需要进一步的信息,我会更新我的帖子。


TESTING PRINCIPLE:

Testing is done in the following way: I click on main windows client area, hold left mouse button down, and drag cursor over item/above (or below) listview. Then I release button which invokes WM_LBUTTONUP message and appropriate checkboxes get checked.

TESTING RESULTS:

Tested on Windows 7

* When releasing left mouse button over item's first subitem nothing is checked.

* When releasing left mouse button over item's second ( third, etc ) subitem checkboxes LVHT_ABOVE and LHVT_ONITEM are checked.

* When releasing button outside of listview I correctly get LVHT_NOWHERE.

* When releasing button over scrollbars I get LVHT_NOWHERE.

* When releasing above header control's first column I get nothing checked, yet for other columns I get LVHT_ONITEM and LVHT_ABOVE.

Tested on Windows XP

* When releasing left mouse button over item's first subitem nothing is checked.

* When releasing left mouse button over item's second ( third, etc ) subitem checkboxes LVHT_ABOVE and LHVT_ONITEM are checked.

* When releasing button outside of listview I get correct combination of LVHT_ABOVE/LVHT_BELOW and LVHT_TOLEFT/LVHT_TORIGHT.

* When releasing button over scrollbars I get LVHT_TORIGHT for vertical, and LVHT_BELOW for horizontal scrollbar.

* When releasing above header control I get inconsistent behavior: When releasing at the very top of the header's item I get LVHT_NOWHERE, yet in other cases it behaves as same as I have described above ( for Windows 7 ).

Important:

Searching through Internet, I have found out that LVHT_ABOVE and LVHT_ONITEMSTATEICON have the same value. This means that I must interpret testing results where I got LVHT_ABOVE and LVHT_ONITEM as LVHT_ONITEM.

While debugging, I have found out that when releasing mouse button above first column or first item gives mask 4, meaning I get LVHT_ONITEMLABEL instead of LVHTI_ONITEM.

QUESTION:

How can I adjust the above code to get correct hittesting results?

If the solution to my problem is complex and requires too much space and effort for you to post, I will be satisfied with instructions and guidelines or atleast some links that point me in the right direction.

If further info is required I will update my post.

推荐答案

我猜你还在继续努力。删除实现并需要检查数据是否可以删除(在项目上)或滚动应该执行。

I guess you are still working on your drag & drop implementation and need to check if data can be dropped (over an item) or scrolling should be performed.
Quote:

我正在尝试确定用户是否点击了项目或列表视图上方/下方。

I am trying to determine if user clicked on item or above/below listview.

因为您的列表处于报告模式,我会使用 ListView_SubItemHitTest [ ^ ]。如果返回值>> = 0,则您在(子)项或标题上, iItem iSubItem 信息成员已设置。当 pt.y 小于或等于标题客户端rect的底部位置时,您已超过标题(信息的 iItem 成员在这种情况下为零)。



当返回值为负数(-1)时,当 pt 位于客户端rect内。否则你在列表窗口之外(包括滚动条)。



要检查是否通过滚动条使用 GetScrollBarInfo [ ^ ]。这将为您提供滚动条(箭头,拇指),滚动条处于活动状态且实际可见的信息,以及可能的滚动方向。

Because your list is in report mode, I would use ListView_SubItemHitTest[^] instead. If the return value is >= 0, you are over a (sub)item or the header and the iItem and iSubItem info members are set. You are over the header when pt.y is less or equal to the bottom position of the header's client rect (the info's iItem member is zero in this case).

When the return value is negative (-1), you are over the empty list space when pt is inside the client rect. Otherwise you are outside the list window (which includes the scroll bars).

To check if over a scroll bar use GetScrollBarInfo[^]. This will give you also information where over the scroll bar (arrows, thumb), if the scroll bar is active and actually visible, and the possible scroll directions.


这篇关于listview hittesting不正确的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆