This is actually a bug in Windows Forms and there's a workaround. In function Form.SizeFromClientSize(int, int)
the AdjustWindowRectEx
function is used to translate the size and it always uses the default measurements and can't be overridden. This function is called from two places:
RestoreWindowBoundsIfNecessary
in WM_WINDOWPOSCHANGED window message handlerSetClientSizeCore
The workaround is the following:
Override CreateParams in the Form:
private bool createParamsHack; protected override CreateParams CreateParams { get { CreateParams cp = base.CreateParams; // Remove styles that affect the border size if (createParamsHack) cp.Style &= ~(int)(WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_THICKFRAME); return cp; } }
Override WndProc and insert the following code to handle WM_WINDOWPOSCHANGED:
if (m.Msg == WM_WINDOWPOSCHANGED) { createParamsHack = true; base.WndProc(ref m); createParamsHack = false; }
Override SetClientSizeCore:
protected override void SetClientSizeCore(int x, int y) { createParamsHack = true; base.SetClientSizeCore(x, y); createParamsHack = false; }
It may also be good idea to override SizeFromClientSize(Size)
to return the correct measurements, but it is not strictly necessary.