0

We currently have a Silverlight UI (which we are unable to change from at this stage) for our system, which has very limited drag drop capabilities. We are currently running out of browser with elevated trust. So in order to handle Silverlight's shortcomings I have created a c++ com library in order to handle Drag Drop events. This works perfectly well for incoming events from other applications, however I'm struggling to get the Drag operations, with our app as the source, working correctly. Most of the files to be dragged from the app will be virtual, which I have managed to get working however regardless of everything I've tried I have been unable to get the operation to be asynchronous, and the app locks up during the process.

I initially implemented only the IAsyncOperation (need backward compatibility to xp), which had no apparent affect. My DataObject is queried for the interface, gets the ref. A Call to GetAsyncMode is made, which returns VARIANT_TRUE, and a call to StartOperation is made. However all operations are done on the same thread (ui thread) and no async seems to be in affect.

I Subsequently tried implementing ICallFactory to return an AsyncIDataObject. Here explorer seems to check for the ICallFactory interface, calls the CreateCall on the call object and queries it to make sure it has the correct interfaces. Using the symbol servers I am able to see that it this occurs in the AsyncStubInvoke call stack. From here a call to StdStubBuffer_QueryInterface is made which is searching for the ICallFactory interface. This check fails and I unfortunately cannot see what object is being checked for this interface. After this fails the call seems to fall back to SyncStubInvoke after an operation not supported error (following from the Interface not supported error). All of this too seems to have no effect on the end result and the call is still apparently synchronous with the source app locking up.

My DragDrop class which exposes the com calls is CComMultiThreadModel. I have tried using my DataObject as a basic class not inheriting from CComObjectRootEx and a wrapper IDataObject class which is defined in the IDL as well and does inherit from CComObjectRootEx as is also CComMultiThreadModel. I have also tried having this class inherit from IDispatch as well as IUnknown.

Any feedback would be greatly appreciated.

Matt
  • 1
  • 3
  • *"However all operations are done on the same thread (ui thread) and no async seems to be in affect."* then the **drop target** has a bad async implementation. The [documentation](https://msdn.microsoft.com/en-us/library/windows/desktop/bb776904.aspx#async) is very clear on this: "The following procedure outlines how the drop target uses the IAsyncOperation interface to extract data asynchronously: ... Call GetAsyncMode. If the method returns VARIANT_TRUE, the data object supports asynchronous data extraction. **Create a separate thread to handle data extraction** and call StartOperation..." – Remy Lebeau Feb 17 '15 at 08:34
  • Hi Remy, thanks for the feedback, however the drop target is Explorer so I don't have much ability to affect it's handling. I have also gotten my hands on a C# based implementation that use ComImport to bring in the DoDragDrop calls and the structures, and here it works perfectly fine. In the C# implementation, I can see the QueryGetData call being done twice firs for FileDrop and next for FileGroupDescriptor, after this second call explorer seems to launch a new thread a subsequent calls are all on a new thread. On the c++ side, this second call never happens. – Matt Feb 17 '15 at 08:52
  • See if [this discussion](https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/bbe470ee-55a1-452c-bc58-621ea62fed9e) helps. The main point is that the object implementing `IStream`, the one that represents actual file data, needs to be created on a worker thread and marshaled on the UI thread, where the resulting proxy gets stuffed into the data object and passed to `DoDragDrop`. Then `IStream::Read` et al will be called on the worker thread. – Igor Tandetnik Feb 17 '15 at 15:33
  • Thanks Igor, that looks very promising. – Matt Feb 20 '15 at 12:37
  • Hi Igor, I managed to get this working in explorer thanks to the above article, thanks. I am however still having issues dragging into outlook. All accessing and downloading is now happening in separate threads as required, however both outlook and the source app are still locking up. Do you possibly have any suggestions of what I might try here? – Matt Apr 09 '15 at 11:09

0 Answers0