MAUI如何检测Windows PC所有屏幕?实现自定义屏幕弹窗需求
解决MAUI Windows平台多屏检测与窗口定位问题
由于MAUI的Microsoft.Maui.Devices.DeviceDisplay仅提供主屏幕信息,要实现多屏检测和指定屏幕显示窗口,需借助Windows原生API实现平台特定逻辑,以下是两种可行方案:
方案一:使用Win32 API枚举显示器
通过EnumDisplayMonitors Win32函数枚举所有连接的显示器,获取每个屏幕的分辨率、位置等信息。
步骤1:定义Win32结构体与导入函数
在Windows平台项目中添加以下代码:
using System.Runtime.InteropServices; public static class Win32DisplayHelper { [StructLayout(LayoutKind.Sequential)] public struct RECT { public int Left; public int Top; public int Right; public int Bottom; } [StructLayout(LayoutKind.Sequential)] public struct MONITORINFOEX { public int cbSize; public RECT rcMonitor; public RECT rcWork; public uint dwFlags; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] public string szDevice; } public delegate bool MonitorEnumDelegate(IntPtr hMonitor, IntPtr hdcMonitor, ref RECT lprcMonitor, IntPtr dwData); [DllImport("user32.dll")] public static extern bool EnumDisplayMonitors(IntPtr hdc, IntPtr lprcClip, MonitorEnumDelegate lpfnEnum, IntPtr dwData); [DllImport("user32.dll")] public static extern bool GetMonitorInfo(IntPtr hMonitor, ref MONITORINFOEX lpmi); }
步骤2:枚举所有屏幕信息
编写方法获取所有屏幕的详细信息:
public List<(string DeviceName, int Width, int Height, int Left, int Top)> GetAllScreens() { var screens = new List<(string, int, int, int, int)>(); Win32DisplayHelper.MonitorEnumDelegate enumDelegate = (hMonitor, hdcMonitor, ref Win32DisplayHelper.RECT lprcMonitor, IntPtr dwData) => { var monitorInfo = new Win32DisplayHelper.MONITORINFOEX(); monitorInfo.cbSize = Marshal.SizeOf(monitorInfo); Win32DisplayHelper.GetMonitorInfo(hMonitor, ref monitorInfo); int width = monitorInfo.rcMonitor.Right - monitorInfo.rcMonitor.Left; int height = monitorInfo.rcMonitor.Bottom - monitorInfo.rcMonitor.Top; screens.Add((monitorInfo.szDevice, width, height, monitorInfo.rcMonitor.Left, monitorInfo.rcMonitor.Top)); return true; }; Win32DisplayHelper.EnumDisplayMonitors(IntPtr.Zero, IntPtr.Zero, enumDelegate, IntPtr.Zero); return screens; }
方案二:使用Windows App SDK的DisplayManager
借助Windows App SDK的DisplayManager类获取显示设备信息,更适配现代Windows应用:
步骤1:安装Windows App SDK NuGet包
在项目中安装Microsoft.WindowsAppSDK包。
步骤2:获取所有显示设备
using Windows.Devices.Display; using Windows.Devices.Display.Core; public async Task<List<(string DisplayId, int Width, int Height)>> GetAllDisplaysAsync() { var displays = new List<(string, int, int)>(); var displayManager = DisplayManager.GetForCurrentView(); await displayManager.RequestStartAsync(); foreach (var display in displayManager.GetCurrentDisplays()) { var resolution = display.CurrentMode.NativeResolution; displays.Add((display.DisplayId.ToString(), resolution.Width, resolution.Height)); } await displayManager.RequestStopAsync(); return displays; }
将窗口定位到指定屏幕
获取屏幕信息后,可通过Win32 API移动MAUI窗口到目标屏幕:
using System.Runtime.InteropServices; public static class WindowHelper { [DllImport("user32.dll")] public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags); private const uint SWP_NOSIZE = 0x0001; private const uint SWP_NOZORDER = 0x0004; public static void MoveWindowToScreen(IntPtr windowHandle, int left, int top) { SetWindowPos(windowHandle, IntPtr.Zero, left, top, 0, 0, SWP_NOSIZE | SWP_NOZORDER); } } // 在MAUI中调用: var windowHandle = Window.Handler.PlatformView.Handle; // 获取当前窗口句柄 var targetScreen = GetAllScreens().First(s => s.DeviceName == "\\\\.\\DISPLAY2"); // 选择目标屏幕 WindowHelper.MoveWindowToScreen(windowHandle, targetScreen.Left, targetScreen.Top);
内容的提问来源于stack exchange,提问作者user251395
相关产品推荐
相关产品推荐

