

Introduction
I looked for a code that resizes and positions all controls of a form relative to the form's real size. I found no code for the same on the internet, and decided to share my code with you. This code uses the resize_begin and resize_end values of the form to get the width and height of the form, and after the form resize, it resizes all controls and their child controls in a recursive fashion. Also, I added some code to avoid flickering and to refresh the form (will take some time).
Using the code
First, we will look at the variables to add to the form for the x, y position and the width, height of the form before it is changed. Use DllImport of SendMessage to stop the window message REDRAW.
private int xBefore = 0;
private int yBefore = 0;
private int widthBefore = 0;
private int heightBefore = 0;
private const int WM_SETREDRAW = 0xB;
[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int Msg,
int wParam, int lParam);
In the ResizeBegin event that will occur when the form changes its size, add the following code:
private void frmDynamicResize_ResizeBegin(object sender, EventArgs e)
{
xBefore = this.Left;
yBefore = this.Top;
heightBefore = this.Height;
widthBefore = this.Width;
}
Here is the ResizeEnd event that will occur when the form ends the change in size:
private void frmDynamicResize_ResizeEnd(object sender, EventArgs e)
{
float WidthPerscpective = (float)Width / widthBefore;
float HeightPerscpective = (float)Height / heightBefore;
ResizeAllControls(this, WidthPerscpective, HeightPerscpective);
}
A recursive function is used to resize each control and its child controls. It uses SuspendLayout / ResumeLayout to stop/start the form drawing.
We use the SendMessage WinAPI to stop Windows from sending redraw Windows messages to the form to protect the form from flickering. It updates each control separately.
private void ResizeAllControls(Control recussiveControl,
float WidthPerscpective, float HeightPerscpective)
{
SuspendLayout();
foreach (Control control in recussiveControl.Controls)
{
if (control.Controls.Count != 0)
{
SendMessage(this.Handle, WM_SETREDRAW, 0, 0);
ResizeAllControls(control, WidthPerscpective, HeightPerscpective);
SendMessage(this.Handle, WM_SETREDRAW, 1, 0);
Invalidate(control.Region);
control.Update();
}
control.Left = (int)(control.Left * WidthPerscpective);
control.Top = (int)(control.Top * HeightPerscpective);
control.Width = (int)(control.Width * WidthPerscpective);
control.Height = (int)(control.Height * HeightPerscpective);
Invalidate(control.Region);
control.Update();
}
ResumeLayout();
}
Points of Interest
I didn't put any code for maximizing or normalizing the form. That is pretty simple. If there is request for it, I will add it to the source.
History
- 06/09/09: Uploaded to CodeProject.