views:

489

answers:

3

The WinForms GroupBox control doesn't support MouseMove (or at least, not consistently), and I don't understand why.

Since it descends from Control, it does have a MouseMove event, but GroupBox explicitly reintroduces it with Browsable(false), so it's not shown in the Property Grid. You can hook the MouseMove event at runtime, and sometimes it works -- as long as FlatStyle is left at Standard. If the GroupBox's FlatStyle is set to System, then no MouseMove events are fired at all.

Reflector hasn't given me any clues. The GroupBox constructor doesn't seem to be setting any strange control styles, and GroupBox doesn't do anything silly like override MouseMove and fail to call base.

This also appears to be a WinForms-specific limitation, because Delphi group boxes support OnMouseMove just fine. Correction: the comparison to Delphi isn't valid. Delphi group boxes aren't actually standard BM_GROUPBOX controls; they're just painted to look like group boxes, without actually inheriting strange groupbox behaviors like this. So this may well be a limitation of the Windows groupbox control, though I haven't seen it documented anywhere.

Why does the WinForms GroupBox not support MouseMove?

+1  A: 

You can see this with Reflector, the key property is CreateParams and the internal OwnerDraw property. GroupBox normally operates with OwnerDraw = true, except when you set FlatStyle = System. Then you get an old-fashioned Windows group box, a window whose class name is BUTTON with the BS_GROUPBOX style bit turned on.

If you take a look with Spy++, you'll see that the control doesn't get any mouse messages at all. Not sure why this is so, the SDK docs don't mention it. I'd guess this dates back to Windows 2.x where every cycle counted. But it does explain why the MouseMove event is hidden, it cannot fire when the System style is selected. Same for Click and Up/Down. The FlatStyle property setter really nails it down by also turning off the Control.UserMouse control style.

Anyhoo, if you want mouse messages, you'll need to avoid the System style.

Hans Passant
+3  A: 

According to this thread, a standard Windows groupbox (i.e., a BUTTON control with BS_GROUPBOX style) appears to return HTTRANSPARENT in response to WM_NCHITTEST. Since the control claims to be transparent, Windows sends the mouse-move events to its parent window instead.

The thread confirms that, if you handle WM_NCHITTEST yourself and return HTCLIENT, then the groupbox will get mouse-move events. They're using MFC but it probably works for WinForms as well.

What's not clear is why Windows returns HTTRANSPARENT by default, but at least the problem has been independently confirmed.

Joe White
A: 
tommieb75
I'm skeptical, since other responses confirm that the `WM_MOUSEMOVE` is never even being sent to the groupbox. Have you tested to see if this code actually works with a GroupBox?
Joe White
@Joe White: Please see my revised code and the steps I used to get this to work. HTH. Best regards, Tom.
tommieb75