1

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

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.

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.

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?

4

1 回答 1

4

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

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

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

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

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

OLE 和数据传输

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

于 2013-09-17T20:07:54.090 回答