Skip to content

DataTransferManager and Share API #970

Closed

Description

@Marv51

Describe the bug
In WinUI 2 I had a "Share" functionality to share an image with Windows 10 system APIs. DataTransferManager has an event called DataRequested that you need to subscribe to that makes this work.

In WinUI3 with CsWinRT this is pretty difficult, because you need to get your `DataTransferManager from IDataTransferManagerInterop, like this:

using Windows.ApplicationModel.DataTransfer;
using Windows.Win32.UI.Shell;

var guid = Guid.Parse("a5caee9b-8708-49d1-8d36-67d25a8da00c");
var iop = DataTransferManager.As<IDataTransferManagerInterop>();
var manager = iop.GetForWindow(GetMainHwnd(), guid);
var dtm = manager as DataTransferManager; // cast is always null here, I believe manager should be cast to an interface, but no interface for DataTransferManager exists.

However, it is unclear to me how to use that returned object. I can't cast to a DataTransferManager, maybe because that would only work with an interface? But DataTransferManager does not have any interface in the API docs.

I'm getting the IDataTransferManagerInterop from CsWin32, I asked on their repo, but no solution could be found.

Is this a projection issue with CsWinRT, or should I be asking somewhere else?

Activity

  1. angelazhangmsft commented on Aug 19, 2021

    @angelazhangmsft
    Contributor

    Marvin Rühe (@Marv51) there are details in #966 that may help with this scenario. You will need to do something like the following, where eventArg is the DataTransferManager object instead.

    var args = SomeEventArgType.FromAbi(((IInspectable)eventArg).ThisPtr);
  2. Marv51 commented on Aug 20, 2021

    @Marv51
    Author

    angelazhangmsft Thank you so much! Unfortunately, when I cast to IInspectable I get an InvalidCastException.

    Could this be happening, because in CsWin32 the object is marshalled as IUnknown?

    [Guid("3A3DCD6C-3EAB-43DC-BCDE-45671CE800C8"),InterfaceType(ComInterfaceType.InterfaceIsIUnknown),ComImport()]
    public interface IDataTransferManagerInterop 
    {
      [return: MarshalAs(UnmanagedType.IUnknown)]
      unsafe object GetForWindow(win32.Foundation.HWND appWindow, global::System.Guid* riid);
      //...

    Full exception:
    System.InvalidCastException: 'Unable to cast COM object of type 'System.__ComObject' to class type 'WinRT.IInspectable'. Instances of types that represent COM components cannot be cast to types that do not represent COM components; however they can be cast to interfaces as long as the underlying COM component supports QueryInterface calls for the IID of the interface.'

  3. lhak commented on Aug 20, 2021

    @lhak

    This code worked for me in the past (have not tested it for a couple of weeks so some things might have changed):

    [ComImport]
    [Guid("3A3DCD6C-3EAB-43DC-BCDE-45671CE800C8")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IDataTransferManagerInterop
    {
        IntPtr GetForWindow([In] IntPtr appWindow, [In] ref Guid riid);
        void ShowShareUIForWindow(IntPtr appWindow);
    }
    
    public static DataTransferManager GetDataTransferManager(IntPtr appWindow)
    {
        IDataTransferManagerInterop interop = DataTransferManager.As<IDataTransferManagerInterop>();
        Guid id = new Guid(0xa5caee9b, 0x8708, 0x49d1, 0x8d, 0x36, 0x67, 0xd2, 0x5a, 0x8d, 0xa0, 0x0c);
        IntPtr result;
        result = interop.GetForWindow(appWindow, id);
        DataTransferManager dataTransferManager = MarshalInterface<DataTransferManager>.FromAbi(result);
        return (dataTransferManager);
    }
  4. Marv51 commented on Aug 30, 2021

    @Marv51
    Author

    The way lhak does it, works for me. So is this a CsWin32 issue and the return value should be an IntPtr? Or is there a different way to use the objectreturn value?

  5. manodasanW commented on Aug 31, 2021

    @manodasanW
    Member

    Marvin Rühe (@Marv51) a return type of object relies on the .NET runtime to handle the marshaling which is no longer supported starting with .NET 5. The replacement for this is the IntPtr return with marshaling done by the CsWinRT APIs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

bugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions