views:

196

answers:

2

Hi all,

I'm doing a Drag Drop to external app like this:

string[] files = new string[/* */];

// get files

DataObject o = new DataObject(DataFormats.FileDrop, files);
DoDragDrop(o, DragDropEffects.Copy | DragDropEffects.Move);

and some apps will take the files and move on to process them and my app is free to do it's stuff, but some apps will make MY app freeze until it processess all the files... is there any way I can go around that? I've tried to do it in a Thread but that didn't work so well - it didn't work at all... so, any suggestions how to make this code do not hang my app?

+2  A: 

the .NET Control.DoDragDrop is just a wapper around the Win32 api called.. (wait for it).. DoDragDrop

So it has the same limitations. DoDragDrop can only be called from a thread that has called OleInitialize, which makes the thread a STA (Single Threaded Apartment) type thread.

Because it can only be used by an STA thread, and the API design is synchronous, you are at the mercy of the destination applications' handling of drop notifications. This is just part of the design of OLE Drag and Drop and cant be changed. (OLE Drag and drop was actually designed in the Windows 3x days, before threads even existed in windows applications).

So, you could maybe make this work on another thread IFF that thread is a STA thread. You would also probably have to use interop to call the unmanaged DoDragDrop function.

John Knoeller
Hmm, that is interesting and I bet that you are right, but that doesn't solve the problem ;) I mean... I do not need to run DoDragDrop async... all I need to do is to have the part of exchanging the data to be async... I read somewhere that the DataObject would have to implement some async interface but I can't find it now... Do you maybe know where I could find the 'place' where my app exchanges the data with the other app? (using DoDragDrop ofc)
argh
The data exchange part is inside DoDragDrop, so if you want the data exachange to be async, then you have to put DoDragDrop on another thread. and it must be an STA thread. Do you know how to force a thread to be STA in .NET?
John Knoeller
Well... correct me if I'm wrong but if I've got:[STAThread]static void Main(string[] parameters)then it's being run in STA Thread, right?
argh
Yep, thats how you get STA for the main thread.
John Knoeller
Tired that... no luck :( (maybe I've done something wrong). Isn't there another way? I've read something about DataObject implementing some asnyc interface?
argh
@argh: sorry, I don't know anything about that. Raymond Chen has written about implementing drag drop in his blog, you could try looking at that (C++ not C# though) http://blogs.msdn.com/oldnewthing/
John Knoeller
A: 

It will always freeze, but the delay isn't noticeable with small files. Check out this answer.

modosansreves