File: Platform\WindowStateManager.uwp.cs
Web Access
Project: src\src\Essentials\src\Essentials.csproj (Microsoft.Maui.Essentials)
#nullable enable
using System;
using Microsoft.UI.Windowing;
using Microsoft.UI.Xaml;
 
namespace Microsoft.Maui.ApplicationModel
{
	/// <summary>
	/// Manager object that manages window states on Windows.
	/// </summary>
	public interface IWindowStateManager
	{
		/// <summary>
		/// Occurs when the application's active window changed.
		/// </summary>
		event EventHandler ActiveWindowChanged;
 
		/// <summary>
		/// Gets the application's currently active window.
		/// </summary>
		/// <returns>The application's currently active <see cref="Window"/> object.</returns>
		Window? GetActiveWindow();
 
		/// <summary>
		/// Occurs when a new window is created, but not yet displayed
		/// </summary>
		/// <param name="window">The <see cref="Window"/> object</param>
		void OnPlatformWindowInitialized(Window window);
 
		/// <summary>
		/// Sets the new active window that can be retrieved with <see cref="GetActiveWindow"/>.
		/// </summary>
		/// <param name="window">The <see cref="Window"/> object that is activated.</param>
		/// <param name="args">The associated event arguments for this window activation event.</param>
		void OnActivated(Window window, WindowActivatedEventArgs args);
	}
 
	/// <summary>
	/// Manager object that manages window states on Windows.
	/// </summary>
	public static class WindowStateManager
	{
		static IWindowStateManager? defaultImplementation;
 
		/// <summary>
		/// Provides the default implementation for static usage of this API.
		/// </summary>
		public static IWindowStateManager Default =>
			defaultImplementation ??= new WindowStateManagerImplementation();
 
		internal static void SetDefault(IWindowStateManager? implementation) =>
			defaultImplementation = implementation;
	}
 
	static class WindowStateManagerExtensions
	{
		/// <summary>
		/// Gets the application's currently active window.
		/// </summary>
		/// <param name="manager">The object to invoke this method on.</param>
		/// <param name="throwOnNull">Throws an exception if no current <see cref="Window"/> can be found and this value is set to <see langword="true"/>, otherwise this method returns <see langword="null"/>.</param>
		/// <returns>The application's currently active <see cref="Window"/> object.</returns>
		/// <exception cref="NullReferenceException">Thrown if no current <see cref="Window"/> can be found and <paramref name="throwOnNull"/> is set to <see langword="true"/>.</exception>
		public static Window? GetActiveWindow(this IWindowStateManager manager, bool throwOnNull)
		{
			var window = manager.GetActiveWindow();
			if (throwOnNull && window == null)
				throw new NullReferenceException("The active Window cannot be detected. Ensure that you have called Init in your Application class.");
 
			return window;
		}
 
		/// <summary>
		/// Gets the application's currently active window's pointer.
		/// </summary>
		/// <param name="manager">The object to invoke this method on.</param>
		/// <param name="throwOnNull">Throws an exception if no current <see cref="Window"/> can be found and this value is set to <see langword="true"/>, otherwise this method returns <see cref="IntPtr.Zero"/>.</param>
		/// <returns>The application's currently active window's <see cref="IntPtr"/>.</returns>
		/// <exception cref="NullReferenceException">Thrown if no current <see cref="Window"/> can be found and <paramref name="throwOnNull"/> is set to <see langword="true"/>.</exception>
		public static IntPtr GetActiveWindowHandle(this IWindowStateManager manager, bool throwOnNull)
		{
			var window = manager.GetActiveWindow();
			if (throwOnNull && window == null)
				throw new NullReferenceException("The active Window cannot be detected. Ensure that you have called Init in your Application class.");
 
			if (window == null)
				return IntPtr.Zero;
 
			var handle = WinRT.Interop.WindowNative.GetWindowHandle(window);
 
			return handle;
		}
 
		/// <summary>
		/// Gets the application's currently active app window.
		/// </summary>
		/// <param name="manager">The object to invoke this method on.</param>
		/// <param name="throwOnNull">Throws an exception if no current <see cref="AppWindow"/> can be found and this value is set to <see langword="true"/>, otherwise this method returns <see langword="null"/>.</param>
		/// <returns>The application's currently active <see cref="AppWindow"/> object.</returns>
		/// <exception cref="NullReferenceException">Thrown if no current <see cref="AppWindow"/> can be found and <paramref name="throwOnNull"/> is set to <see langword="true"/>.</exception>
		public static AppWindow? GetActiveAppWindow(this IWindowStateManager manager, bool throwOnNull)
		{
			var window = manager.GetActiveWindow();
			if (throwOnNull && window == null)
				throw new NullReferenceException("The active Window cannot be detected. Ensure that you have called Init in your Application class.");
 
			if (window == null)
				return null;
 
			var handle = WinRT.Interop.WindowNative.GetWindowHandle(window);
			var windowId = UI.Win32Interop.GetWindowIdFromWindow(handle);
			var appWindow = AppWindow.GetFromWindowId(windowId);
 
			return appWindow;
		}
	}
 
	class WindowStateManagerImplementation : IWindowStateManager
	{
		Window? _activeWindow;
 
		public event EventHandler? ActiveWindowChanged;
 
		public Window? GetActiveWindow() =>
			_activeWindow;
 
		void SetActiveWindow(Window window)
		{
			if (_activeWindow == window)
				return;
 
			_activeWindow = window;
 
			ActiveWindowChanged?.Invoke(window, EventArgs.Empty);
		}
 
		public void OnPlatformWindowInitialized(Window window)
		{
			SetActiveWindow(window);
		}
 
		public void OnActivated(Window window, WindowActivatedEventArgs args)
		{
			if (args.WindowActivationState != WindowActivationState.Deactivated)
				SetActiveWindow(window);
		}
	}
}