August 10, 2004

Bug in Windows Forms MinimumSize property

I love my job, I really do. Nothing quite compares to being a developer, but in my previous life, I was a tester, and as such, it kinda sucks to be pulled out of the coding zone by a nagging bug...that isn't even your own.

There is a bug in the .NET Framework v1.1 implementation of the Form.MinimumSize property that can cause redraws to take a heinously long time. On some of the systems here, we have simple forms with less than 10 controls on them that will take up to five seconds to render.

If you want to reproduce the bug, here's how (code is VB.NET, conversion to C# is left as an exercise for the reader).

1. Create three forms (I'll call mine Form1, MinSize and NoMinSize.)

2. Enlarge Form1, and set the IsMdiContainer property to True.

3. Drag on a MainMenu control, add two menu items (NoMinSize and MinSize), and add the following code.

Private Sub MenuItem1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuItem1.Click

With New NoMinSize
.MdiParent = Me
End With
End Sub

Private Sub MenuItem2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuItem2.Click
With New MinSize
.MdiParent = Me
End With
End Sub

4. Open the NoMinSize form, and drag on a few controls. There is no need to hook up any logic.

5. Highlight all of the controls on the NoMinSize form, and select Edit->Copy.

6. Open the MinSize form, and paste the controls on.

7. Set the MinimumSize property for the MinSize form to whatever the Size property is. If you didn't resize the form at all, you should be able to set it to {300,300}.

8. Run your project. Click each of the menu items once, then drag them around rapidly.

Results: The one without the MinimumSize property set drags smoothly. The one with the MinimumSize property set drags extremely chunkily.

I do not know why the .NET Framework would be chugging with that property set. The only thing that I can think of is that it handles its own window move events. If that's the case, then rather than sending WM_MOVE messages to the window to move it, they're calling the MoveWindow() API, which sends WM_WINDOWPOSCHANGING, WM_WINDOWPOSCHANGED, WM_MOVE, WM_SIZE and WM_NCCALCSIZE messages.

Any thoughts?

No comments: