Anzeigen von WinRT UI-Objekten, die von CoreWindow abhängig sind
Bestimmte Auswahlsteuerelemente, Popups, Dialogfelder und andere WinRT-Objekte (Windows-Runtime) sind von einem CoreWindow-Element abhängig. In der Regel wird eine Benutzeroberfläche (UI) angezeigt. CoreWindow wird in Desktop-Apps zwar nicht unterstützt (siehe Nicht unterstützte Core-Klassen), Sie können aber dennoch viele dieser WinRT-Klassen in Ihrer Desktop-App verwenden, indem Sie ein wenig Interoperationscode hinzufügen.
Ihre Desktop-App kann WinUI 3-, Windows Presentation Foundation (WPF)- oder Windows Forms (WinForms)-Apps sein. Codebeispiele werden in C# und C++/WinRT dargestellt.
Festlegen des Besitzerfensterhandles (HWND) für ein WinRT-UI-Objekt
Für Klassen, die die IInitializeWithWindow-Schnittstelle (oder die entsprechende IDataTransferManagerInterop-Schnittstelle) implementieren, können Sie diese Schnittstelle verwenden, um ein Besitzerfenster für das Objekt festzulegen, bevor Sie es anzeigen. Dies ist ein zweistufiger Prozess.
- Entscheiden Sie, welches Fenster der Besitzer des UI-Objekts sein soll, das Sie anzeigen möchten, und rufen Sie das HWND dieses Fensters auf. Weitere Details und Codebeispiele für diesen Schritt finden Sie unter Abrufen eines Fensterhandles (HWND).
- Rufen Sie dann die entsprechende Interoperabilitäts-API (für C# oder C++/WinRT) auf, um einen Besitzerfensterhandle (HWND) für das WinRT-UI-Objekt festzulegen.
Für Klassen, die „IInitializeWithWindow“ implementieren
Diese Klassen implementieren IInitializeWithWindow:
- Windows.ApplicationModel.Contacts.PinnedContactManager
- Windows.ApplicationModel.Payments.PaymentMediator
- Windows.Devices.Enumeration.DevicePicker
- Windows.Graphics.Capture.GraphicsCapturePicker
- Windows.Media.Casting.CastingDevicePicker
- Windows.Media.DialProtocol.DialDevicePicker
- Windows.Networking.NetworkOperators.ProvisioningAgent
- Windows.Security.Authentication.OnlineId.OnlineIdAuthenticator
- Windows.Services.Store.StoreContext
- Windows.Storage.Pickers.FileOpenPicker
- Windows.Storage.Pickers.FileSavePicker
- Windows.Storage.Pickers.FolderPicker
- Windows.System.FolderLauncherOptions – Windows 10, Version 1903 (10.0; Build 18362) und höher
- Windows.System.LauncherOptions – Windows 10, Version 1903 (10.0; Build 18362) und höher
- Windows.UI.Core.CoreWindowDialog
- Windows.UI.Core.CoreWindowFlyout
- Windows.UI.Popups.MessageDialog. Für neue Apps empfehlen wir jedoch stattdessen die Verwendung des ContentDialog-Steuerelements.
- Windows.UI.Popups.PopupMenu
- Windows.UI.StartScreen.SecondaryTile
- Windows.Web.Http.Filters.HttpBaseProtocolFilter
Hinweis
Die oben aufgeführte Liste ist notwendigerweise unvollständig – verweisen Sie auf die Dokumentation eines Typs, um festzustellen, ob IInitializeWithWindow (oder eine entsprechende Interop-Schnittstelle) implementiert wird.
Die nächsten Abschnitte enthalten Codebeispiele zum Anzeigen eines FolderPicker. Es ist jedoch dieselbe Technik, eine der oben aufgeführten APIs anzuzeigen.
WinUI 3 mit C# (auch WPF/WinForms mit .NET 6 oder höher)
Hinweis
Die Codebeispiele in diesem Abschnitt verwenden die WinRT.Interop.WindowNative C#-Interop-Klasse. Wenn Sie auf .NET 6 oder höher abzielen, können Sie diese Klasse in einem WPF- oder WinForms-Projekt verwenden. Informationen zum Einrichten Ihres Projekts hierzu finden Sie unter Aufrufen von Interop-APIs aus einer .NET-App.
Der folgende C#-Code setzt voraus, dass Sie bereits das Muster verwendet haben, das in Abrufen eines Fensterhandles (HWND) dokumentiert ist. Um dann das Besitzerfenster für das anzuzeigende UI-Objekt festzulegen, ruft der Code die Initialize-Methode für die WinRT.Interop.InitializeWithWindow C#-Interop-Klasse auf. Weitere Informationen zu den C#-Interop-Klassen finden Sie unter Aufrufen von Interop-APIs aus einer .NET-App.
// 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 mit C++
Der folgende C++/WinRT-Code setzt voraus, dass Sie bereits das Muster verwendet haben, das in Abrufen eines Fensterhandles (HWND) dokumentiert ist. Um dann das Besitzerfenster für das anzuzeigende UI-Objekt festzulegen, ruft der Code die Interoperatability-Methode IInitializeWithWindow::Initialize auf.
// 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() };
}
Für Klassen, die IDataTransferManagerInterop implementieren
Die Windows.ApplicationModel.DataTransfer.DataTransferManager-Klasse implementiert die IDataTransferManagerInterop-Schnittstelle (mit der Sie wie IInitializeWithWindow ein Besitzerfenster festlegen können).
Anstatt in einer Desktop-App die DataTransferManager.ShowShareUI-Methode aufzurufen, rufen Sie IDataTransferManagerInterop::ShowShareUIForWindow wie in den folgenden Codebeispielen dargestellt auf.
WinUI 3 mit C# (auch WPF/WinForms mit .NET 6 oder höher)
// 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 mit 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);
}
...
Für Klassen, die IUserConsentVerifierInterop implementieren
Die Windows.Security.Credentials.UI.UserConsentVerifier-Klasse implementiert die IUserConsentVerifierInterop-Schnittstelle (mit der Sie wie IInitializeWithWindow ein Besitzerfenster festlegen können).
Anstatt in einer Desktop-App die UserConsentVerifier.RequestVerificationAsync-Methode aufzurufen:
- C#. Rufen Sie die RequestVerificationForWindowAsync-Methode der Windows.Security.Credentials.UI.UserConsentVerifierInterop C#-Interop-Klasse auf. Weitere Informationen zu den C#-Interop-Klassen finden Sie unter Aufrufen von Interop-APIs aus einer .NET-App.
- C++/WinRT. Rufen Sie IUserConsentVerifierInterop::RequestVerificationForWindowAsync auf.
Weitere Informationen und Codebeispiele finden Sie unter UserConsentVerifier.
Für Klassen, die andere Interop-Schnittstellen implementieren
Diese Schnittstellen verfügen über XxxForWindow-Methoden, mit denen Sie ein Besitzerfensterhandle (HWND) festlegen können. Sie können diese Schnittstellen direkt aus C++/WinRT verwenden. Versionen der Schnittstellen sind auch in Form von C#-Klassen vorhanden. Weitere Informationen finden Sie unter Aufrufen von Interop-APIs aus einer .NET-App.
- IAccountsSettingsPaneInterop
- IDragDropManagerInterop
- IInputPaneInterop
- IPlayToManagerInterop
- IPrintManagerInterop
- IRadialControllerConfigurationInterop
- IRadialControllerIndependentInputSourceInterop
- IRadialControllerInterop
- ISpatialInteractionManagerInterop
- ISystemMediaTransportControlsInterop
- IUIViewSettingsInterop
- IWebAuthenticationCoreManagerInterop
Zugehörige Themen
Windows developer