//Except where stated all code and programs in this project are the copyright of Jim Blackler, 2008. //jimblackler@gmail.com // //This is free software. Libraries and programs are distributed under the terms of the GNU Lesser //General Public License. Please see the files COPYING and COPYING.LESSER. using System; using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.Design; using System.Drawing; using System.Windows.Forms; namespace MiscControls { /// /// A control that sizes all sub-controls on a parent form proportionally /// public partial class FormScaler : Component { /// /// Record of the parent form /// [Browsable(false)] [DefaultValue("")] public Control ParentControl { get { // Designer code ... set the form if ((parentControl == null) && DesignMode) { IDesignerHost host = (IDesignerHost)GetService(typeof(IDesignerHost)); if (host != null) { parentControl = host.RootComponent as Control; } } return parentControl; } set { if (parentControl != value) { // Quite a bit of setup is done as soon as we know the parent form parentControl = value; parentControl.FindForm().Load += new EventHandler(FormScaler_Load); parentControl.Resize += new EventHandler(parentControl_Resize); } } } /// /// Called to record the positions of the controls after the client window is initialised /// void FormScaler_Load(object sender, EventArgs e) { originalWidth = parentControl.ClientRectangle.Width; originalHeight = parentControl.ClientRectangle.Height; // record the original positions of the controls originalSizesAndPositions = new List(); Control.ControlCollection collection = parentControl.Controls; RecordControlCollection(collection); } private void RecordControlCollection(Control.ControlCollection collection) { foreach (Control control in collection) { if (control as MenuStrip == null) { OriginalSizeAndPosition originalSizeAndPosition = new OriginalSizeAndPosition(); originalSizeAndPosition.originalWidth = control.Size.Width; originalSizeAndPosition.originalHeight = control.Size.Height; originalSizeAndPosition.originalX = control.Location.X; originalSizeAndPosition.originalY = control.Location.Y; originalSizeAndPosition.originalFontSize = control.Font.Size; originalSizeAndPosition.control = control; originalSizesAndPositions.Add(originalSizeAndPosition); RecordControlCollection(control.Controls); } } } /// /// Size the parent control proportionally /// void parentControl_Resize(object sender, EventArgs e) { if (originalSizesAndPositions == null) { return; } else { if (previousWidth != parentControl.ClientRectangle.Width || previousHeight != parentControl.ClientRectangle.Height) { int currentWidth = parentControl.ClientRectangle.Width; int currentHeight = parentControl.ClientRectangle.Height; if (currentWidth > 0 && currentHeight > 0) { int topOffset; Form clientForm = parentControl as Form; if (clientForm == null) { topOffset = 0; } else { topOffset = clientForm.MainMenuStrip.Height; } float propX = (float)currentWidth / originalWidth; float propY = (float)(currentHeight - topOffset) / (originalHeight - topOffset); parentControl.SuspendLayout(); foreach (OriginalSizeAndPosition originalSizeAndPosition in originalSizesAndPositions) { originalSizeAndPosition.control.SetBounds((int)(propX * originalSizeAndPosition.originalX), (int)(topOffset + propY * (originalSizeAndPosition.originalY - topOffset)), (int)(propX * originalSizeAndPosition.originalWidth), (int)(propY * originalSizeAndPosition.originalHeight)); originalSizeAndPosition.control.Font = new Font(originalSizeAndPosition.control.Font.FontFamily, Math.Min(propX, propY) * originalSizeAndPosition.originalFontSize, originalSizeAndPosition.control.Font.Unit); } parentControl.ResumeLayout(); } previousWidth = currentWidth; previousHeight = currentHeight; } return; } } // Fields follow private Control parentControl; private List originalSizesAndPositions; private int originalWidth; private int originalHeight; private int previousWidth; private int previousHeight; /// /// A record of the original bounds stored for each child control /// class OriginalSizeAndPosition { public int originalWidth; public int originalHeight; public int originalX; public int originalY; public float originalFontSize; public Control control; } } }