WinForm多屏幕选择器按钮布局匹配系统配置问题求助
WinForm屏幕选择按钮布局不匹配系统配置
在Windows 11家庭版环境下,使用C# WinForm(.NET 8.0)开发一款支持物理屏幕选择的App Launcher,当前无法实现与系统屏幕布局一致的按钮排布:期望按钮分布匹配实际屏幕配置,但实际效果不符。
未解决问题
- 按钮顺序错误
- 按钮布局无法匹配系统配置
当前最接近预期的代码
using System.Runtime.InteropServices; namespace WebStack_Deployer_for_Docker.Forms { public partial class DisplaySelector : Form { private const int SW_SHOWNORMAL = 1; [StructLayout(LayoutKind.Sequential)] private struct POINT { public int X; public int Y; } [StructLayout(LayoutKind.Sequential)] private struct RECT { public int Left; public int Top; public int Right; public int Bottom; } [StructLayout(LayoutKind.Sequential)] private struct WINDOWPLACEMENT { public int length; public int flags; public int showCmd; public POINT ptMinPosition; public POINT ptMaxPosition; public RECT rcNormalPosition; } public readonly int screens = Screen.AllScreens.Length; private Panel panelMonitors; private const int ButtonWidth = 160; private const int ButtonHeight = 100; public DisplaySelector() { InitializeComponent(); InitializeMonitorSelection(); } private void InitializeMonitorSelection() { panelMonitors = new Panel { Dock = DockStyle.Fill }; Controls.Add(panelMonitors); Screen[] allScreens = Screen.AllScreens; Array.Sort(allScreens, (a, b) => a.Bounds.X.CompareTo(b.Bounds.X)); int totalScreens = allScreens.Length; int startX = (ClientSize.Width - totalScreens * (ButtonWidth + 20)) / 2; int startY = (ClientSize.Height - ButtonHeight) / 2; for (int i = 0; i < totalScreens; i++) { int monitorIndex = i; Button monitorButton = new Button { Text = $"Pantalla #{monitorIndex + 1}", Tag = monitorIndex, Size = new Size(ButtonWidth, ButtonHeight), // Calcula la posición X y Y del botón de acuerdo a la disposición real de las pantallas Location = CalculateButtonPosition(startX, startY, monitorIndex, totalScreens, ButtonWidth) }; monitorButton.Click += MonitorButton_Click; panelMonitors.Controls.Add(monitorButton); } } private Point CalculateButtonPosition(int startX, int startY, int monitorIndex, int totalScreens, int buttonWidth) { int positionX = startX; if (monitorIndex > 0) { positionX += (buttonWidth + 20) * monitorIndex; } int positionY = startY; if (totalScreens > 1) { if (monitorIndex == 0) { positionY -= ButtonHeight / 2 + 20; } else if (monitorIndex == totalScreens - 1) { positionY += ButtonHeight / 2 + 20; } } return new Point(positionX, positionY); } private void MonitorButton_Click(object sender, EventArgs e) { Button clickedButton = (Button)sender; int monitorIndex = (int)clickedButton.Tag; MessageBox.Show($"Has seleccionado el Monitor #{monitorIndex}"); MoveToDisplay(monitorIndex); } public static void MoveToDisplay(int display) { if (Screen.AllScreens.Length > 1) { IntPtr windowHandle = GetForegroundWindow(); WINDOWPLACEMENT placement = new WINDOWPLACEMENT { length = Marshal.SizeOf(typeof(WINDOWPLACEMENT)) }; GetWindowPlacement(windowHandle, ref placement); Rectangle secondMonitor = Screen.AllScreens[display].WorkingArea; int windowWidth = placement.rcNormalPosition.Right - placement.rcNormalPosition.Left; int windowHeight = placement.rcNormalPosition.Bottom - placement.rcNormalPosition.Top; int windowLeft = secondMonitor.Left + (secondMonitor.Width - windowWidth) / 2; int windowTop = secondMonitor.Top + (secondMonitor.Height - windowHeight) / 2; placement.rcNormalPosition.Left = windowLeft; placement.rcNormalPosition.Top = windowTop; placement.rcNormalPosition.Right = windowLeft + windowWidth; placement.rcNormalPosition.Bottom = windowTop + windowHeight; placement.showCmd = SW_SHOWNORMAL; SetWindowPlacement(windowHandle, ref placement); } } [DllImport("user32.dll")] private static extern IntPtr GetForegroundWindow(); [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl); [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool SetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl); } }
内容的提问来源于stack exchange,提问作者user22473069
相关产品推荐
相关产品推荐

