我无法根据我的屏幕布局获得按钮布局(使用按钮进行模拟).
我希望能够获得与屏幕上现有按钮类似的相同分布的按钮.
相反,我得到了这样的结论:
我目前的脚本是这样的(这是我实现的最接近最终布局的脚本):
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);
}
}
100我用C#/WinForm在Windows 11家用PC上为.net8.0编写了这个程序.
100
- 按钮的顺序.
- 与系统中建立的配置类似的按钮布局.