将文件拖到窗口中时的SetCursor [英] SetCursor while dragging files into a window

查看:78
本文介绍了将文件拖到窗口中时的SetCursor的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Windows API创建仅具有窗口的应用程序,因此该窗口中的所有内容均使用Direct2D绘制.

I'm using windows API to create an application with a window only, so everything inside this window is drawn using Direct2D.

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

Now I want to drop some files in specific parts of my window's client area, and I'm handling the message WM_DROPFILES. No problem here, when the files are dropped in those specific areas, I can treat them correctly and everything is working properly. BTW, my window is DragAcceptFiles(hWnd, true), it always accepts drag/drops.

我希望鼠标光标根据鼠标所在的窗口区域而有所不同.在我不处理拖放的区域中,我希望光标是无效的图标,并且对于在我处理下拉菜单的窗口中,我想要正确的下拉图标.

I want the mouse cursor to be different depending on the area of the window the mouse is in. In the areas that I don't treat the drop, I want the cursor to be the invalid icon, and for the areas of the window that I do handle the drops, I want the correct drop icon.

我注意到的第一件事是,将文件拖到窗口中时不会生成任何消息,因此,我使用 SetWindowsHookEx 添加了一个鼠标钩( WH_MOUSE_LL ).处理挂钩后,我只会查看 WM_MOUSEMOVE 消息,因此可以根据鼠标所在的区域来更改光标.

The first thing I noticed is that no message is generated when files are being dragged into the window, and for this reason I added a mouse hook (WH_MOUSE_LL using SetWindowsHookEx). When the hook is processed, I only look at the WM_MOUSEMOVE message, so I can change the cursor according to the area the mouse is in.

问题是 SetCursor 不执行任何操作,如果我的Windows配置为接受拖动文件,则无论我调用 SetCursor多少次,光标始终是拖放光标.

The problem is that the SetCursor does nothing, if my windows is configured to accept drag files, the cursor is always the drag/drop cursor, no matter how many times I call SetCursor.

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

It seems impossible to change the cursor this way, but is there any other way of doing what I'm trying to achieve?

推荐答案

您需要在代码中编写一个实现 IDropTarget 接口,然后创建该类的实例并将其传递给

You need to write a class in your code that implements the IDropTarget interface, then create an instance of that class and pass it to RegisterDragDrop() to associate it with your window. Do not use DragAcceptFiles() anymore.

每当用户在窗口上拖动任何内容(不仅仅是文件)时,您的 IDropTarget :: DragEnter() IDropTarget :: DragOver() IDropTarget:: DragLeave()方法将被相应调用,为您提供拖动的当前坐标以及有关被拖动数据的信息(以便您可以过滤出任何您不希望接受的数据).如果您选择接受数据,并且用户实际上将数据拖放到窗口上,则将调用您的 IDropTarget :: Drop()方法.

Whenever the user drags anything (not just files) over your window, your IDropTarget::DragEnter() and IDropTarget::DragOver(), IDropTarget::DragLeave() methods will be called accordingly, giving you the current coordinates of the drag and information about the data being dragged (so you can filter out any data you don't want to accept). If you choose to accept the data, and the user actually drops the data onto your window, your IDropTarget::Drop() method will be called.

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

As the drop target, it is not your responsibility to change the cursor. It is the responsibility of the drop source instead to handle that as needed. In your IDropTarget::DragEnter() and IDropTarget::DragOver() implementations, all you need to do is set the pdwEffect output parameter to an appropriate DROPEFFECT value. That value gets passed back to the drop source, which then displays visual feedback to the user (like changing the cursor) in its IDropSource::GiveFeedback() implementation.

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

It is possible for your IDropTarget to be invoked without user interaction (ie, programmably from another apps, and not just for drag&drop operations). That is why the drop source, not the drop target, decides whether or not to display UI updates to the user, since only the drop source knows why it is invoking your IDropTarget in the first place. The drop target does not know (or care) why it is being invoked, only that it is being given some data and asked whether it will accept or reject that data, nothing more.

有关更多详细信息,请参考MSDN:

Refer to MSDN for more details:

OLE和数据传输

使用拖放和剪贴板传输外壳对象

这篇关于将文件拖到窗口中时的SetCursor的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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