我正在使用Windows API创建一个只有窗口的应用程序,因此这个窗口中的所有内容都是使用Direct2D绘制的 .
现在我想删除窗口特定部分的一些文件's client area, and I' m处理消息 WM_DROPFILES
. 这里没问题,当文件被丢弃在那些特定区域时,我可以正确对待它们并且一切正常 . 顺便说一句,我的窗口是 DragAcceptFiles(hWnd, true)
,它总是接受拖放 .
我希望鼠标光标不同,具体取决于鼠标所在窗口的区域 . 在我不处理丢弃的区域,我希望光标是无效图标,对于窗口区域,我确实处理掉落,我想要正确的放置图标 .
我注意到的第一件事是当文件被拖入窗口时没有生成消息,因此我添加了一个鼠标钩子( WH_MOUSE_LL
使用 SetWindowsHookEx
) . 处理钩子时,我只查看 WM_MOUSEMOVE
消息,因此我可以根据鼠标所在的区域更改光标 .
问题是 SetCursor
什么也没做,如果我的windows配置为接受拖动文件,则无论我多少次调用 SetCursor
,光标始终是拖放光标 .
用这种方式改变光标似乎是不可能的,但还有其他方法可以实现我想要实现的目标吗?
1 回答
您需要在代码中编写一个实现IDropTarget接口的类,然后创建该类的实例并将其传递给RegisterDragDrop()以将其与您的窗口关联 . 不要再使用
DragAcceptFiles()
了 .每当用户在窗口上拖动任何内容(不仅仅是文件)时,都会相应地调用
IDropTarget::DragEnter()
和IDropTarget::DragOver()
,IDropTarget::DragLeave()
方法,为您提供拖动的当前坐标和有关被拖动数据的信息(这样您就可以过滤掉任何数据了不想接受) . 如果您选择接受数据,并且用户实际将数据丢弃到您的窗口,则会调用IDropTarget::Drop()
方法 .作为放置目标,更改光标的责任是 not . 根据需要,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