A CoreWindow-tól függő WinRT felhasználói felületi objektumok megjelenítése

Bizonyos választók, előugró ablakok, párbeszédpanelek és más Windows-futtatókörnyezet (WinRT) objektumok a CoreWindow-tól függenek, jellemzően a felhasználói felület (UI) megjelenítéséhez. Annak ellenére, hogy a CoreWindow nem támogatott az asztali alkalmazásokban (lásd a Nem támogatott Core-osztályokat), az asztali alkalmazásban továbbra is használhatja ezeket a WinRT-osztályokat egy kis együttműködési kód hozzáadásával.

Az asztali alkalmazás lehet WinUI 3, Windows megjelenítési alaprendszer (WPF) vagy Windows Forms (WinForms) alkalmazások. A kódpéldákat C# és C++/WinRT formátumban mutatjuk be.

WinRT felhasználói felületi objektum tulajdonosi ablakfogantyújának (HWND) beállítása

Az IInitializeWithWindow felületet (vagy az azzal egyenértékű IDataTransferManagerInterop felületet) megvalósító osztályok esetében a kezelőfelülettel a megjelenítés előtt beállíthat egy tulajdonosi ablakot az objektumon. Ez egy kétlépéses folyamat.

  1. Döntse el, melyik ablak lesz a megjeleníteni kívánt felhasználói felületi objektum tulajdonosa, és kérje le az ablak HWND-jét. Ehhez a lépéshez további részletekért és kód példákért lásd: Ablakleíró (HWND) lekérése.
  2. Ezután hívja meg a megfelelő együttműködési API-t (C# vagy C++/WinRT esetén), hogy beállítson egy tulajdonosi ablakfogópontot (HWND) a WinRT felhasználói felületi objektumhoz.

Az IInitializeWithWindow implementálását megvalósító osztályok esetében

Ezek az osztályok implementálják az IInitializeWithWindow-t:

Megjegyzés:

A fenti lista szükségszerűen hiányos – tekintse meg egy típus dokumentációját, hogy lássa, implementálja-e az IInitializeWithWindow-t (vagy ezzel egyenértékű interop interfészt).

A következő szakaszok egy FolderPicker megjelenítésére szolgáló kódpéldákat tartalmaznak. De ugyanez a technika a fent felsorolt API-k bármelyikének megjelenítésére.

WinUI C#-rel (valamint WPF/WinForms .NET 6 verzió vagy újabb)

Megjegyzés:

Az ebben a szakaszban szereplő kód példák a WinRT.Interop.WindowNative C# interop osztályt használják. Ha a .NET 6 vagy újabb verzióját célzott meg, akkor használhatja ezt az osztályt egy WPF vagy WinForms projektben. A projekt beállításával kapcsolatos információkért lásd: A .NET alkalmazásközi API-k hívása.

Az alábbi C#-kód arra számít, hogy már használta az ablakleíróban (HWND) dokumentált mintát. Ezután a megjeleníteni kívánt felhasználói felület objektum tulajdonosi ablakának beállításához a kód meghívja az Inicializálásmetódust a WinRT.Interop.InitializeWithWindow C# interop osztályban. A C#-interop osztályokkal kapcsolatos további információkért lásd: A .NET alkalmazásközi API-k hívása.

// 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 a C++ használatával

Az alábbi C++/WinRT-kód arra számít, hogy már használta az ablakleíróban (HWND) dokumentált mintát. Ezután a megjeleníteni kívánt felhasználói felület objektum tulajdonosi ablakának beállításához a kód meghívja az IInitializeWithWindow::Initialize együttműködési módszert.

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

Az IDataTransferManagerInterop-t implementáló osztályok esetében

A Windows.ApplicationModel.DataTransfer.DataTransferManager osztály implementálja az IDataTransferManagerInterop felületet (amely az IInitializeWithWindow-hez hasonlóan lehetővé teszi a tulajdonosi ablak beállítását).

Asztali alkalmazásokban a DataTransferManager.ShowShareUI metódus meghívása helyett az IDataTransferManagerInterop::ShowShareUIForWindow metódust kell meghívni, ahogy az alábbi kódpéldákban is látható.

WinUI C#-rel (valamint WPF/WinForms .NET 6 verzió vagy újabb)

// 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 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 a C++ használatával

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

Az IUserConsentVerifierInterop-t implementáló osztályok esetében

A Windows.Security.Credentials.UI.UserConsentVerifier osztály implementálja az IUserConsentVerifierInterop felületet (amely az IInitializeWithWindow-hez hasonlóan lehetővé teszi a tulajdonosi ablak beállítását).

Asztali alkalmazásokban a UserConsentVerifier.RequestVerificationAsync metódus meghívása helyett:

További információ és példakód: UserConsentVerifier.

Egyéb interop interfészeket implementáló osztályok esetén

Ezek az interfészek XxxForWindow metódusokkal rendelkeznek, amelyekkel beállíthat egy tulajdonosi ablakfogópontot (HWND). Ezeket az interfészeket közvetlenül a C++/WinRT-ből használhatja. A felületek verziói C#-osztályok formájában is léteznek – további részletekért lásd: A .NET alkalmazásközi API-k hívása.