Skip to content

System.Runtime.InteropServices.ComTypes.IDataObject vs Windows.Win32.System.Com.IDataObject #1673

@xeonix

Description

@xeonix

Is your feature request related to a problem? Please describe.
Hello guys.
I'm having issue with implementing Drag&Drop in WPF for .NET 9, using IDropTargetHelper.
The problem is with DragEnter event handler.

public partial class MyWindow {
...
  Windows.Win32.UI.Shell.IDropTargetHelper _dropTargetHelper = Activator.CreateInstance(Type.GetTypeFromCLSID(PInvoke.CLSID_DragDropHelper)!) as Windows.Win32.UI.Shell.IDropTargetHelper;
...

  private void MainWindow_DragEnter(object sender, DragEventArgs e)
  {
    ...
    var pointWpf = e.GetPosition(this);
    var point = new System.Drawing.Point(Convert.ToInt32(pointWpf.X), Convert.ToInt32(pointWpf.Y));
    _dropTargetHelper?.DragEnter(HWnd,

    //here's the issue, it always results into null:
    e.Data as Windows.Win32.System.Com.IDataObject,

    in point, (Windows.Win32.System.Ole.DROPEFFECT)e.Effects);
}
...

Here, e.Data implements interface System.Runtime.InteropServices.ComTypes.IDataObject while Windows.Win32.UI.Shell.IDropTargetHelper expects it's own Windows.Win32.System.Com.IDataObject.
And even thought these both IDataObject are the same, there's no way to cast them, as .NET-wise, they are completely different interfaces.
And for PInvoke, CsWin32 does use System.Runtime.InteropServices.ComTypes.IDataObject.
For example, when adding SHCreateShellItemArrayFromDataObject to NativeMethods.txt, PInvoke.SHCreateShellItemArrayFromDataObject expects System.Runtime.InteropServices.ComTypes.IDataObject.
Therefore, it looks like the issue is scoped to COM interop only.

Describe the solution you'd like
When generating something that uses IDataObject, use System.Runtime.InteropServices.ComTypes.IDataObject instead.
Or provide a way to configure mapping in NativeMethods.txt, something like

CLSID_DragDropHelper
IDropTargetHelper
IDataObject=System.Runtime.InteropServices.ComTypes.IDataObject

Describe alternatives you've considered
Don't use CsWin32 in favor of plain, manually crafted COM interop.
Things like Marshal.QueryInterface/Marshal.GetComInterfaceForObject/Marshal.GetObjectForIUnknown or Unsafe.As didn't work.

Additional context
Add any other context or screenshots about the feature request here.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions