views:

198

answers:

2

I hit this problem in Windows Forms, after using PInvoke of SetWindowLongPtr to remove the caption (WS_CAPTION) from a Sizable window. After that whenever the window is either Minimized or Maximized and then restored to Normal it grows (by the CaptionHeight + border).

It appears that Windows Forms' layout mechanism is trying to compensate for the caption bar that it thinks is still there. (If I start with a FormBorderStyle of None and add what I want, i.e. the sizable border, I end up with the opposite problem, the window shrinks).

I found one other person had hit this problem on codeplex, but no solution was posted.

Attempts to adjust the size in a custom handler for one of the resizing events all are too early, i.e. Windows Forms makes its adjustments after Layout, Resize and SizeChanged events have fired and ResizeEnd does not fire if there is no Caption bar. This would just be a workaround in any case, I'd like a way to tell Windows Forms to do the right thing. Ideas?

(I have a workaround that works, that I'll post shortly, but it is visible to the end user.)

A: 

link textMy solution, sparked by Justin Rogers Awesome Windows Forms message pump trick:

    private delegate void VoidMethodInvoker();
    public void ShrinkWindow()
    {
        int widthAdjust = 2 * SystemInformation.BorderSize.Height;
        int heightAdjust = SystemInformation.CaptionHeight + 2 * SystemInformation.BorderSize.Height;
        this.Size = new System.Drawing.Size(Size.Width - widthAdjust, Size.Height - heightAdjust);
    }

// Then in the Resize event:
     case FormWindowState.Normal:
     {
            this.BeginInvoke(new VoidMethodInvoker(this.ShrinkWindow));

            break;
     }

The BeginInvoke puts the ShrinkWindow call on the message pump; calling it directly from within the Resize event handler is too early and the ResizeEnd event doesn't seem to fire when the caption bar is not visible. The end user does see this grow and shrink, but it's pretty quick.

crpatton
A: 

It works fine if you do this the Windows Forms' way. Paste this code into your form:

protected override CreateParams CreateParams {
  get {
    CreateParams parms = base.CreateParams;
    parms.Style &= ~0xC00000;  // Turn off WS_CAPTION
    return parms;
  }
}
Hans Passant
Excellent! This is much cleaner; less code, no visual anomaly. It's not exactly easy to discover.... Thanks.
crpatton