Menampilkan objek UI WinRT yang bergantung pada CoreWindow

Pemilih tertentu, popup, dialog, dan objek Windows Runtime (WinRT) lainnya bergantung pada CoreWindow; biasanya untuk menampilkan antarmuka pengguna (UI). Meskipun CoreWindow tidak didukung di aplikasi desktop (lihat Kelas inti yang tidak didukung), Anda masih dapat menggunakan banyak kelas WinRT tersebut di aplikasi desktop Anda dengan menambahkan sedikit kode interoperabilitas.

Aplikasi desktop Anda bisa berupa aplikasi Pustaka Windows UI (WinUI) 3, Windows Presentation Foundation (WPF), atau Formulir Windows (WinForms). Contoh kode disajikan dalam C# dan C++/WinRT.

Mengatur handel jendela pemilik (HWND) untuk objek UI WinRT

Untuk kelas yang mengimplementasikan antarmuka IInitializeWithWindow (atau antarmuka IDataTransferManagerInterop yang setara), Anda dapat menggunakan antarmuka tersebut untuk mengatur jendela pemilik pada objek sebelum Anda menampilkannya. Ini adalah proses dua langkah.

  1. Tentukan jendela mana yang akan menjadi pemilik objek UI yang ingin Anda tampilkan, dan ambil HWND jendela tersebut. Untuk detail selengkapnya dan contoh kode untuk langkah ini, lihat Mengambil handel jendela (HWND).
  2. Kemudian panggil API interoperabilitas yang sesuai (untuk C# atau C++/WinRT) untuk mengatur handel jendela pemilik (HWND) untuk objek UI WinRT.

Untuk kelas yang mengimplementasikan IInitializeWithWindow

Kelas-kelas ini mengimplementasikan IInitializeWithWindow:

Catatan

Daftar di atas tentu tidak lengkap—lihat dokumentasi jenis untuk melihat apakah itu mengimplementasikan IInitializeWithWindow (atau antarmuka interop yang setara).

Bagian berikutnya berisi contoh kode untuk menampilkan FolderPicker. Tetapi ini adalah teknik yang sama untuk menampilkan salah satu API yang tercantum di atas.

WinUI 3 dengan C# (juga WPF/WinForms dengan .NET 6 atau yang lebih baru)

Catatan

Contoh kode di bagian ini menggunakan kelas interop WinRT.Interop.WindowNative C#. Jika Anda menargetkan .NET 6 atau yang lebih baru, maka Anda dapat menggunakan kelas tersebut dalam proyek WPF atau WinForms. Untuk informasi tentang menyiapkan proyek Anda untuk melakukannya, lihat Memanggil API interop dari aplikasi .NET.

Kode C# di bawah ini mengharapkan bahwa Anda telah menggunakan pola yang didokumenkan dalam Mengambil handel jendela (HWND). Kemudian, untuk mengatur jendela pemilik untuk objek UI yang ingin Anda tampilkan, kode memanggil metode Inisialisasi pada kelas interop WinRT.Interop.InitializeWithWindow C#. Untuk informasi selengkapnya tentang kelas interop C#, lihat Memanggil API interop dari aplikasi .NET.

// MainWindow.xaml.cs
private async void ShowFolderPickerAsync(IntPtr hWnd)
{
    // Create a folder picker.
    var folderPicker = new Windows.Storage.Pickers.FolderPicker();

    // Initialize the folder picker with the window handle (HWND).
    WinRT.Interop.InitializeWithWindow.Initialize(folderPicker, hWnd);

    // Use the folder picker as usual.
    folderPicker.FileTypeFilter.Add("*");
    var folder = await folderPicker.PickSingleFolderAsync();
}

WinUI 3 dengan C++

Kode C++/WinRT di bawah ini mengharapkan bahwa Anda telah menggunakan pola yang didokumenkan dalam Mengambil handel jendela (HWND). Kemudian, untuk mengatur jendela pemilik untuk objek UI yang ingin Anda tampilkan, kode memanggil metode interoperabilitas IInitializeWithWindow::Initialize.

// pch.h
...
#include <microsoft.ui.xaml.window.h>
#include <Shobjidl.h>
#include <winrt/Windows.Storage.Pickers.h>

// MainWindow.xaml.cpp
winrt::fire_and_forget ShowFolderPickerAsync(HWND hWnd)
{
    // Create a folder picker.
    Windows::Storage::Pickers::FolderPicker folderPicker;

    // Initialize the folder picker with the window handle (HWND).
    auto initializeWithWindow{ folderPicker.as<::IInitializeWithWindow>() };
    initializeWithWindow->Initialize(hWnd);

    // Use the folder picker as usual.
    folderPicker.FileTypeFilter().Append(L"*");
    auto folder{ co_await folderPicker.PickSingleFolderAsync() };
}

Untuk kelas yang mengimplementasikan IDataTransferManagerInterop

Kelas Windows.ApplicationModel.DataTransfer.DataTransferManager mengimplementasikan antarmuka IDataTransferManagerInterop (yang, seperti IInitializeWithWindow, memungkinkan Anda mengatur jendela pemilik).

Di aplikasi desktop, alih-alih memanggil metode DataTransferManager.ShowShareUI, Anda memanggil IDataTransferManagerInterop::ShowShareUIForWindow, seperti yang ditunjukkan pada contoh kode di bawah ini.

WinUI 3 dengan C# (juga WPF/WinForms dengan .NET 6 atau yang lebih baru)

// 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);
    }
}
...

WinUI 3 dengan C++

// pch.h in a Windows App SDK app
...
#include <shobjidl_core.h>
#include <microsoft.ui.xaml.window.h>
#include <winrt/Windows.ApplicationModel.DataTransfer.h>
...

// MainWindow.xaml.cpp
...
void MainWindow::myButton_Click(IInspectable const&, RoutedEventArgs const&)
{
    // Retrieve the window handle (HWND) of the current WinUI 3 window.
    auto windowNative{ this->m_inner.as<::IWindowNative>() };
    HWND hWnd{ 0 };
    windowNative->get_WindowHandle(&hWnd);

    winrt::com_ptr<IDataTransferManagerInterop> interop = 
        winrt::get_activation_factory<Windows::ApplicationModel::DataTransfer::DataTransferManager,
        IDataTransferManagerInterop>();

    winrt::guid _dtm_iid{ 0xa5caee9b, 0x8708, 0x49d1, { 0x8d, 0x36, 0x67, 0xd2, 0x5a, 0x8d, 0xa0, 0x0c } };
    Windows::ApplicationModel::DataTransfer::DataTransferManager dataTransferManager{ nullptr };
    interop->GetForWindow(hWnd, _dtm_iid, winrt::put_abi(dataTransferManager));

    dataTransferManager.DataRequested([](Windows::ApplicationModel::DataTransfer::DataTransferManager const& /* sender */,
        Windows::ApplicationModel::DataTransfer::DataRequestedEventArgs const& args)
    {
        args.Request().Data().Properties().Title(L"In a desktop app...");
        args.Request().Data().SetText(L"...display WinRT UI objects that depend on CoreWindow.");
        args.Request().Data().RequestedOperation(Windows::ApplicationModel::DataTransfer::DataPackageOperation::Copy);
    });

    interop->ShowShareUIForWindow(hWnd);
}
...

Untuk kelas yang mengimplementasikan IUserConsentVerifierInterop

Kelas Windows.Security.Credentials.UI.UserConsentVerifier mengimplementasikan antarmuka IUserConsentVerifierInterop (yang, seperti IInitializeWithWindow, memungkinkan Anda mengatur jendela pemilik).

Di aplikasi desktop, alih-alih memanggil metode UserConsentVerifier.RequestVerificationAsync:

Untuk informasi selengkapnya, dan contoh kode, lihat UserConsentVerifier.

Untuk kelas yang mengimplementasikan antarmuka interop lainnya

Antarmuka ini memiliki metode XxxForWindow , yang memungkinkan Anda mengatur handel jendela pemilik (HWND). Anda dapat menggunakan antarmuka ini langsung dari C++/WinRT. Versi antarmuka juga ada dalam bentuk kelas C#—untuk detail selengkapnya, lihat Memanggil API interop dari aplikasi .NET.