mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-05 23:58:06 +02:00
lcl: redo MouseEnter/MouseLeave notifications:
- move application mouse events notification from various message handlers to the WND proc of TWinControl - don't assume that control at mouse is the current control which has mouse events. If some control has a mouse capture set then it has the mouse messages and not the control at mouse - don't perform a control search in TApplication.DoBeforeMouseMessage - it already has an argument which contains the new mouse control (fixes bug #0016715) - fix CM_MOUSEENTER, CM_MOUSELEAVE message handlers so Parent controls will always get CM_ notification before the event handler and inspite of who is the message owner git-svn-id: trunk@27770 -
This commit is contained in:
parent
084fed8f6c
commit
d5cb0e2fbe
@ -285,7 +285,6 @@ type
|
||||
procedure CMButtonPressed(var Message: TLMessage); message CM_BUTTONPRESSED;
|
||||
procedure CMEnabledChanged(var Message: TLMessage); message CM_ENABLEDCHANGED;
|
||||
private
|
||||
procedure DoBeforeMouseMessage;
|
||||
procedure DoMouseUp(var Message: TLMMouse; Button: TMouseButton);
|
||||
procedure WMLButtonDown(Var Message: TLMLButtonDown); message LM_LBUTTONDOWN;
|
||||
procedure WMLButtonUp(var Message: TLMLButtonUp); message LM_LBUTTONUP;
|
||||
|
@ -1106,8 +1106,8 @@ type
|
||||
procedure CMBiDiModeChanged(var Message: TLMessage); message CM_BIDIMODECHANGED;
|
||||
procedure CMEnabledChanged(var Message: TLMEssage); message CM_ENABLEDCHANGED;
|
||||
procedure CMHitTest(var Message: TCMHittest) ; message CM_HITTEST;
|
||||
procedure CMMouseEnter(var Message :TLMessage); message CM_MouseEnter;
|
||||
procedure CMMouseLeave(var Message :TLMessage); message CM_MouseLeave;
|
||||
procedure CMMouseEnter(var Message :TLMessage); message CM_MOUSEENTER;
|
||||
procedure CMMouseLeave(var Message :TLMessage); message CM_MOUSELEAVE;
|
||||
procedure CMHintShow(var Message: TLMessage); message CM_HINTSHOW;
|
||||
procedure CMParentBiDiModeChanged(var Message: TLMessage); message CM_PARENTBIDIMODECHANGED;
|
||||
procedure CMParentColorChanged(var Message: TLMessage); message CM_PARENTCOLORCHANGED;
|
||||
@ -2768,7 +2768,7 @@ begin
|
||||
begin
|
||||
Result := WinControl;
|
||||
Control := WinControl.ControlAtPos(WinControl.ScreenToClient(Position),
|
||||
[capfAllowDisabled,capfAllowWinControls,capfRecursive]);
|
||||
[capfAllowDisabled, capfAllowWinControls, capfRecursive]);
|
||||
//debugln(['FindControlAtPosition ',dbgs(Position),' ',DbgSName(WinControl),' ',dbgs(WinControl.ScreenToClient(Position)),' ',DbgSName(Control)]);
|
||||
if Control <> nil then
|
||||
Result := Control;
|
||||
|
@ -1242,7 +1242,6 @@ type
|
||||
function GetTitle: string;
|
||||
procedure FreeIconHandles;
|
||||
procedure IconChanged(Sender: TObject);
|
||||
function GetControlAtMouse: TControl;
|
||||
procedure SetBidiMode(const AValue: TBiDiMode);
|
||||
procedure SetFlags(const AValue: TApplicationFlags);
|
||||
procedure SetNavigation(const AValue: TApplicationNavigationOptions);
|
||||
@ -1293,6 +1292,7 @@ type
|
||||
constructor Create(AOwner: TComponent); override;
|
||||
destructor Destroy; override;
|
||||
procedure ActivateHint(CursorPos: TPoint; CheckHintControlChange: Boolean = False);
|
||||
function GetControlAtMouse: TControl;
|
||||
procedure ControlDestroyed(AControl: TControl);
|
||||
function BigIconHandle: HIcon;
|
||||
function SmallIconHandle: HIcon;
|
||||
|
@ -495,18 +495,18 @@ var
|
||||
begin
|
||||
GetCursorPos(P);
|
||||
//debugln(['TApplication.GetControlAtMouse p=',dbgs(p),' FLastMousePos=',dbgs(FLastMousePos)]);
|
||||
if FLastMouseControlValid and (P.X=FLastMousePos.x) and (P.Y=FLastMousePos.Y)
|
||||
then
|
||||
if FLastMouseControlValid and (P.X = FLastMousePos.x) and (P.Y = FLastMousePos.Y) then
|
||||
Result := FLastMouseControl
|
||||
else
|
||||
Result := FindControlAtPosition(P, True);
|
||||
|
||||
if (Result <> nil) and (csDesigning in Result.ComponentState) then
|
||||
Result := nil;
|
||||
if Result<> nil then begin
|
||||
FLastMouseControlValid:=true;
|
||||
FLastMousePos:=p;
|
||||
FLastMouseControl:=Result;
|
||||
if Result <> nil then
|
||||
begin
|
||||
FLastMouseControlValid := True;
|
||||
FLastMousePos := p;
|
||||
FLastMouseControl := Result;
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -1959,7 +1959,7 @@ end;
|
||||
procedure TApplication.DoBeforeMouseMessage(CurMouseControl: TControl);
|
||||
begin
|
||||
//debugln(['TApplication.DoBeforeMouseMessage ',DbgSName(CurMouseControl)]);
|
||||
UpdateMouseControl(GetControlAtMouse);
|
||||
UpdateMouseControl(CurMouseControl);
|
||||
end;
|
||||
|
||||
function TApplication.IsShortcut(var Message: TLMKey): boolean;
|
||||
|
@ -667,15 +667,18 @@ end;
|
||||
------------------------------------------------------------------------------}
|
||||
procedure TControl.CMMouseEnter(var Message: TLMessage);
|
||||
begin
|
||||
// this is a LCL based mouse message, so don't call DoBeforeMouseMessage
|
||||
//DebugLn('TControl.CMMouseEnter ',Name,':',ClassName,' ',FMouseEntered,' ',Message.LParam);
|
||||
if (Message.LParam=0) and (not FMouseEntered) then
|
||||
begin
|
||||
FMouseEntered := True;
|
||||
if FMouseEntered then
|
||||
Exit;
|
||||
|
||||
FMouseEntered := True;
|
||||
|
||||
// broadcast to parents first
|
||||
if Assigned(Parent) then
|
||||
Parent.Perform(CM_MOUSEENTER, 0, LParam(Self));
|
||||
|
||||
// if it is not a child message then perform an event
|
||||
if (Message.LParam = 0) then
|
||||
MouseEnter;
|
||||
if FParent <> nil then
|
||||
FParent.Perform(CM_MOUSEENTER, 0, LParam(Self));
|
||||
end;
|
||||
end;
|
||||
|
||||
{------------------------------------------------------------------------------
|
||||
@ -683,15 +686,18 @@ end;
|
||||
------------------------------------------------------------------------------}
|
||||
procedure TControl.CMMouseLeave(var Message: TLMessage);
|
||||
begin
|
||||
// this is a LCL based mouse message, so don't call DoBeforeMouseMessage
|
||||
//DebugLn('TControl.CMMouseLeave ',Name,':',ClassName,' ',FMouseEntered,' ',Message.LParam);
|
||||
if (Message.LParam = 0) and FMouseEntered then
|
||||
begin
|
||||
FMouseEntered := False;
|
||||
if not FMouseEntered then
|
||||
Exit;
|
||||
|
||||
FMouseEntered := False;
|
||||
|
||||
// broadcast to parents first
|
||||
if Assigned(Parent) then
|
||||
Parent.Perform(CM_MOUSELEAVE, 0, LParam(Self));
|
||||
|
||||
// if it is not a child message then perform an event
|
||||
if (Message.LParam = 0) then
|
||||
MouseLeave;
|
||||
if FParent <> nil then
|
||||
FParent.Perform(CM_MOUSELEAVE, 0, LParam(Self));
|
||||
end;
|
||||
end;
|
||||
|
||||
{------------------------------------------------------------------------------
|
||||
@ -873,9 +879,16 @@ end;
|
||||
procedure TControl.DoBeforeMouseMessage;
|
||||
------------------------------------------------------------------------------}
|
||||
procedure TControl.DoBeforeMouseMessage;
|
||||
var
|
||||
NewMouseControl: TControl;
|
||||
begin
|
||||
if Application<>nil then
|
||||
Application.DoBeforeMouseMessage(Self);
|
||||
if Assigned(Application) then
|
||||
begin
|
||||
NewMouseControl := CaptureControl;
|
||||
if NewMouseControl = nil then
|
||||
NewMouseControl := Application.GetControlAtMouse;
|
||||
Application.DoBeforeMouseMessage(NewMouseControl);
|
||||
end;
|
||||
end;
|
||||
|
||||
{------------------------------------------------------------------------------
|
||||
@ -1785,7 +1798,6 @@ end;
|
||||
------------------------------------------------------------------------------}
|
||||
procedure TControl.WMLButtonDown(var Message: TLMLButtonDown);
|
||||
begin
|
||||
DoBeforeMouseMessage;
|
||||
if (csCaptureMouse in ControlStyle) and (mbLeft in CaptureMouseButtons) then
|
||||
begin
|
||||
{$IFDEF VerboseMouseCapture}
|
||||
@ -1807,7 +1819,6 @@ end;
|
||||
------------------------------------------------------------------------------}
|
||||
procedure TControl.WMRButtonDown(var Message: TLMRButtonDown);
|
||||
begin
|
||||
DoBeforeMouseMessage;
|
||||
if (csCaptureMouse in ControlStyle) and (mbRight in CaptureMouseButtons) then
|
||||
begin
|
||||
{$IFDEF VerboseMouseCapture}
|
||||
@ -1827,7 +1838,6 @@ end;
|
||||
------------------------------------------------------------------------------}
|
||||
procedure TControl.WMMButtonDown(var Message: TLMMButtonDown);
|
||||
begin
|
||||
DoBeforeMouseMessage;
|
||||
if (csCaptureMouse in ControlStyle) and (mbMiddle in CaptureMouseButtons) then
|
||||
begin
|
||||
{$IFDEF VerboseMouseCapture}
|
||||
@ -1849,7 +1859,6 @@ begin
|
||||
Btn := mbExtra2
|
||||
else
|
||||
Exit;
|
||||
DoBeforeMouseMessage;
|
||||
if (csCaptureMouse in ControlStyle) and (Btn in CaptureMouseButtons) then
|
||||
begin
|
||||
{$IFDEF VerboseMouseCapture}
|
||||
@ -1870,7 +1879,6 @@ end;
|
||||
------------------------------------------------------------------------------}
|
||||
procedure TControl.WMLButtonDblClk(var Message: TLMLButtonDblClk);
|
||||
begin
|
||||
DoBeforeMouseMessage;
|
||||
//TODO: SendCancelMode(self);
|
||||
if (csCaptureMouse in ControlStyle) and (mbLeft in CaptureMouseButtons) then
|
||||
begin
|
||||
@ -1894,7 +1902,6 @@ end;
|
||||
------------------------------------------------------------------------------}
|
||||
procedure TControl.WMRButtonDblClk(var Message: TLMRButtonDblClk);
|
||||
begin
|
||||
DoBeforeMouseMessage;
|
||||
if (csCaptureMouse in ControlStyle) and (mbRight in CaptureMouseButtons) then
|
||||
begin
|
||||
{$IFDEF VerboseMouseCapture}
|
||||
@ -1914,7 +1921,6 @@ end;
|
||||
------------------------------------------------------------------------------}
|
||||
procedure TControl.WMMButtonDblClk(var Message: TLMMButtonDblClk);
|
||||
begin
|
||||
DoBeforeMouseMessage;
|
||||
if (csCaptureMouse in ControlStyle) and (mbMiddle in CaptureMouseButtons) then
|
||||
begin
|
||||
{$IFDEF VerboseMouseCapture}
|
||||
@ -1936,7 +1942,6 @@ begin
|
||||
Btn := mbExtra2
|
||||
else
|
||||
Exit;
|
||||
DoBeforeMouseMessage;
|
||||
if (csCaptureMouse in ControlStyle) and (Btn in CaptureMouseButtons) then
|
||||
begin
|
||||
{$IFDEF VerboseMouseCapture}
|
||||
@ -1956,7 +1961,6 @@ end;
|
||||
------------------------------------------------------------------------------}
|
||||
procedure TControl.WMLButtonTripleClk(var Message: TLMLButtonTripleClk);
|
||||
begin
|
||||
DoBeforeMouseMessage;
|
||||
//TODO: SendCancelMode(self);
|
||||
if (csCaptureMouse in ControlStyle) and (mbLeft in CaptureMouseButtons) then
|
||||
begin
|
||||
@ -1978,7 +1982,6 @@ end;
|
||||
------------------------------------------------------------------------------}
|
||||
procedure TControl.WMRButtonTripleClk(var Message: TLMRButtonTripleClk);
|
||||
begin
|
||||
DoBeforeMouseMessage;
|
||||
if (csCaptureMouse in ControlStyle) and (mbRight in CaptureMouseButtons) then
|
||||
begin
|
||||
{$IFDEF VerboseMouseCapture}
|
||||
@ -1998,7 +2001,6 @@ end;
|
||||
------------------------------------------------------------------------------}
|
||||
procedure TControl.WMMButtonTripleClk(var Message: TLMMButtonTripleClk);
|
||||
begin
|
||||
DoBeforeMouseMessage;
|
||||
if (csCaptureMouse in ControlStyle) and (mbMiddle in CaptureMouseButtons) then
|
||||
begin
|
||||
{$IFDEF VerboseMouseCapture}
|
||||
@ -2020,7 +2022,6 @@ begin
|
||||
Btn := mbExtra2
|
||||
else
|
||||
Exit;
|
||||
DoBeforeMouseMessage;
|
||||
if (csCaptureMouse in ControlStyle) and (Btn in CaptureMouseButtons) then
|
||||
begin
|
||||
{$IFDEF VerboseMouseCapture}
|
||||
@ -2040,7 +2041,6 @@ end;
|
||||
------------------------------------------------------------------------------}
|
||||
procedure TControl.WMLButtonQuadClk(var Message: TLMLButtonQuadClk);
|
||||
begin
|
||||
DoBeforeMouseMessage;
|
||||
//TODO: SendCancelMode(self);
|
||||
if (csCaptureMouse in ControlStyle) and (mbLeft in CaptureMouseButtons) then
|
||||
begin
|
||||
@ -2062,7 +2062,6 @@ end;
|
||||
------------------------------------------------------------------------------}
|
||||
procedure TControl.WMRButtonQuadClk(var Message: TLMRButtonQuadClk);
|
||||
begin
|
||||
DoBeforeMouseMessage;
|
||||
if (csCaptureMouse in ControlStyle) and (mbRight in CaptureMouseButtons) then
|
||||
begin
|
||||
{$IFDEF VerboseMouseCapture}
|
||||
@ -2082,7 +2081,6 @@ end;
|
||||
------------------------------------------------------------------------------}
|
||||
procedure TControl.WMMButtonQuadClk(var Message: TLMMButtonQuadClk);
|
||||
begin
|
||||
DoBeforeMouseMessage;
|
||||
if (csCaptureMouse in ControlStyle) and (mbMiddle in CaptureMouseButtons) then
|
||||
begin
|
||||
{$IFDEF VerboseMouseCapture}
|
||||
@ -2104,7 +2102,6 @@ begin
|
||||
Btn := mbExtra2
|
||||
else
|
||||
Exit;
|
||||
DoBeforeMouseMessage;
|
||||
if (csCaptureMouse in ControlStyle) and (Btn in CaptureMouseButtons) then
|
||||
begin
|
||||
{$IFDEF VerboseMouseCapture}
|
||||
@ -2124,7 +2121,6 @@ end;
|
||||
------------------------------------------------------------------------------}
|
||||
procedure TControl.WMLButtonUp(var Message: TLMLButtonUp);
|
||||
begin
|
||||
DoBeforeMouseMessage;
|
||||
//DebugLn('TControl.WMLButtonUp A ',Name,':',ClassName,' csCaptureMouse=',DbgS(csCaptureMouse in ControlStyle),' csClicked=',DbgS(csClicked in ControlState));
|
||||
if (csCaptureMouse in ControlStyle) and (mbLeft in CaptureMouseButtons) then
|
||||
begin
|
||||
@ -2158,7 +2154,6 @@ end;
|
||||
------------------------------------------------------------------------------}
|
||||
procedure TControl.WMRButtonUp(var Message: TLMRButtonUp);
|
||||
begin
|
||||
DoBeforeMouseMessage;
|
||||
if (csCaptureMouse in ControlStyle) and (mbRight in CaptureMouseButtons) then
|
||||
begin
|
||||
{$IFDEF VerboseMouseCapture}
|
||||
@ -2179,7 +2174,6 @@ end;
|
||||
------------------------------------------------------------------------------}
|
||||
procedure TControl.WMMButtonUp(var Message: TLMMButtonUp);
|
||||
begin
|
||||
DoBeforeMouseMessage;
|
||||
if (csCaptureMouse in ControlStyle) and (mbMiddle in CaptureMouseButtons) then
|
||||
begin
|
||||
{$IFDEF VerboseMouseCapture}
|
||||
@ -2202,7 +2196,6 @@ begin
|
||||
Btn := mbExtra2
|
||||
else
|
||||
Exit;
|
||||
DoBeforeMouseMessage;
|
||||
if (csCaptureMouse in ControlStyle) and (Btn in CaptureMouseButtons) then
|
||||
begin
|
||||
{$IFDEF VerboseMouseCapture}
|
||||
@ -2225,8 +2218,6 @@ procedure TControl.WMMouseWheel(var Message: TLMMouseEvent);
|
||||
var
|
||||
MousePos: TPoint;
|
||||
begin
|
||||
DoBeforeMouseMessage;
|
||||
|
||||
MousePos.X := Message.X;
|
||||
MousePos.Y := Message.Y;
|
||||
|
||||
@ -3550,7 +3541,6 @@ begin
|
||||
{$IFDEF VerboseMouseBugfix}
|
||||
DebugLn(['[TControl.WMMouseMove] ',Name,':',ClassName,' ',Message.XPos,',',Message.YPos]);
|
||||
{$ENDIF}
|
||||
DoBeforeMouseMessage;
|
||||
UpdateMouseCursor(Message.XPos,Message.YPos);
|
||||
if not (csNoStdEvents in ControlStyle) then
|
||||
with Message do
|
||||
|
@ -704,15 +704,6 @@ begin
|
||||
inherited MouseUp(Button, Shift, X, Y);
|
||||
end;
|
||||
|
||||
{------------------------------------------------------------------------------
|
||||
procedure TCustomSpeedButton.DoBeforeMouseMessage;
|
||||
------------------------------------------------------------------------------}
|
||||
procedure TCustomSpeedButton.DoBeforeMouseMessage;
|
||||
begin
|
||||
if Application<>nil then
|
||||
Application.DoBeforeMouseMessage(Self);
|
||||
end;
|
||||
|
||||
{------------------------------------------------------------------------------
|
||||
TCustomSpeedButton DoMouseUp "Event Handler"
|
||||
------------------------------------------------------------------------------}
|
||||
@ -758,7 +749,6 @@ procedure TCustomSpeedButton.WMLButtonUp(var Message: TLMLButtonUp);
|
||||
var
|
||||
OldState: TButtonState;
|
||||
begin
|
||||
DoBeforeMouseMessage;
|
||||
//DebugLn('TCustomSpeedButton.WMLButtonUp A ',DbgSName(Self),' csCaptureMouse=',DbgS(csCaptureMouse in ControlStyle),' csClicked=',DbgS(csClicked in ControlState));
|
||||
if (csCaptureMouse in ControlStyle) and (mbLeft in CaptureMouseButtons) then
|
||||
begin
|
||||
|
@ -5157,18 +5157,16 @@ begin
|
||||
Exit;
|
||||
end;
|
||||
|
||||
// exclude only LM_MOUSEENTER, LM_MOUSELEAVE
|
||||
LM_MOUSEFIRST..LM_MOUSELAST,
|
||||
LM_LBUTTONTRIPLECLK,
|
||||
LM_LBUTTONQUADCLK,
|
||||
LM_MBUTTONTRIPLECLK,
|
||||
LM_MBUTTONQUADCLK,
|
||||
LM_RBUTTONTRIPLECLK,
|
||||
LM_RBUTTONQUADCLK:
|
||||
LM_MOUSEFIRST2..LM_RBUTTONQUADCLK,
|
||||
LM_XBUTTONTRIPLECLK..LM_MOUSELAST2:
|
||||
begin
|
||||
{$IFDEF VerboseMouseBugfix}
|
||||
DebugLn('TWinControl.WndPRoc A ',Name,':',ClassName);
|
||||
{$ENDIF}
|
||||
//if Message.Msg=LM_RBUTTONUP then begin DebugLn(['TWinControl.WndProc ',DbgSName(Self)]); DumpStack end;
|
||||
DoBeforeMouseMessage;
|
||||
if IsControlMouseMSG(Message) then
|
||||
Exit
|
||||
else
|
||||
|
Loading…
Reference in New Issue
Block a user