views:

250

answers:

4

I wonder if anyone knows if there's any way to start OLE file drag from a C++ Win32 application without blocking until the drag completed.

I'm currently using DoDragDrop() to start the drag operation, but this function doesn't return until the drag operation is completed. The problem with this is that the animation in my program halts while a drag is in progress.

I tried to launch this command from a new thread, but that didn't work, even if I called OleInitialize() in this thread.

The only thing I found that was related to this is doing the data operation afterwards (such as copying/moving the file/data) asynchronously. In my application drag&drop is not used for such operations, so it isn't an issue, and the main issue is the block while the user is performing the drag. Edit: To be more clear about this: IAsyncOperation on the DataObject isn't a solution to this problem, because it only makes the operation occuring after the data has been dropped assynchronous. The problem I have is the blocking behavior from the point where the user starts dragging until the moment he releases the mouse button.

2 solutions do come to mind, but I hope there will be an easier or better way to achieve this.

  1. Implement my own (non-ole) drag&drop. This would be more work to do, and I actually found it a nice feature that it was possible to drag files from within my program to other programs as well.

  2. Create/launch a new process and start the drag operation from there. Since I have no problems when dragging a file from windows explorer inside my application, I think this might work. The drag should start immediately though, and I have no idea if creating a new process takes any noticeable time.

A: 

I've run into this. I would spin up a new thread and do this. CreateProcess does take time, but probably not a lot. You could always create the thread or process ahead of time and synchronize it so it blocks right before a call to DoDragDrop(), then unblock it from the main application.

kbyrd
+2  A: 

If your IDataObject supports the IAsyncOperation interface, then the IDropTarget will have the option of allowing IDropTarget::Drop() exit quickly and then perform the actual transfer asynchronously. However, the IDropTarget is not required to support IAsyncOperation.

This behavior is described in MSDN's documentation. Also, DoDragDrop() will not exit until the user releases the mouse to initiate the drop either way, so your thread that calls DoDragDrop() will still be blocked while the user is dragging the mouse around.

Remy Lebeau - TeamB
+1  A: 

Remy's answer is correct. There is also a set of blog posts from the The Old New Thing about implementing IDataObject's. It doesn't go into IAsyncOperation but it's a start.

Shane Powell
+1  A: 

Run your animation in a separate thread.

CannibalSmith