将文件拖入窗口时将SetCursor设置为

时间:2013-09-17 17:46:39

标签: c++ winapi drag-and-drop cursor

我正在使用Windows API创建一个只有窗口的应用程序,因此这个窗口中的所有内容都是使用Direct2D绘制的。

现在我想删除窗口客户区特定部分的一些文件,我正在处理消息WM_DROPFILES。这里没问题,当文件被丢弃在那些特定区域时,我可以正确对待它们并且一切正常。顺便说一句,我的窗口是DragAcceptFiles(hWnd, true),它总是接受拖放。

我希望鼠标光标不同,具体取决于鼠标所在窗口的区域。在我不处理掉落的区域,我希望光标是无效图标,对于以下区域:我处理掉落的窗口,我想要正确的放置图标。

我注意到的第一件事是当文件被拖入窗口时没有生成消息,因此我添加了一个鼠标钩子(WH_MOUSE_LL使用SetWindowsHookEx)。处理钩子时,我只查看WM_MOUSEMOVE消息,因此我可以根据鼠标所在的区域更改光标。

问题是SetCursor什么都不做,如果我的窗口配置为接受拖动文件,则无论我调用SetCursor多少次,光标始终是拖放光标。< / p>

似乎不可能以这种方式改变光标,但还有其他方法可以实现我想要实现的目标吗?

1 个答案:

答案 0 :(得分:4)

您需要在代码中编写一个实现IDropTarget接口的类,然后创建该类的实例并将其传递给RegisterDragDrop()以将其与您的窗口关联。不要再使用DragAcceptFiles()

每当用户在您的窗口上拖动任何内容(而不仅仅是文件)时,系统会相应调用IDropTarget::DragEnter()IDropTarget::DragOver()IDropTarget::DragLeave()方法,为您提供拖动的当前坐标和有关被拖动数据的信息(因此您可以过滤掉您不想接受的任何数据)。如果您选择接受数据,并且用户实际将数据删除到您的窗口,则会调用IDropTarget::Drop()方法。

作为放弃目标,您有责任 更改光标。根据需要,drop source负责处理。在IDropTarget::DragEnter()IDropTarget::DragOver()实现中,您需要做的就是将pdwEffect输出参数设置为适当的DROPEFFECT值。该值将传递回drop source,然后在IDropSource::GiveFeedback()实现中向用户显示视觉反馈(如更改光标)。

可以在没有用户交互的情况下调用IDropTarget(即,可以从其他应用程序进行编程,而不仅仅是拖放操作)。这就是为什么drop source而不是drop target决定是否向用户显示UI更新的原因,因为只有drop source才知道它为什么首先调用你的IDropTarget。放置目标不知道(或关心)它被调用的原因,只是给它一些数据,并询问它是否会接受或拒绝该数据,仅此而已。

有关详细信息,请参阅MSDN:

OLE and Data Transfer

Transferring Shell Objects with Drag-and-Drop and the Clipboard