在用户拖动列表视图项时检测何时需要滚动

Detect when scrolling is necessary while user drags listview items

简介:

我在不使用 OLE 拖放的情况下实现列表视图项目的重新排列。

问题:

我已经成功解决了大部分任务,除了滚动 up/down 当用户想要将项目放在当前不可见的位置时。

问题:

我可以使用以下消息滚动 up/down 列表视图:

SendMessage(hwndListView, WM_VSCROLL, (WPARAM)SB_LINEUP, (LPARAM)0);
SendMessage(hwndListView, WM_VSCROLL, (WPARAM)SB_LINEDOWN, (LPARAM)0);

我需要你的建议来确定何时何地 我需要发送这些消息(我想应该在 WM_MOUSEHOVER 或类似的时间完成?) .

我只是不知道在哪个消息上,以及如何,我应该检查是否需要滚动。

我有兴趣实现拖放的默认滚动行为。

我为解决这个问题所做的努力:

我曾尝试使用列表视图命中测试,因此我可以检查 LVHITTESTINFO 中的 LVHT_ABOVELVHT_BELOW,但这对我不起作用。

单击列表视图时我无法获得这些值...

我在其他编程语言中找到了一些使用定时器来实现这一点的例子。我在写这篇文章时正在研究它们 post。

附加信息:

Listview处于报表模式,支持多选。

我正在处理以下消息:

LVN_BEGINDRAG  // I create drag image here
WM_MOUSEMOVE   // I update drag image here
WM_LBUTTONUP   // I rearrange items here and perform cleanup

我省略了 SSCCE 以保持 post 简短。如果需要我可以 post 它。如果需要更多信息,请发表评论。

推测您的拖放循环使用 SetCapture 捕获鼠标输入。

您所要做的就是注意 WM_MOUSEMOVE 消息。当鼠标移动到列表视图的顶部上方或底部下方时,设置一个标志以指示您正在滚动并使用 SetTimer.

启动计时器

每次计时器关闭时,通过向列表视图发送 WM_VSCROLL 消息,向适当的方向滚动一行。

如果鼠标移回列表视图内,或者捕获丢失(即您得到 WM_CAPTURECHANGED),请停止计时器并停止滚动。