Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Please simply wrap the DataTransferManager interop class #3777

Closed
Gaoyifei1011 opened this issue Aug 2, 2023 · 3 comments
Closed

Please simply wrap the DataTransferManager interop class #3777

Gaoyifei1011 opened this issue Aug 2, 2023 · 3 comments

Comments

@Gaoyifei1011
Copy link

Gaoyifei1011 commented Aug 2, 2023

Describe the bug

Please simply wrap the DataTransferManager interop class

At present in desktop applications, if we want to invoke DataTransferManager class methods, the need to import IDataTransferManagerInterop interface, and implement the corresponding operation in accordance with the corresponding methods, it is a bit too cumbersome. Hope future versions can be a simple packaging IDataTransferManagerInterop interface, to call DataTransferManager method in a class.
目前在桌面应用中,如果我们想要调用DataTransferManager类的方法,需要自己导入IDataTransferManagerInterop接口,并按照相应的方法实现对应的操作,这有点太繁琐了。希望未来的版本中可以简单包装一下IDataTransferManagerInterop接口,能更快的调用DataTransferManager类中的方法。

This is the code in the official example.
这是官方示例中的代码。

// MainWindow.xaml.cs
...
public sealed partial class MainWindow : Window
{
...
[System.Runtime.InteropServices.ComImport]
[System.Runtime.InteropServices.Guid("3A3DCD6C-3EAB-43DC-BCDE-45671CE800C8")]
[System.Runtime.InteropServices.InterfaceType(
System.Runtime.InteropServices.ComInterfaceType.InterfaceIsIUnknown)]
interface IDataTransferManagerInterop
{
IntPtr GetForWindow([System.Runtime.InteropServices.In] IntPtr appWindow,
[System.Runtime.InteropServices.In] ref Guid riid);
void ShowShareUIForWindow(IntPtr appWindow);
}

static readonly Guid _dtm_iid = 
    new Guid(0xa5caee9b, 0x8708, 0x49d1, 0x8d, 0x36, 0x67, 0xd2, 0x5a, 0x8d, 0xa0, 0x0c);

private void myButton_Click(object sender, RoutedEventArgs e)
{
    // Retrieve the window handle (HWND) of the current WinUI 3 window.
    var hWnd = WinRT.Interop.WindowNative.GetWindowHandle(this);

    IDataTransferManagerInterop interop =
    Windows.ApplicationModel.DataTransfer.DataTransferManager.As
        <IDataTransferManagerInterop>();

    IntPtr result = interop.GetForWindow(hWnd, _dtm_iid);
    var dataTransferManager = WinRT.MarshalInterface
        <Windows.ApplicationModel.DataTransfer.DataTransferManager>.FromAbi(result);

    dataTransferManager.DataRequested += (sender, args) =>
    {
        args.Request.Data.Properties.Title = "In a desktop app...";
        args.Request.Data.SetText("...display WinRT UI objects that depend on CoreWindow.");
        args.Request.Data.RequestedOperation = 
            Windows.ApplicationModel.DataTransfer.DataPackageOperation.Copy;
    };

    // Show the Share UI
    interop.ShowShareUIForWindow(hWnd);
}

}
...

image

Steps to reproduce the bug

None

Expected behavior

Please provide a DataTransferManagerInterop static class, the class has achieved IDataTransferManagerInterop interface, and provides the corresponding interactions. The following code
请提供一个DataTransferManagerInterop静态类,这个类内部已经实现了IDataTransferManagerInterop接口,并提供了相应的交互操作。如下面的代码

public static class DataTransferManagerInterop
{
    private static readonly Guid riid = new Guid(0xa5caee9b, 0x8708, 0x49d1, 0x8d, 0x36, 0x67, 0xd2, 0x5a, 0x8d, 0xa0, 0x0c);

    private static IDataTransferManagerInterop dataTransferManagerInterop = DataTransferManager.As<IDataTransferManagerInterop>();

    public static DataTransferManager GetForWindow(IntPtr window)
    {
        return MarshalInterface<DataTransferManager>.FromAbi(dataTransferManagerInterop.GetForWindow(window, riid));
    }

    public static void ShowShareUI(IntPtr window)
    {
        dataTransferManagerInterop.ShowShareUIForWindow(window);
    }
}

In this wrapped class, if we need to use the methods provided in the DataTransferManager class, we only need one line of code:
在这个包装好的类中,如果我们需要使用DataTransferManager类中提供的方法,只需要一行代码:

DataTransferManager dataTransferManager = DataTransferManagerInterop.GetForWindow(/need to input window handle/);

To display the shared window, just:
想要显示共享窗口,只需要:
DataTransferManagerInterop.ShowShareUI(/need to input window handle/);

It can be called quickly.
即可快速调用。

Screenshots

Defined static class
定义的静态类
image

快速调用示例
Quick call example
image

The definition of the DataTransferManagerInterop static class reference is DisplayInformationInterop static class definition
这个DataTransferManagerInterop静态类的定义参考的是DisplayInformationInterop静态类的定义

NuGet package version

Windows App SDK 1.4 Preview 1: 1.4.230628000-preview1

Packaging type

Packaged (MSIX)

Windows version

Windows 11 version 22H2 (22621, 2022 Update)

IDE

Visual Studio 2022

Additional context

None

@JaiganeshKumaran
Copy link
Contributor

Related to #1063

@zhuxb711
Copy link

通过使用Vanara.Windows.Shell提供的Win32 API包装,应当能够将其简化为以下代码。但是确实WAS应该提供官方实现。
With Vanara.Windows.Shell, you could simplify it as the following, but we need the official implement, in indeed:

Shell32.IDataTransferManagerInterop Interop = DataTransferManager.As<Shell32.IDataTransferManagerInterop>();
Interop.GetForWindow(<Your window handle>, Shell32.IID_DataTransferManager, out IntPtr ObjectPointer).ThrowIfFailed();
DataTransferManager.FromAbi(ObjectPointer).DataRequested += (s, e) =>
{
    DataRequestDeferral Deferral = e.Request.GetDeferral();

    try
    {
        e.Request.Data = new DataPackage();
        e.Request.Data.Properties.Title = <Your file name>;
        e.Request.Data.Properties.Description = <Your file type>;
        e.Request.Data.SetStorageItems(new IStorageItem[] { <Your file that want to share> }, false);
    }
    catch (Exception ex)
    {
        e.Request.FailWithDisplayText(ex.Message);
    }
    finally
    {
        Deferral.Complete();
    }
};

Interop.ShowShareUIForWindow(<Your window handle>).ThrowIfFailed();

@Gaoyifei1011
Copy link
Author

Describe the bug

Please simply wrap the DataTransferManager interop class

At present in desktop applications, if we want to invoke DataTransferManager class methods, the need to import IDataTransferManagerInterop interface, and implement the corresponding operation in accordance with the corresponding methods, it is a bit too cumbersome. Hope future versions can be a simple packaging IDataTransferManagerInterop interface, to call DataTransferManager method in a class. 目前在桌面应用中,如果我们想要调用DataTransferManager类的方法,需要自己导入IDataTransferManagerInterop接口,并按照相应的方法实现对应的操作,这有点太繁琐了。希望未来的版本中可以简单包装一下IDataTransferManagerInterop接口,能更快的调用DataTransferManager类中的方法。

This is the code in the official example. 这是官方示例中的代码。

// MainWindow.xaml.cs ... public sealed partial class MainWindow : Window { ... [System.Runtime.InteropServices.ComImport] [System.Runtime.InteropServices.Guid("3A3DCD6C-3EAB-43DC-BCDE-45671CE800C8")] [System.Runtime.InteropServices.InterfaceType( System.Runtime.InteropServices.ComInterfaceType.InterfaceIsIUnknown)] interface IDataTransferManagerInterop { IntPtr GetForWindow([System.Runtime.InteropServices.In] IntPtr appWindow, [System.Runtime.InteropServices.In] ref Guid riid); void ShowShareUIForWindow(IntPtr appWindow); }

static readonly Guid _dtm_iid = 
    new Guid(0xa5caee9b, 0x8708, 0x49d1, 0x8d, 0x36, 0x67, 0xd2, 0x5a, 0x8d, 0xa0, 0x0c);

private void myButton_Click(object sender, RoutedEventArgs e)
{
    // Retrieve the window handle (HWND) of the current WinUI 3 window.
    var hWnd = WinRT.Interop.WindowNative.GetWindowHandle(this);

    IDataTransferManagerInterop interop =
    Windows.ApplicationModel.DataTransfer.DataTransferManager.As
        <IDataTransferManagerInterop>();

    IntPtr result = interop.GetForWindow(hWnd, _dtm_iid);
    var dataTransferManager = WinRT.MarshalInterface
        <Windows.ApplicationModel.DataTransfer.DataTransferManager>.FromAbi(result);

    dataTransferManager.DataRequested += (sender, args) =>
    {
        args.Request.Data.Properties.Title = "In a desktop app...";
        args.Request.Data.SetText("...display WinRT UI objects that depend on CoreWindow.");
        args.Request.Data.RequestedOperation = 
            Windows.ApplicationModel.DataTransfer.DataPackageOperation.Copy;
    };

    // Show the Share UI
    interop.ShowShareUIForWindow(hWnd);
}

} ...

image

Steps to reproduce the bug

None

Expected behavior

Please provide a DataTransferManagerInterop static class, the class has achieved IDataTransferManagerInterop interface, and provides the corresponding interactions. The following code 请提供一个DataTransferManagerInterop静态类,这个类内部已经实现了IDataTransferManagerInterop接口,并提供了相应的交互操作。如下面的代码

public static class DataTransferManagerInterop
{
    private static readonly Guid riid = new Guid(0xa5caee9b, 0x8708, 0x49d1, 0x8d, 0x36, 0x67, 0xd2, 0x5a, 0x8d, 0xa0, 0x0c);

    private static IDataTransferManagerInterop dataTransferManagerInterop = DataTransferManager.As<IDataTransferManagerInterop>();

    public static DataTransferManager GetForWindow(IntPtr window)
    {
        return MarshalInterface<DataTransferManager>.FromAbi(dataTransferManagerInterop.GetForWindow(window, riid));
    }

    public static void ShowShareUI(IntPtr window)
    {
        dataTransferManagerInterop.ShowShareUIForWindow(window);
    }
}

In this wrapped class, if we need to use the methods provided in the DataTransferManager class, we only need one line of code: 在这个包装好的类中,如果我们需要使用DataTransferManager类中提供的方法,只需要一行代码:

DataTransferManager dataTransferManager = DataTransferManagerInterop.GetForWindow(/need to input window handle/);

To display the shared window, just: 想要显示共享窗口,只需要: DataTransferManagerInterop.ShowShareUI(/need to input window handle/);

It can be called quickly. 即可快速调用。

Screenshots

Defined static class 定义的静态类 image

快速调用示例 Quick call example image

The definition of the DataTransferManagerInterop static class reference is DisplayInformationInterop static class definition 这个DataTransferManagerInterop静态类的定义参考的是DisplayInformationInterop静态类的定义

NuGet package version

Windows App SDK 1.4 Preview 1: 1.4.230628000-preview1

Packaging type

Packaged (MSIX)

Windows version

Windows 11 version 22H2 (22621, 2022 Update)

IDE

Visual Studio 2022

Additional context

None

See reference microsoft/CsWinRT#1528

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

No branches or pull requests

4 participants