1. Computing

Is Some (Delphi) TControl Under the Mouse?

Where is the Mouse? Is it Over Some TControl Descendant?

By

Sometimes knowing what is the control directly under the mouse is not enough.

Suppose the following: there's a panel ("ppanel") and a panel ("cpanel") inside it as a child, there's also a TImage ("img") inside the "cpanel". The question is: "is the mouse over "ppanel"?

The FindVCLWindow function can locate the windowed control under a certain point - for example under the mouse pointer. If the mouse is over "cpanel" it is also above "ppanel" as cpanel is its child - but FindVCLWindow would return cpanel ton ppanel. Ok, you can check if ppanel is a parent of cpanel - but it would be much easier to simply check is the mouse over a ppanel.

Not to mess the intro any more, here's a question for this Delphi tip :)

Is the mouse over some TControl descendant that might be completely covered by its child controls?.

Is Mouse Over Some TControl?

For the answer: grab the position of the mouse (screen coordinates), check if the mouse point is inside the rectangle determined by TControl's position in screen coordinates:
function IsMouseOverControl(const ctrl: TControl): boolean;
var
  sr : TRect;
begin
  sr := Rect(ctrl.ClientToScreen(Point(0, 0)), ctrl.ClientToScreen(Point(ctrl.Width, ctrl.Height)));

  result := PtInRect(sr, Mouse.CursorPos);
end;

//test
//handles TApplication Events OnIdle

procedure TForm3.ApplicationEvents1Idle(Sender: TObject; var Done: Boolean);
begin
  if IsMouseOverControl(Panel1) then
    aption := 'over panel 1'
  else
    Caption := 'not over panel 1';
end;
The TApplicationEvents component and its OnIdle event is used here to test when the mouse is over "Panel1" - never mind if there are some other child controls inside Panel1.
ClientToScreen converts the client coordinates of a specified point to screen coordinates.
PtInRect determines whether the specified point (mouse pointer) lies within the specified rectangle ("panel1" bounding rectangle in screen coordinates).

Note: since IsMouseOverControl uses a TControl for its parameter you can use it to check if the mouse is over a TImage - something FindVCLWindow cannot be used for (as it locates TWinControl descendants - and TImage is not a windowed control).

Delphi tips navigator:
» Handling Mouse Wheel Messages For The TImage Delphi Control
« TEdit.AutoSelect OnClick

©2014 About.com. All rights reserved.