我有 2 台显示器,我需要保存表单位置,它应该在屏幕上显示它关闭的位置。
有人可以建议如何获取它所在的屏幕,并在表单加载时在表单关闭的屏幕上显示它吗?
我保存在注册表中的设置。
最简单的方法是调用GetWindowPlacement
函数。这将返回一个包含有关窗口屏幕坐标信息的WINDOWPLACEMENT
结构。
使用此功能而不是该Form.Location
属性可以解决您在使用多个显示器、最小化窗口、位置奇怪的任务栏等时遇到的问题。
攻击路线是在您的应用程序关闭时调用该GetWindowPlacement
函数,将窗口的位置保存到注册表(或您存储它的任何地方 - 注册表不再是保存应用程序状态的推荐位置),然后当您的应用程序重新打开时,调用相应的SetWindowPlacement
函数将窗口恢复到之前的位置。
由于这些是 Win32 API 公开的本机函数,并且您使用 C# 工作,因此您需要通过 P/Invoke 调用它们。以下是必需的定义(出于组织目的,我建议将它们放在名为 的静态类中NativeMethods
):
[StructLayout(LayoutKind.Sequential)]
struct POINT
{
public int X;
public int Y;
}
[StructLayout(LayoutKind.Sequential)]
struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
}
[Serializable]
[StructLayout(LayoutKind.Sequential)]
struct WINDOWPLACEMENT
{
public int length;
public int flags;
public int showCmd;
public POINT ptMinPosition;
public POINT ptMaxPosition;
public RECT rcNormalPosition;
}
[DllImport("user32", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);
[DllImport("user32", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);
要获取窗口的当前位置(在您的应用程序关闭时执行此操作),请使用以下代码:
WINDOWPLACEMENT wp = new WINDOWPLACEMENT();
wp.length = Marshal.SizeOf(wp);
GetWindowPlacement(MyForm.Handle, ref wp);
回想一下,我提到注册表不再是持久化应用程序状态的推荐位置。由于您是在 .NET 中进行开发的,因此您可以使用更强大、更通用的选项。并且由于WINDOWPLACEMENT
上面声明的类被标记[Serializable]
,因此很容易将这些信息序列化到您的应用程序设置中,然后在您下次打开时重新加载它。
我多次实现了类似的功能。您所要做的就是在表单关闭时保存和属性Form.WindowState
,并在表单打开时恢复它们。Form.Size
Form.Loaction