|
Reported by Mike Lischke
Mouse wheel handlers are often not properly triggered due to the assumption
of the VCL, that mouse messages always come with their coordinates being
relative to the window they are sent to. This is true with one exception:
WM_MOUSEWHEEL. coordinates are screen coordinates.
This is a problem because TWinControl tries to forward each mouse message to
an eventual child control. For this task the method IsControlMouseMsg is
called passing the message record as TWMMouse record. The IsControlMouseMsg
method then tries to find a control to forward the message to by comparing
the bounding rectangles of all child controls (which do not need to be
windowed controls like TPaintBox) with the passed mouse coordinates. This is
obviously wrong when WM_MOUSEWHEEL messages are handled because the
coordinates are wrongly interpreted.
Interestingly enough, this error does not appear on Win9x systems because
they do not have native mousewheel support. This causes the VCL to take
another path in the message handling (see TWinControl.WndProc, 'else' branch
of the 'case' command). This path does not involve the search for a child
control but instead the mouse wheel message is directly handled.
To reproduce:
Create a new form and place a TShape on it. Make it covering much of the
form or set it to alClient alignment. Now include a handler for the
OnMouseWheel event of the form, e.g. using Beep; as signal. Compile and run
the project. When the form has the focus then mouse wheel messages are sent
to it and you can hear the beeps (roll the wheel to make that work). Now
move the form far to the left of the screen and try again. Vary also the
position of the mouse. The mouse wheel messages will suddenly disappear when
the program assumes that the shape control is under the mouse and this can
happen somewhere, depending on the position of the form on the screen (and
the true mouse position, of course). |