using System; using System.Drawing; using System.Windows.Forms; using System.Runtime.InteropServices; using Microsoft.Win32; namespace Common { class FormDimensions { public Form Form; public string RegSubKey; public FormWindowState DefaultFormWindowState = FormWindowState.Normal; [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl); public FormDimensions() { RegSubKey = "Forms"; } private struct WINDOWPLACEMENT { public int length; public int flags; public int showCmd; public System.Drawing.Point ptMinPosition; public System.Drawing.Point ptMaxPosition; public System.Drawing.Rectangle rcNormalPosition; } const UInt32 SW_HIDE = 0; const UInt32 SW_SHOWNORMAL = 1; const UInt32 SW_NORMAL = 1; const UInt32 SW_SHOWMINIMIZED = 2; const UInt32 SW_SHOWMAXIMIZED = 3; const UInt32 SW_MAXIMIZE = 3; const UInt32 SW_SHOWNOACTIVATE = 4; const UInt32 SW_SHOW = 5; const UInt32 SW_MINIMIZE = 6; const UInt32 SW_SHOWMINNOACTIVE = 7; const UInt32 SW_SHOWNA = 8; const UInt32 SW_RESTORE = 9; private WINDOWPLACEMENT GetPlacement(Form form) { WINDOWPLACEMENT placement = new WINDOWPLACEMENT(); placement.length = Marshal.SizeOf(placement); GetWindowPlacement(form.Handle, ref placement); return placement; } private bool IsVisibleOnAnyScreen(Rectangle rect) { int minVisible = 50; foreach (Screen screen in Screen.AllScreens) { Rectangle visibleArea = screen.WorkingArea; visibleArea.Intersect(rect); if ((visibleArea.Width > minVisible) && (visibleArea.Height > minVisible) && (rect.Top >= 0)) { return true; } } return false; } public void Load(Form form, Form parentForm = null) { this.Form = form; RegistryKey regKey = Application.UserAppDataRegistry.OpenSubKey(RegSubKey + "\\" + form.Name); if (regKey == null) regKey = Application.UserAppDataRegistry.CreateSubKey(RegSubKey + "\\" + form.Name); string name = ""; if (parentForm != null) name = parentForm.Name; bool prevVisibleState = form.Visible; form.Visible = false; Rectangle windowPosition = form.DesktopBounds; Rectangle restoreBounds = form.RestoreBounds; if (parentForm != null) { // Set default form position centered to parent form Point currentParentFormCenter = parentForm.DesktopBounds.Center(); windowPosition.X = currentParentFormCenter.X - windowPosition.Width / 2; windowPosition.Y = currentParentFormCenter.Y - windowPosition.Height / 2; restoreBounds.X = currentParentFormCenter.X - restoreBounds.Width / 2; restoreBounds.Y = currentParentFormCenter.Y - restoreBounds.Height / 2; } windowPosition = new Rectangle( (int)regKey.GetValue("DesktopBoundsLeft" + name, windowPosition.Left), (int)regKey.GetValue("DesktopBoundsTop" + name, windowPosition.Top), (int)regKey.GetValue("DesktopBoundsWidth" + name, windowPosition.Width), (int)regKey.GetValue("DesktopBoundsHeight" + name, windowPosition.Height)); restoreBounds = new Rectangle( (int)regKey.GetValue("RestoreBoundsLeft" + name, restoreBounds.Left), (int)regKey.GetValue("RestoreBoundsTop" + name, restoreBounds.Top), (int)regKey.GetValue("RestoreBoundsWidth" + name, restoreBounds.Width), (int)regKey.GetValue("RestoreBoundsHeight" + name, restoreBounds.Height)); FormWindowState windowState = (FormWindowState)regKey.GetValue("State" + name, (int)DefaultFormWindowState); if (parentForm != null) { Rectangle parentBounds = new Rectangle( (int)regKey.GetValue("ParentBoundsLeft" + name, parentForm.DesktopBounds.Left), (int)regKey.GetValue("ParentBoundsTop" + name, parentForm.DesktopBounds.Top), (int)regKey.GetValue("ParentBoundsWidth" + name, parentForm.DesktopBounds.Width), (int)regKey.GetValue("ParentBoundsHeight" + name, parentForm.DesktopBounds.Height)); Point currentParentFormCenter = parentForm.DesktopBounds.Center(); Point previousParentFormCenter = parentBounds.Center(); Point parentShift = Point.Subtract(currentParentFormCenter, new Size(previousParentFormCenter)); windowPosition.Offset(parentShift); } switch (windowState) { case FormWindowState.Normal: form.WindowState = FormWindowState.Normal; if ((windowPosition != Rectangle.Empty) && IsVisibleOnAnyScreen(windowPosition)) { form.DesktopBounds = windowPosition; } form.WindowState = windowState; break; case FormWindowState.Minimized: form.WindowState = FormWindowState.Normal; if ((windowPosition != Rectangle.Empty) && IsVisibleOnAnyScreen(restoreBounds)) { form.DesktopBounds = restoreBounds; } break; case FormWindowState.Maximized: form.WindowState = FormWindowState.Normal; if ((windowPosition != Rectangle.Empty) && IsVisibleOnAnyScreen(restoreBounds)) { form.DesktopBounds = restoreBounds; } form.WindowState = FormWindowState.Maximized; break; default: break; } form.Visible = prevVisibleState; LoadControl(form); } public void Save(Form form, Form parentForm = null) { this.Form = form; RegistryKey regKey = Application.UserAppDataRegistry.OpenSubKey(RegSubKey + "\\" + form.Name, true); if (regKey == null) regKey = Application.UserAppDataRegistry.CreateSubKey(RegSubKey + "\\" + form.Name); string name = ""; if (parentForm != null) name = parentForm.Name; WINDOWPLACEMENT placement = GetPlacement(form); const int WPF_RESTORETOMAXIMIZED = 0x2; if ((form.WindowState == FormWindowState.Minimized) && ((placement.flags | WPF_RESTORETOMAXIMIZED) != WPF_RESTORETOMAXIMIZED)) { regKey.SetValue("State" + name, (int)FormWindowState.Minimized); } else { regKey.SetValue("State" + name, (int)form.WindowState); } regKey.SetValue("DesktopBoundsLeft" + name, form.DesktopBounds.Left); regKey.SetValue("DesktopBoundsTop" + name, form.DesktopBounds.Top); regKey.SetValue("DesktopBoundsWidth" + name, form.DesktopBounds.Width); regKey.SetValue("DesktopBoundsHeight" + name, form.DesktopBounds.Height); regKey.SetValue("RestoreBoundsLeft" + name, form.RestoreBounds.Left); regKey.SetValue("RestoreBoundsTop" + name, form.RestoreBounds.Top); regKey.SetValue("RestoreBoundsWidth" + name, form.RestoreBounds.Width); regKey.SetValue("RestoreBoundsHeight" + name, form.RestoreBounds.Height); if (parentForm != null) { regKey.SetValue("ParentBoundsLeft" + name, parentForm.DesktopBounds.Left); regKey.SetValue("ParentBoundsTop" + name, parentForm.DesktopBounds.Top); regKey.SetValue("ParentBoundsWidth" + name, parentForm.DesktopBounds.Width); regKey.SetValue("ParentBoundsHeight" + name, parentForm.DesktopBounds.Height); } SaveControl(form); } public void LoadControl(Control control) { if (control is ListView) { RegistryKey regKey = Application.UserAppDataRegistry.OpenSubKey(RegSubKey + "\\" + Form.Name + "\\" + control.Name, true); if (regKey == null) regKey = Application.UserAppDataRegistry.CreateSubKey(RegSubKey + "\\" + Form.Name + "\\" + control.Name); for (int I = 0; I < (control as ListView).Columns.Count; I++) { if (regKey.GetValue("ColWidth" + I.ToString()) != null) (control as ListView).Columns[I].Width = (int) regKey.GetValue("ColWidth" + I.ToString()); } } else if (control is DataGridView) { RegistryKey regKey = Application.UserAppDataRegistry.OpenSubKey(RegSubKey + "\\" + Form.Name + "\\" + control.Name, true); if (regKey == null) regKey = Application.UserAppDataRegistry.CreateSubKey(RegSubKey + "\\" + Form.Name + "\\" + control.Name); for (int I = 0; I < (control as DataGridView).Columns.Count; I++) { if (regKey.GetValue("ColWidth" + I.ToString()) != null) (control as DataGridView).Columns[I].Width = (int)regKey.GetValue("ColWidth" + I.ToString()); } } if (control is SplitContainer) { RegistryKey regKey = Application.UserAppDataRegistry.OpenSubKey(RegSubKey + "\\" + Form.Name + "\\" + control.Name, true); if (regKey == null) regKey = Application.UserAppDataRegistry.CreateSubKey(RegSubKey + "\\" + Form.Name + "\\" + control.Name); if (regKey.GetValue("SplitterDistance") != null) (control as SplitContainer).SplitterDistance = (int)regKey.GetValue("SplitterDistance"); } foreach (Control child in control.Controls) { LoadControl(child); } } public void SaveControl(Control control) { if (control is ListView) { RegistryKey regKey = Application.UserAppDataRegistry.OpenSubKey(RegSubKey + "\\" + Form.Name + "\\" + control.Name, true); if (regKey == null) regKey = Application.UserAppDataRegistry.CreateSubKey(RegSubKey + "\\" + Form.Name + "\\" + control.Name); for (int I = 0; I < (control as ListView).Columns.Count; I++) { regKey.SetValue("ColWidth" + I.ToString(), (control as ListView).Columns[I].Width); } } else if (control is DataGridView) { RegistryKey regKey = Application.UserAppDataRegistry.OpenSubKey(RegSubKey + "\\" + Form.Name + "\\" + control.Name, true); if (regKey == null) regKey = Application.UserAppDataRegistry.CreateSubKey(RegSubKey + "\\" + Form.Name + "\\" + control.Name); for (int I = 0; I < (control as DataGridView).Columns.Count; I++) { regKey.SetValue("ColWidth" + I.ToString(), (control as DataGridView).Columns[I].Width); } } if (control is SplitContainer) { RegistryKey regKey = Application.UserAppDataRegistry.OpenSubKey(RegSubKey + "\\" + Form.Name + "\\" + control.Name, true); if (regKey == null) regKey = Application.UserAppDataRegistry.CreateSubKey(RegSubKey + "\\" + Form.Name + "\\" + control.Name); regKey.SetValue("SplitterDistance", (control as SplitContainer).SplitterDistance); } foreach (Control child in control.Controls) { SaveControl(child); } } } public static class RectangleExt { public static Point Center(this Rectangle rect) { return new Point(rect.Left + rect.Width / 2, rect.Top + rect.Height / 2); } } }