读书笔记:窗口位置的保存和恢复
这个保存和恢复指的不同的执行之间,如果想要程序在下一次运行的时候显示在本次运行的相同位置,那么就需要通过一个合适的方法将这些信息保存在合适的位置,虽然保存到文件也不错,不过注册表似乎更方便一点。
直接保存高度、宽度和位置很简单,只是,如果进行保存操作的时候,窗口处于最大化或最小化的状态,那么,下一次进行恢复的时候,可能就无法以正确的并且正常的尺寸显示了,这里还是需要使用两个Windows API函数:
[DllImport("user32.dll")]
private static extern bool GetWindowPlacement(IntPtr handle,
ref ManagedWindowPlacement placement);
[DllImport("user32.dll")]
private static extern bool SetWindowPlacement(IntPtr handle,
ref ManagedWindowPlacement placement);
只是,这一次有一点麻烦:这两个函数的参数中包含有一个结构。在能够使用这两个函数之前,先要正确地定义好这个结构:
[Serializable]
[StructLayout(LayoutKind.Sequential)]
private class ManagedPt
{
public int X = 0;
public int Y = 0;
public ManagedPt()
{
}
public ManagedPt(int x, int y)
{
X = x;
Y = y;
}
}
[Serializable]
[StructLayout(LayoutKind.Sequential)]
private class ManagedRect
{
public int X = 0;
public int Y = 0;
public int Right = 0;
public int Bottom = 0;
public ManagedRect()
{
}
public ManagedRect(int x, int y, int right, int bottom)
{
X = x;
Y = y;
Right = right;
Bottom = bottom;
}
}
[Serializable]
[StructLayout(LayoutKind.Sequential)]
private class ManagedWindowPlacement
{
public uint Length = 0;
public uint Flags = 0;
public uint ShowCmd = 0;
public ManagedPt MinPosition = null;
public ManagedPt MaxPosition = null;
public ManagedRect NormalPosition = null;
public ManagedWindowPlacement()
{
Length = (uint)Marshal.SizeOf(this);
}
}
现在只剩下了最后一个问题:序列化与反序列化。既然是保存的对象,要恢复的自然也是对象:
ManagedWindowPlacement placement = new ManagedWindowPlacement();
GetWindowPlacement(frm.Handle, ref placement);
// 序列化
MemoryStream ms = new MemoryStream();
BinaryFormatter f = new BinaryFormatter();
f.Serialize(ms, placement);
//将ms的内容保存就是了
...
MemoryStream ms = new MemoryStream((byte[])key.GetValue("Placement"));
//这个是从注册表中提取的,也可以是其他位置
BinaryFormatter f = new BinaryFormatter();
ManagedWindowPlacement placement = (ManagedWindowPlacement)
f.Deserialize(ms);//反序列化
SetWindowPlacement(frm.Handle, ref placement);

浙公网安备 33010602011771号