C++ to C# - Dragging nightmare
-
Ok - here's the story: c++ supports a coclass (
CLSID_DragDropHelper
) with 2 interfaces;IDropTargetHelper
andIDropSourceHelper
. TheIDropTargetHelper
has 4 methods,DragEnter, DragLeave, DragOver and Drop
. Calling these methods is what gives c++ the ability to display a drag image created by the shell. In other words, you can drag from Windows Explorer and your form/control will display the drag image. C#, on the other hand, doesn’t have the ability to do this natively. I’ve found an old VB6 project that allows anything with a valid Windows handle to be subclassed, thereby supporting the Explorer drag image. I created an RCW (Runtime Callable Wrapper) of the project's ATL library and attempted to get the same effect in c#. Sadly, I could not get it to work. Something that VB’s internals hide from developers allows the subclassing to work, and I have no idea how to get it to work in c# (seems like an OLE problem??) I would be grateful if anyone can make the following VB6 project work with either c# or vb.net: Download the project at: http://www.glimt.dk/code/clipx.zip (Run the project and drag something from Explorer over the Drag/Clip button) More info can be found on MSDN: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwui/html/ddhelp_pt1.asp -
Ok - here's the story: c++ supports a coclass (
CLSID_DragDropHelper
) with 2 interfaces;IDropTargetHelper
andIDropSourceHelper
. TheIDropTargetHelper
has 4 methods,DragEnter, DragLeave, DragOver and Drop
. Calling these methods is what gives c++ the ability to display a drag image created by the shell. In other words, you can drag from Windows Explorer and your form/control will display the drag image. C#, on the other hand, doesn’t have the ability to do this natively. I’ve found an old VB6 project that allows anything with a valid Windows handle to be subclassed, thereby supporting the Explorer drag image. I created an RCW (Runtime Callable Wrapper) of the project's ATL library and attempted to get the same effect in c#. Sadly, I could not get it to work. Something that VB’s internals hide from developers allows the subclassing to work, and I have no idea how to get it to work in c# (seems like an OLE problem??) I would be grateful if anyone can make the following VB6 project work with either c# or vb.net: Download the project at: http://www.glimt.dk/code/clipx.zip (Run the project and drag something from Explorer over the Drag/Clip button) More info can be found on MSDN: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwui/html/ddhelp_pt1.aspDon't interop the VB6 project - that's a waste (requires two phases of marshaling for a one-way call and requires extra DLLs/OCXs that need to be registered). Declare the COM interfaces in C# (as I mentioned to you before) along with a skeleton implementation with the same GUID as the CLSID_DragDropHelper. You can then use
Activator.CreateComInstanceFrom
and instantiate the COM coclass but treat it as the skeleton type you created. Now your C# code is directly using the COM coclass provided by the shell. If you need to passHWND
s, then useControl.Handle
(like your mainForm
'sHandle
property). ThatIntPtr
(native-size integer) is yourHWND
for thatControl
.Microsoft MVP, Visual C# My Articles
-
Don't interop the VB6 project - that's a waste (requires two phases of marshaling for a one-way call and requires extra DLLs/OCXs that need to be registered). Declare the COM interfaces in C# (as I mentioned to you before) along with a skeleton implementation with the same GUID as the CLSID_DragDropHelper. You can then use
Activator.CreateComInstanceFrom
and instantiate the COM coclass but treat it as the skeleton type you created. Now your C# code is directly using the COM coclass provided by the shell. If you need to passHWND
s, then useControl.Handle
(like your mainForm
'sHandle
property). ThatIntPtr
(native-size integer) is yourHWND
for thatControl
.Microsoft MVP, Visual C# My Articles
Heath, I appreciate you trying to help, but you're missing the boat here. It's not shell programming/COM interfacing I'm having a problem with. I can't find the GUIDs for the helper class or the interface definitions. I can't declare the com interface without the GUIDs, and I can't stub out the interfaces without knowing how the COM interface looks. Since I found a pre-existing project I was looking to port the implementation to c# using a wrapper for the library. I wasn't trying to interop vb6 code. If I had the GUIDs and interfaces (or could find them) I never would have posted this or my previous post in the first place......
-
Heath, I appreciate you trying to help, but you're missing the boat here. It's not shell programming/COM interfacing I'm having a problem with. I can't find the GUIDs for the helper class or the interface definitions. I can't declare the com interface without the GUIDs, and I can't stub out the interfaces without knowing how the COM interface looks. Since I found a pre-existing project I was looking to port the implementation to c# using a wrapper for the library. I wasn't trying to interop vb6 code. If I had the GUIDs and interfaces (or could find them) I never would have posted this or my previous post in the first place......
That's a simple problem, and that VB control won't help you. Download and install the Platform SDK if you don't have it already. Search for the GUIDs. I personally use GViM (Graphics VI iMproved) with a tags file created for each INCLUDE. This makes it fast to find things like this. The interfaces you mentioned are documented in the Platform SDK, and you can always look at their declaration in the header files (which gives you the order of methods so you can get the VTBL order right for
IUnknown
-inheritted or dual interfaces. I do it all the time with poorly documented interfaces or to find orders or to find the pre-proc defs or GUIDs for anything.Microsoft MVP, Visual C# My Articles