From af8d17ad85ed5f3bbd9392e08a016941cae760bd Mon Sep 17 00:00:00 2001 From: Shane Neuville Date: Fri, 10 Dec 2021 15:20:16 -0600 Subject: [PATCH 1/5] Retrieve Interaction mode from Handle --- src/Essentials/src/DeviceInfo/DeviceInfo.uwp.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Essentials/src/DeviceInfo/DeviceInfo.uwp.cs b/src/Essentials/src/DeviceInfo/DeviceInfo.uwp.cs index 22d8e7a114c5..b86a0a556bd9 100644 --- a/src/Essentials/src/DeviceInfo/DeviceInfo.uwp.cs +++ b/src/Essentials/src/DeviceInfo/DeviceInfo.uwp.cs @@ -63,7 +63,9 @@ static DeviceIdiom GetIdiom() { try { - var uiMode = UIViewSettings.GetForCurrentView().UserInteractionMode; + var currentHandle = Essentials.Platform.CurrentWindowHandle; + var settings = UIViewSettingsInterop.GetForWindow(currentHandle); + var uiMode = settings.UserInteractionMode; currentIdiom = uiMode == UserInteractionMode.Mouse ? DeviceIdiom.Desktop : DeviceIdiom.Tablet; } catch (Exception ex) From 31a63e2b265aa1a10f87d40da059884599a6fdc0 Mon Sep 17 00:00:00 2001 From: Shane Neuville Date: Fri, 10 Dec 2021 17:38:55 -0600 Subject: [PATCH 2/5] Add calls for orientation --- .../src/DeviceDisplay/DeviceDisplay.uwp.cs | 116 +++++++++++++++--- 1 file changed, 101 insertions(+), 15 deletions(-) diff --git a/src/Essentials/src/DeviceDisplay/DeviceDisplay.uwp.cs b/src/Essentials/src/DeviceDisplay/DeviceDisplay.uwp.cs index 4876b1f54222..d35bd2ad10a2 100644 --- a/src/Essentials/src/DeviceDisplay/DeviceDisplay.uwp.cs +++ b/src/Essentials/src/DeviceDisplay/DeviceDisplay.uwp.cs @@ -1,5 +1,7 @@ #nullable enable using System; +using System.Runtime.InteropServices; +using Microsoft.UI.Windowing; using Windows.Graphics.Display; using Windows.Graphics.Display.Core; using Windows.System.Display; @@ -47,20 +49,20 @@ public bool KeepScreenOn } } - public DisplayInfo GetMainDisplayInfo() => - GetMainDisplayInfo(null); - - DisplayInfo GetMainDisplayInfo(DisplayInformation? di = null) + public DisplayInfo GetMainDisplayInfo() { - di ??= DisplayInformation.GetForCurrentView(); + var appWindow = GetAppWindowForCurrentWindow(); + DEVMODE vDevMode = new DEVMODE(); + EnumDisplaySettings(null!, -1, ref vDevMode); - var rotation = CalculateRotation(di); + var rotation = CalculateRotation(vDevMode); var perpendicular = rotation == DisplayRotation.Rotation90 || rotation == DisplayRotation.Rotation270; - var w = di.ScreenWidthInRawPixels; - var h = di.ScreenHeightInRawPixels; + var w = appWindow.Size.Width; + var h = appWindow.Size.Height; + var hdi = HdmiDisplayInformation.GetForCurrentView(); var hdm = hdi?.GetCurrentDisplayMode(); @@ -68,8 +70,8 @@ DisplayInfo GetMainDisplayInfo(DisplayInformation? di = null) return new DisplayInfo( width: perpendicular ? h : w, height: perpendicular ? w : h, - density: di.LogicalDpi / 96.0, - orientation: CalculateOrientation(di), + density: 999,//di.LogicalDpi / 96.0, TODO FIX + orientation: GetWindowOrientationWin32() == DisplayOrientations.Landscape ? DisplayOrientation.Landscape : DisplayOrientation.Portrait, rotation: rotation, rate: (float)(hdm?.RefreshRate ?? 0)); } @@ -98,8 +100,11 @@ public void StopScreenMetricsListeners() void OnDisplayInformationChanged(DisplayInformation di, object args) { - var metrics = GetMainDisplayInfo(di); - MainDisplayInfoChanged?.Invoke(this, new DisplayInfoChangedEventArgs(metrics)); + + //var metrics = GetMainDisplayInfo(di); + + // TODO this is just so it compiles + MainDisplayInfoChanged?.Invoke(this, new DisplayInfoChangedEventArgs(new DisplayInfo())); } DisplayOrientation CalculateOrientation(DisplayInformation di) @@ -117,10 +122,26 @@ DisplayOrientation CalculateOrientation(DisplayInformation di) return DisplayOrientation.Unknown; } - static DisplayRotation CalculateRotation(DisplayInformation di) + static DisplayRotation CalculateRotation(DEVMODE devMode) { - var native = di.NativeOrientation; - var current = di.CurrentOrientation; + DisplayOrientations native = DisplayOrientations.Portrait; + switch (devMode.dmDisplayOrientation) + { + case 0: + native = DisplayOrientations.Portrait; + break; + case 1: + native = DisplayOrientations.Landscape; + break; + case 2: + native = DisplayOrientations.LandscapeFlipped; + break; + case 3: + native = DisplayOrientations.PortraitFlipped; + break; + } + + var current = GetWindowOrientationWin32(); if (native == DisplayOrientations.Portrait) { @@ -153,5 +174,70 @@ static DisplayRotation CalculateRotation(DisplayInformation di) return DisplayRotation.Unknown; } + + static AppWindow GetAppWindowForCurrentWindow() + { + var myWndId = Microsoft.UI.Win32Interop.GetWindowIdFromWindow(Essentials.Platform.CurrentWindowHandle); + return AppWindow.GetFromWindowId(myWndId); + } + + [DllImport("User32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern Boolean EnumDisplaySettings( + byte[] lpszDeviceName, + [param: MarshalAs(UnmanagedType.U4)] int iModeNum, + [In, Out] ref DEVMODE lpDevMode); + + static DisplayOrientations GetWindowOrientationWin32() + { + var appWindow = GetAppWindowForCurrentWindow(); + DisplayOrientations orientationEnum; + int theScreenWidth = appWindow.Size.Width; + int theScreenHeight = appWindow.Size.Height; + if (theScreenWidth > theScreenHeight) + orientationEnum = DisplayOrientations.Landscape; + else + orientationEnum = DisplayOrientations.Portrait; + + return orientationEnum; + } + + public struct DEVMODE + { + private const int CCHDEVICENAME = 0x20; + private const int CCHFORMNAME = 0x20; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)] + public string dmDeviceName; + public short dmSpecVersion; + public short dmDriverVersion; + public short dmSize; + public short dmDriverExtra; + public int dmFields; + public int dmPositionX; + public int dmPositionY; + public int dmDisplayOrientation; + public int dmDisplayFixedOutput; + public short dmColor; + public short dmDuplex; + public short dmYResolution; + public short dmTTOption; + public short dmCollate; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)] + public string dmFormName; + public short dmLogPixels; + public int dmBitsPerPel; + public int dmPelsWidth; + public int dmPelsHeight; + public int dmDisplayFlags; + public int dmDisplayFrequency; + public int dmICMMethod; + public int dmICMIntent; + public int dmMediaType; + public int dmDitherType; + public int dmReserved1; + public int dmReserved2; + public int dmPanningWidth; + public int dmPanningHeight; + } } } From aedddc8f379182666dd8b60eeed7f8d6dec474be Mon Sep 17 00:00:00 2001 From: Shane Neuville Date: Mon, 13 Dec 2021 14:57:53 -0600 Subject: [PATCH 3/5] - finish up the rest of the static caller cleanups --- .../src/Platform/Windows/MauiWinUIWindow.cs | 1 + .../src/DeviceDisplay/DeviceDisplay.uwp.cs | 344 +++++++++++++----- src/Essentials/src/Platform/Platform.uwp.cs | 46 ++- .../src/Properties/AssemblyInfo.uwp.cs | 3 + 4 files changed, 306 insertions(+), 88 deletions(-) create mode 100644 src/Essentials/src/Properties/AssemblyInfo.uwp.cs diff --git a/src/Core/src/Platform/Windows/MauiWinUIWindow.cs b/src/Core/src/Platform/Windows/MauiWinUIWindow.cs index db91429bb4c7..7d1d6333d5a2 100644 --- a/src/Core/src/Platform/Windows/MauiWinUIWindow.cs +++ b/src/Core/src/Platform/Windows/MauiWinUIWindow.cs @@ -86,6 +86,7 @@ IntPtr NewWindowProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam) NativeMessage?.Invoke(this, args); + Essentials.Platform.NewWindowProc(hWnd, msg, wParam, lParam); return CallWindowProc(oldWndProc, hWnd, msg, wParam, lParam); } diff --git a/src/Essentials/src/DeviceDisplay/DeviceDisplay.uwp.cs b/src/Essentials/src/DeviceDisplay/DeviceDisplay.uwp.cs index d35bd2ad10a2..f610cdfa5615 100644 --- a/src/Essentials/src/DeviceDisplay/DeviceDisplay.uwp.cs +++ b/src/Essentials/src/DeviceDisplay/DeviceDisplay.uwp.cs @@ -49,41 +49,98 @@ public bool KeepScreenOn } } + static DisplayRotation CalculateRotation(DisplayOrientations native, DisplayOrientations current) + { + if (native == DisplayOrientations.Portrait) + { + switch (current) + { + case DisplayOrientations.Landscape: + return DisplayRotation.Rotation90; + case DisplayOrientations.Portrait: + return DisplayRotation.Rotation0; + case DisplayOrientations.LandscapeFlipped: + return DisplayRotation.Rotation270; + case DisplayOrientations.PortraitFlipped: + return DisplayRotation.Rotation180; + } + } + else if (native == DisplayOrientations.Landscape) + { + switch (current) + { + case DisplayOrientations.Landscape: + return DisplayRotation.Rotation0; + case DisplayOrientations.Portrait: + return DisplayRotation.Rotation270; + case DisplayOrientations.LandscapeFlipped: + return DisplayRotation.Rotation180; + case DisplayOrientations.PortraitFlipped: + return DisplayRotation.Rotation90; + } + } + + return DisplayRotation.Unknown; + } + +#if WINDOWS + + AppWindow? _currentAppWindowListeningTo; public DisplayInfo GetMainDisplayInfo() { - var appWindow = GetAppWindowForCurrentWindow(); + var appWindow = Platform.CurrentAppWindow; + var windowHandler = Platform.CurrentWindowHandle; + var mi = GetDisplay(windowHandler); + + if (mi == null) + return new DisplayInfo(); + DEVMODE vDevMode = new DEVMODE(); - EnumDisplaySettings(null!, -1, ref vDevMode); + EnumDisplaySettings(mi.Value.DeviceNameToLPTStr(), -1, ref vDevMode); - var rotation = CalculateRotation(vDevMode); + var rotation = CalculateRotation(vDevMode, appWindow); var perpendicular = rotation == DisplayRotation.Rotation90 || rotation == DisplayRotation.Rotation270; - var w = appWindow.Size.Width; - var h = appWindow.Size.Height; - - - var hdi = HdmiDisplayInformation.GetForCurrentView(); - var hdm = hdi?.GetCurrentDisplayMode(); + var w = vDevMode.dmPelsWidth; + var h = vDevMode.dmPelsHeight; + var dpi = GetDpiForWindow(windowHandler) / 96.0; return new DisplayInfo( width: perpendicular ? h : w, height: perpendicular ? w : h, - density: 999,//di.LogicalDpi / 96.0, TODO FIX - orientation: GetWindowOrientationWin32() == DisplayOrientations.Landscape ? DisplayOrientation.Landscape : DisplayOrientation.Portrait, + density: dpi, + orientation: GetWindowOrientationWin32(appWindow) == DisplayOrientations.Landscape ? DisplayOrientation.Landscape : DisplayOrientation.Portrait, rotation: rotation, - rate: (float)(hdm?.RefreshRate ?? 0)); + rate: vDevMode.dmDisplayFrequency); + } + + static MONITORINFOEX? GetDisplay(IntPtr hwnd) + { + IntPtr hMonitor; + RECT rc; + GetWindowRect(hwnd, out rc); + hMonitor = MonitorFromRect(ref rc, MonitorOptions.MONITOR_DEFAULTTONEAREST); + + MONITORINFOEX mi = new MONITORINFOEX(); + mi.Size = Marshal.SizeOf(mi); + bool success = GetMonitorInfo(hMonitor, ref mi); + if (success) + { + return mi; + } + return null; } public void StartScreenMetricsListeners() { MainThread.BeginInvokeOnMainThread(() => { - var di = DisplayInformation.GetForCurrentView(); - - di.DpiChanged += OnDisplayInformationChanged; - di.OrientationChanged += OnDisplayInformationChanged; + Platform.CurrentWindowDisplayChanged += OnWindowDisplayChanged; + Platform.CurrentWindowChanged += OnCurrentWindowChanged; + _currentAppWindowListeningTo = Platform.CurrentAppWindow; + _currentAppWindowListeningTo.Changed += OnAppWindowChanged; }); } @@ -91,47 +148,51 @@ public void StopScreenMetricsListeners() { MainThread.BeginInvokeOnMainThread(() => { - var di = DisplayInformation.GetForCurrentView(); + Platform.CurrentWindowChanged -= OnCurrentWindowChanged; + Platform.CurrentWindowDisplayChanged -= OnWindowDisplayChanged; - di.DpiChanged -= OnDisplayInformationChanged; - di.OrientationChanged -= OnDisplayInformationChanged; + if (_currentAppWindowListeningTo != null) + _currentAppWindowListeningTo.Changed -= OnAppWindowChanged; + + _currentAppWindowListeningTo = null; }); } - void OnDisplayInformationChanged(DisplayInformation di, object args) + void OnCurrentWindowChanged(object? sender, EventArgs e) { + if (_currentAppWindowListeningTo != null) + { + _currentAppWindowListeningTo.Changed -= OnAppWindowChanged; + } - //var metrics = GetMainDisplayInfo(di); - - // TODO this is just so it compiles - MainDisplayInfoChanged?.Invoke(this, new DisplayInfoChangedEventArgs(new DisplayInfo())); + _currentAppWindowListeningTo = Platform.CurrentAppWindow; + _currentAppWindowListeningTo.Changed += OnAppWindowChanged; } - DisplayOrientation CalculateOrientation(DisplayInformation di) + void OnWindowDisplayChanged(object? sender, EventArgs e) { - switch (di.CurrentOrientation) - { - case DisplayOrientations.Landscape: - case DisplayOrientations.LandscapeFlipped: - return DisplayOrientation.Landscape; - case DisplayOrientations.Portrait: - case DisplayOrientations.PortraitFlipped: - return DisplayOrientation.Portrait; - } + WindowDisplayPropertiesChanged(); + } - return DisplayOrientation.Unknown; + void WindowDisplayPropertiesChanged() + { + var metrics = GetMainDisplayInfo(); + MainDisplayInfoChanged?.Invoke(this, new DisplayInfoChangedEventArgs(metrics)); } - static DisplayRotation CalculateRotation(DEVMODE devMode) + void OnAppWindowChanged(AppWindow sender, AppWindowChangedEventArgs args) => + WindowDisplayPropertiesChanged(); + + static DisplayRotation CalculateRotation(DEVMODE devMode, AppWindow appWindow) { DisplayOrientations native = DisplayOrientations.Portrait; switch (devMode.dmDisplayOrientation) { case 0: - native = DisplayOrientations.Portrait; + native = DisplayOrientations.Landscape; break; case 1: - native = DisplayOrientations.Landscape; + native = DisplayOrientations.Portrait; break; case 2: native = DisplayOrientations.LandscapeFlipped; @@ -141,56 +202,13 @@ static DisplayRotation CalculateRotation(DEVMODE devMode) break; } - var current = GetWindowOrientationWin32(); - - if (native == DisplayOrientations.Portrait) - { - switch (current) - { - case DisplayOrientations.Landscape: - return DisplayRotation.Rotation90; - case DisplayOrientations.Portrait: - return DisplayRotation.Rotation0; - case DisplayOrientations.LandscapeFlipped: - return DisplayRotation.Rotation270; - case DisplayOrientations.PortraitFlipped: - return DisplayRotation.Rotation180; - } - } - else if (native == DisplayOrientations.Landscape) - { - switch (current) - { - case DisplayOrientations.Landscape: - return DisplayRotation.Rotation0; - case DisplayOrientations.Portrait: - return DisplayRotation.Rotation270; - case DisplayOrientations.LandscapeFlipped: - return DisplayRotation.Rotation180; - case DisplayOrientations.PortraitFlipped: - return DisplayRotation.Rotation90; - } - } - - return DisplayRotation.Unknown; + var current = GetWindowOrientationWin32(appWindow); + return CalculateRotation(native, current); } - static AppWindow GetAppWindowForCurrentWindow() - { - var myWndId = Microsoft.UI.Win32Interop.GetWindowIdFromWindow(Essentials.Platform.CurrentWindowHandle); - return AppWindow.GetFromWindowId(myWndId); - } - - [DllImport("User32.dll")] - [return: MarshalAs(UnmanagedType.Bool)] - internal static extern Boolean EnumDisplaySettings( - byte[] lpszDeviceName, - [param: MarshalAs(UnmanagedType.U4)] int iModeNum, - [In, Out] ref DEVMODE lpDevMode); - - static DisplayOrientations GetWindowOrientationWin32() + // https://github.com/marb2000/DesktopWindow/blob/abb21b797767bb24da09c066514117d5f1aabd75/WindowExtensions/DesktopWindow.cs#L407 + static DisplayOrientations GetWindowOrientationWin32(AppWindow appWindow) { - var appWindow = GetAppWindowForCurrentWindow(); DisplayOrientations orientationEnum; int theScreenWidth = appWindow.Size.Width; int theScreenHeight = appWindow.Size.Height; @@ -202,7 +220,81 @@ static DisplayOrientations GetWindowOrientationWin32() return orientationEnum; } - public struct DEVMODE + [DllImport("User32", CharSet = CharSet.Unicode)] + static extern int GetDpiForWindow(IntPtr hwnd); + + [DllImport("User32", CharSet = CharSet.Unicode, SetLastError = true)] + static extern IntPtr MonitorFromRect(ref RECT lprc, MonitorOptions dwFlags); + + [DllImport("User32", CharSet = CharSet.Unicode, SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect); + + [DllImport("User32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + static extern Boolean EnumDisplaySettings( + byte[] lpszDeviceName, + [param: MarshalAs(UnmanagedType.U4)] int iModeNum, + [In, Out] ref DEVMODE lpDevMode); + + [DllImport("user32.dll", CharSet = CharSet.Unicode)] + static extern bool GetMonitorInfo(IntPtr hMonitor, ref MONITORINFOEX lpmi); + + [DllImport("user32.dll")] + static extern bool EnumDisplayMonitors(IntPtr hdc, IntPtr lprcClip, EnumMonitorsDelegate lpfnEnum, IntPtr dwData); + delegate bool EnumMonitorsDelegate(IntPtr hMonitor, IntPtr hdcMonitor, ref RECT lprcMonitor, IntPtr dwData); + + static bool MonitorEnumProc(IntPtr hMonitor, IntPtr hdcMonitor, ref RECT lprcMonitor, IntPtr dwData) + { + MONITORINFOEX mi = new MONITORINFOEX(); + mi.Size = Marshal.SizeOf(typeof(MONITORINFOEX)); + if (GetMonitorInfo(hMonitor, ref mi)) + Console.WriteLine(mi.DeviceName); + + return true; + } + + enum MonitorOptions : uint + { + MONITOR_DEFAULTTONULL, + MONITOR_DEFAULTTOPRIMARY, + MONITOR_DEFAULTTONEAREST + } + + [StructLayout(LayoutKind.Sequential)] + struct RECT + { + public int Left; + public int Top; + public int Right; + public int Bottom; + } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + struct MONITORINFOEX + { + public int Size; + public RECT Monitor; + public RECT WorkArea; + public uint Flags; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)] + public string DeviceName; + + public byte[] DeviceNameToLPTStr() + { + var lptArray = new byte[DeviceName.Length + 1]; + + var index = 0; + foreach (char c in DeviceName.ToCharArray()) + lptArray[index++] = Convert.ToByte(c); + + lptArray[index] = Convert.ToByte('\0'); + + return lptArray; + } + } + + struct DEVMODE { private const int CCHDEVICENAME = 0x20; private const int CCHFORMNAME = 0x20; @@ -239,5 +331,85 @@ public struct DEVMODE public int dmPanningWidth; public int dmPanningHeight; } +#elif WINDOWS_UWP + public DisplayInfo GetMainDisplayInfo() => + GetMainDisplayInfo(null); + + DisplayInfo GetMainDisplayInfo(DisplayInformation? di = null) + { + di ??= DisplayInformation.GetForCurrentView(); + + var rotation = CalculateRotation(di); + var perpendicular = + rotation == DisplayRotation.Rotation90 || + rotation == DisplayRotation.Rotation270; + + var w = di.ScreenWidthInRawPixels; + var h = di.ScreenHeightInRawPixels; + + var hdi = HdmiDisplayInformation.GetForCurrentView(); + var hdm = hdi?.GetCurrentDisplayMode(); + + return new DisplayInfo( + width: perpendicular ? h : w, + height: perpendicular ? w : h, + density: di.LogicalDpi / 96.0, + orientation: CalculateOrientation(di), + rotation: rotation, + rate: (float)(hdm?.RefreshRate ?? 0)); + } + + public void StartScreenMetricsListeners() + { + MainThread.BeginInvokeOnMainThread(() => + { + var di = DisplayInformation.GetForCurrentView(); + + di.DpiChanged += OnDisplayInformationChanged; + di.OrientationChanged += OnDisplayInformationChanged; + }); + } + + public void StopScreenMetricsListeners() + { + MainThread.BeginInvokeOnMainThread(() => + { + var di = DisplayInformation.GetForCurrentView(); + + di.DpiChanged -= OnDisplayInformationChanged; + di.OrientationChanged -= OnDisplayInformationChanged; + }); + } + + void OnDisplayInformationChanged(DisplayInformation di, object args) + { + var metrics = GetMainDisplayInfo(di); + MainDisplayInfoChanged?.Invoke(this, new DisplayInfoChangedEventArgs(metrics)); + } + + DisplayOrientation CalculateOrientation(DisplayInformation di) + { + switch (di.CurrentOrientation) + { + case DisplayOrientations.Landscape: + case DisplayOrientations.LandscapeFlipped: + return DisplayOrientation.Landscape; + case DisplayOrientations.Portrait: + case DisplayOrientations.PortraitFlipped: + return DisplayOrientation.Portrait; + } + + return DisplayOrientation.Unknown; + } + + static DisplayRotation CalculateRotation(DisplayInformation di) + { + var native = di.NativeOrientation; + var current = di.CurrentOrientation; + + return CalculateRotation(native, current); + } + } +#endif } } diff --git a/src/Essentials/src/Platform/Platform.uwp.cs b/src/Essentials/src/Platform/Platform.uwp.cs index 940e42b22120..58320edc0abd 100644 --- a/src/Essentials/src/Platform/Platform.uwp.cs +++ b/src/Essentials/src/Platform/Platform.uwp.cs @@ -5,6 +5,7 @@ using WindowActivationState = Windows.UI.Core.CoreWindowActivationState; #elif WINDOWS using System; +using Microsoft.UI.Windowing; using Microsoft.UI.Xaml; #endif @@ -12,15 +13,54 @@ namespace Microsoft.Maui.Essentials { public static partial class Platform { + const uint DISPLAY_CHANGED = 126; + const uint DPI_CHANGED = 126; + + static internal event EventHandler CurrentWindowChanged; + static internal event EventHandler CurrentWindowDisplayChanged; + internal static Window CurrentWindow { get => _currentWindow ?? Window.Current; - set => _currentWindow = value; + set + { + bool changed = _currentWindow != value; + _currentWindow = value; + + if(changed) + CurrentWindowChanged?.Invoke(value, EventArgs.Empty); + } } internal static IntPtr CurrentWindowHandle => WinRT.Interop.WindowNative.GetWindowHandle(CurrentWindow); - +#if WINDOWS + internal static UI.WindowId CurrentWindowId + => UI.Win32Interop.GetWindowIdFromWindow(CurrentWindowHandle); + + internal static AppWindow CurrentAppWindow + => AppWindow.GetFromWindowId(CurrentWindowId); + + // Currently there isn't a way to detect Orientation Changes unless you subclass the WinUI.Window and watch the messages + // Maui.Core forwards these messages to here so that WinUI can react accordingly. + // This is the "subtlest" way to currently wire this together. + // Hopefully there will be a more public API for this down the road so we can just use that directly from Essentials + internal static void NewWindowProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam) + { + if (CurrentWindowDisplayChanged == null) + return; + + // We only care about orientation or dpi changes + if (DISPLAY_CHANGED != msg && DPI_CHANGED != msg) + return; + + if (_currentWindow != null && hWnd == CurrentWindowHandle) + { + CurrentWindowDisplayChanged?.Invoke(CurrentWindow, EventArgs.Empty); + } + } +#endif + internal const string AppManifestFilename = "AppxManifest.xml"; internal const string AppManifestXmlns = "http://schemas.microsoft.com/appx/manifest/foundation/windows10"; internal const string AppManifestUapXmlns = "http://schemas.microsoft.com/appx/manifest/uap/windows10"; @@ -34,7 +74,9 @@ public static async void OnLaunched(LaunchActivatedEventArgs e) public static void OnActivated(Window window, WindowActivatedEventArgs args) { if (args.WindowActivationState != WindowActivationState.Deactivated) + { CurrentWindow = window; + } } } } diff --git a/src/Essentials/src/Properties/AssemblyInfo.uwp.cs b/src/Essentials/src/Properties/AssemblyInfo.uwp.cs new file mode 100644 index 000000000000..c254f190c6c2 --- /dev/null +++ b/src/Essentials/src/Properties/AssemblyInfo.uwp.cs @@ -0,0 +1,3 @@ +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("Microsoft.Maui")] From ca4892b332aa9b156cb6c6a5ebe9badb36c24508 Mon Sep 17 00:00:00 2001 From: Shane Neuville Date: Mon, 13 Dec 2021 15:09:59 -0600 Subject: [PATCH 4/5] Update Platform.uwp.cs --- src/Essentials/src/Platform/Platform.uwp.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Essentials/src/Platform/Platform.uwp.cs b/src/Essentials/src/Platform/Platform.uwp.cs index 58320edc0abd..659f9514de21 100644 --- a/src/Essentials/src/Platform/Platform.uwp.cs +++ b/src/Essentials/src/Platform/Platform.uwp.cs @@ -14,7 +14,7 @@ namespace Microsoft.Maui.Essentials public static partial class Platform { const uint DISPLAY_CHANGED = 126; - const uint DPI_CHANGED = 126; + const uint DPI_CHANGED = 736; static internal event EventHandler CurrentWindowChanged; static internal event EventHandler CurrentWindowDisplayChanged; From ff2a3edaae89c9fa26f435750cfcce3d6010c563 Mon Sep 17 00:00:00 2001 From: Redth Date: Fri, 17 Dec 2021 10:27:16 -0500 Subject: [PATCH 5/5] Add app.manifest to essentials sample for better DPI --- .../Samples/Platforms/Windows/app.manifest | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 src/Essentials/samples/Samples/Platforms/Windows/app.manifest diff --git a/src/Essentials/samples/Samples/Platforms/Windows/app.manifest b/src/Essentials/samples/Samples/Platforms/Windows/app.manifest new file mode 100644 index 000000000000..4c44e1f9c8e2 --- /dev/null +++ b/src/Essentials/samples/Samples/Platforms/Windows/app.manifest @@ -0,0 +1,15 @@ + + + + + + + + true/PM + PerMonitorV2, PerMonitor + + +