我正在使用Windows API创建一个只有窗口的应用程序,因此这个窗口中的所有内容都是使用Direct2D绘制的。
现在我想删除窗口客户区特定部分的一些文件,我正在处理消息WM_DROPFILES
。这里没问题,当文件被丢弃在那些特定区域时,我可以正确对待它们并且一切正常。顺便说一句,我的窗口是DragAcceptFiles(hWnd, true)
,它总是接受拖放。
我希望鼠标光标不同,具体取决于鼠标所在窗口的区域。在我不处理掉落的区域,我希望光标是无效图标,对于以下区域:我处理掉落的窗口,我想要正确的放置图标。
我注意到的第一件事是当文件被拖入窗口时没有生成消息,因此我添加了一个鼠标钩子(WH_MOUSE_LL
使用SetWindowsHookEx
)。处理钩子时,我只查看WM_MOUSEMOVE
消息,因此我可以根据鼠标所在的区域更改光标。
问题是SetCursor
什么都不做,如果我的窗口配置为接受拖动文件,则无论我调用SetCursor
多少次,光标始终是拖放光标。< / p>
似乎不可能以这种方式改变光标,但还有其他方法可以实现我想要实现的目标吗?
答案 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:
Transferring Shell Objects with Drag-and-Drop and the Clipboard