Delphi 获取鼠标点击的控件名称
1、PtInRect介绍:
PtInRect 函数确定指定的点是否位于指定的矩形内。 如果点位于左侧或顶部,或者位于所有四个边内,则点位于矩形内。 右侧或底部的点被视为矩形外部的点。
ptInRect 函数 (winuser.h) - Win32 apps | Microsoft Learn
2、ClientRect:内容区域
Vcl.Controls.TControl.ClientRect - RAD Studio API Documentation (embarcadero.com)
以像素为单位指定控件客户端区域的大小。
读取 ClientRect 可查出控件客户端区域的大小。ClientRect 返回一个矩形,其顶部和左侧字段设置为零,底部和右侧字段分别设置为控件的高度和宽度。ClientRect 相当于 Rect(0,0,ClientWidth,ClientHeight)。
如果一个点位于控件客户端矩形的左侧或上侧,则该点会被视为在客户端矩形内,但如果该点位于右侧或下侧,则不会被视为在客户端矩形内。也就是说,要位于客户端矩形内,X 坐标必须大于或等于 ClientRect.Left,小于 ClientRect.Right,Y 坐标必须大于或等于 ClientRect.Top,小于 ClientRect.Bottom。
注意:ClientRect 是控件物理客户端区域的大小,而不是其逻辑客户端区域的大小。如果控件支持滚动,则 ClientRect 不是整个滚动范围,而只是在任何给定时间内可用的区域。
3、BoundsRect:整体区域
Vcl.Controls.TControl.BoundsRect - RAD Studio API Documentation (embarcadero.com)
指定控件的边界矩形,以父控件的坐标系表示。
使用 BoundsRect 可以快速一次性获得控件所有角的像素位置。
4、TControl.ParentToClient:用于将相对于父控件的坐标转换为相对于当前控件客户端区域的坐标
5、TControl.ClientToParent:用于将相对于当前控件客户端区域的坐标转换为相对于父控件的坐标
下面给出具体的代码实例:
procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG; var Handled: Boolean);
var
AtempContrl : TControl;
APoint : TPoint;
i : Integer;
begin
if Msg.message = WM_LBUTTONDOWN then
begin
APoint := Msg.pt;
Memo1.Lines.Add('Msg.pt坐标:' + IntToStr(APoint.X) + ',' + IntToStr(APoint.Y));
APoint := ScreenToClient(APoint);
AtempContrl := FindClickedControl(Self, APoint);
if AtempContrl <> nil then
memo1.Lines.Add('点击了: ' + AtempContrl.Name);
end;
end;
function FindClickedControl(AControl: TControl; AInputPoint: TPoint): TControl;
var
I: Integer;
ASubControl: TControl;
ATempPoint: TPoint;
ATempWinControl : TWinControl;
begin
Result := nil;
if PtInRect(AControl.ClientRect, AInputPoint) then
begin
if AControl is TWinControl then
begin
ATempWinControl := AControl as TWinControl;
for I := 0 to ATempWinControl.ControlCount - 1 do
begin
ASubControl := ATempWinControl.Controls[I];
ATempPoint := ASubControl.ParentToClient(AInputPoint,ATempWinControl);
// ATempPoint := ASubControl.ClientToParent(AInputPoint, ASubControl.Parent);
if PtInRect(ASubControl.ClientRect, ATempPoint) then
begin
Result := FindClickedControl(ASubControl, ATempPoint);
if Result <> nil then
Exit; // 找到后退出循环
end;
end;
end;
// 如果没有子控件被点击,或者AControl是TGraphicControl且被点击,返回AControl
Result := AControl;
end;
- 点赞
- 收藏
- 关注作者
评论(0)