Error in TWinControl.ControlAtPos => Wrong Mousecursor shown in windows
Original Reporter info from Mantis: Martin @martin_frb
-
Reporter name: Martin Friebe
Original Reporter info from Mantis: Martin @martin_frb
- Reporter name: Martin Friebe
Description:
Under GTK this doesn't seem to happen. I believe GTK manages a cursor (like crDefault, crHourGlas) for each widget.)
Under Windows there is only one per Form => and Windows sends WM_SETMOUSE, and Widget/LCL use ControlAtPos to find the cursor.
Put a Button with special cursor in a scrolbox, scroll down 20 pixel => the button will have the correct cursur => but 20 pixel above the Cursor from the button is also shown (as if a ghost button was there).
This happens, because the Scrollbox has crDefault, so it hands the message to the Form, which uses ControlAtPos, which goes wrong.
This is just one example how to see the error, probably there are plenty more
-----
The issue is in the following code:
-File: lcl\include\wincontrol.inc
-function TWinControl.ControlAtPos(const Pos: TPoint;
-Line: 4732
-See block below
The issue exists in Gtk2 and Windows, but not in gtk1 (didn't test others)
In Gtk2 and Win:
ClientOrigin
Returns the Location of the invisible (scrolled out) Top/Right point.
(where it would be on the screen, if it was visible)
ClientOrigin.Y = TScrollBox.Top - TScrollBox.ScrollOffset.Y
ClientOrigin.X = TScrollBox.Left - TScrollBox.ScrollOffset.X
In Gtk1:
ClientOrigin
Returns the Location of the Visible Top/Right
ClientOrigin.Y = TScrollBox.Top
ClientOrigin.X = TScrollBox.Left
Therefore under windows, and GTK2 "NewPos" does already include the Scrolloffset.
This means
LControl:=TWinControl(Result).ControlAtPos(NewPos, Flags-[capfHasScrollOffset]);
Is wrong for Win and GTK2 it should be "plus" "Flags + [capfHasScrollOffset]"
Additional information:
// check recursive sub childs
if (capfRecursive in Flags) and (Result is TWinControl)
and (TWinControl(Result).ControlCount>0) then begin
OldClientOrigin:=ClientOrigin;
NewClientOrigin:=TWinControl(Result).ClientOrigin;
NewPos:=Pos;
NewPos.X:=NewPos.X-NewClientOrigin.X+OldClientOrigin.X;
NewPos.Y:=NewPos.Y-NewClientOrigin.Y+OldClientOrigin.Y;
LControl:=TWinControl(Result).ControlAtPos(NewPos, Flags-[capfHasScrollOffset]);
//debugln(['TWinControl.RECURSED ControlAtPos Result=',DbgSName(Result),' LControl=',DbgSName(LControl),' ',dbgs(NewPos),' AllowDisabled=',AllowDisabled,' OnlyClientAreas=',OnlyClientAreas]);
if LControl<>nil then
Result:=LControl;
end;
Mantis conversion info:
- Mantis ID: 14256
- Fixed in version: 0.9.29 (SVN)
- Fixed in revision: 26660 (#b18be464)
- Target version: 1.0.0
- LazTarget: 1.0