Visualizzare gli oggetti dell'interfaccia utente WinRT che dipendono da CoreWindow
Alcuni selettori, popup, finestre di dialogo e altri oggetti di Windows Runtime (WinRT) dipendono da CoreWindow, in genere per visualizzare un'interfaccia utente. Anche se CoreWindow non è supportato nelle app desktop (vedere Classi di base non supportate), è possibile comunque usare molte di queste classi WinRT nell'app desktop aggiungendo un po' di codice di interoperabilità.
L'app desktop può essere WinUI 3, Windows Presentation Foundation (WPF) o app Windows Form (WinForms). Gli esempi di codice vengono presentati in C# e C++/WinRT.
Impostare l'handle della finestra proprietaria (HWND) per un oggetto dell'interfaccia utente WinRT
Per le classi che implementano l'interfaccia IInitializeWithWindow (o l'interfaccia IDataTransferManagerInterop), è possibile usare tale interfaccia per impostare una finestra proprietaria sull'oggetto prima di visualizzarla. Il processo si articola in due passaggi.
- Decidere quale finestra sarà proprietaria dell'oggetto dell'interfaccia utente da visualizzare e recuperare l'HWND della finestra. Per altri dettagli ed esempi di codice per questo passaggio, consultare Recuperare un handle di finestra (HWND).
- Quindi chiamare l'API di interoperabilità appropriata (per C# o C++/WinRT) per impostare un handle di finestra proprietaria (HWND) per l'oggetto interfaccia utente WinRT.
Per le classi che implementano IInitializeWithWindow
Queste classi implementano 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, versione 1903 (10.0; Build 18362) e successive
- Windows.System.LauncherOptions—Windows 10, version 1903 (10.0; Build 18362) e successive
- Windows.UI.Core.CoreWindowDialog
- Windows.UI.Core.CoreWindowFlyout
- Windows.UI.Popups.MessageDialog. Tuttavia, per le nuove app è consigliabile usare il controllo ContentDialog.
- Windows.UI.Popups.PopupMenu
- Windows.UI.StartScreen.SecondaryTile
- Windows.Web.Http.Filters.HttpBaseProtocolFilter
Nota
L'elenco precedente è necessariamente incompleto: fare riferimento alla documentazione di un tipo per verificare se implementa IInitializeWithWindow (o un'interfaccia di interoperabilità equivalente).
Le sezioni successive contengono esempi di codice per visualizzare FolderPicker. in sostanza è la stessa tecnica per visualizzare una delle API elencate in precedenza.
WinUI 3 con C# (anche WPF/WinForms con .NET 6 o versione successiva)
Nota
Gli esempi di codice in questa sezione usano la classe di interoperabilità C# WinRT.Interop.WindowNative. Se si usa .NET 6 o versione successiva, è possibile usare tale classe in un progetto WPF o WinForms. Per informazioni sulla configurazione del progetto a tale scopo, vedere Chiamare le API interop da un'app .NET.
Il codice C# seguente prevede che sia già stato usato il modello documentato in Recuperare un handle di finestra (HWND). Quindi, per impostare la finestra del proprietario per l'oggetto dell'interfaccia utente da visualizzare, il codice chiama il metodo Initialize nella classe di interoperabilità C# WinRT.Interop.InitializeWithWindow. Per altre informazioni sulle classi di interoperabilità C#, vedere Chiamare le API interop da un'app .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 con C++
Il codice C++/WinRT seguente prevede che sia già stato usato il modello documentato in Recuperare un handle di finestra (HWND). Quindi, per impostare la finestra proprietaria per l'oggetto dell'interfaccia utente da visualizzare, il codice chiama il metodo di interoperabilità 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() };
}
Per le classi che implementano IDataTransferManagerInterop
La classe Windows.ApplicationModel.DataTransfer.DataTransferManager implementa l'interfaccia IDataTransferManagerInterop (come IInitializeWithWindow, che consente di impostare una finestra proprietaria).
In un'app desktop, invece di chiamare il metodo DataTransferManager.ShowShareUI si chiama IDataTransferManagerInterop::ShowShareUIForWindow, come illustrato negli esempi di codice seguenti.
WinUI 3 con C# (anche WPF/WinForms con .NET 6 o versione successiva)
// 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 con 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);
}
...
Per le classi che implementano IUserConsentVerifierInterop
la classe Windows.Security.Credentials.UI.UserConsentVerifier implementa l'interfaccia IUserConsentVerifierInterop (come IInitializeWithWindow, che consente di impostare una finestra proprietaria).
In un'app desktop, invece di chiamare il metodo UserConsentVerifier.RequestVerificationAsync:
- C#. Chiamare il metodo RequestVerificationForWindowAsync della classe di interoperabilità C# Windows.Security.Credentials.UI.UserConsentVerifierInterop. Per altre informazioni sulle classi di interoperabilità C#, vedere Chiamare le API interop da un'app .NET.
- C++/WinRT. Chiamare IUserConsentVerifierInterop::RequestVerificationForWindowAsync.
Per altre informazioni ed esempi di codice, consultare UserConsentVerifier.
Per le classi che implementano altre interfacce di interoperabilità
Queste interfacce hanno metodi XxxForWindow, che consentono di impostare un handle di finestra proprietaria (HWND). È possibile usare queste interfacce direttamente da C++/WinRT. Le versioni delle interfacce esistono anche sotto forma di classi C#. Per altri dettagli, vedere Chiamare le API interop da un'app .NET.
- IAccountsSettingsPaneInterop
- IDragDropManagerInterop
- IInputPaneInterop
- IPlayToManagerInterop
- IPrintManagerInterop
- IRadialControllerConfigurationInterop
- IRadialControllerIndependentInputSourceInterop
- IRadialControllerInterop
- ISpatialInteractionManagerInterop
- ISystemMediaTransportControlsInterop
- IUIViewSettingsInterop
- IWebAuthenticationCoreManagerInterop