Delphi 获取鼠标点击的控件名称

举报
走在那条路上 发表于 2024/07/29 16:30:40 2024/07/29
【摘要】 1、PtInRect介绍:PtInRect 函数确定指定的点是否位于指定的矩形内。 如果点位于左侧或顶部,或者位于所有四个边内,则点位于矩形内。 右侧或底部的点被视为矩形外部的点。ptInRect 函数 (winuser.h) - Win32 apps | Microsoft Learn2、ClientRect:内容区域Vcl.Controls.TControl.ClientRect - R...

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;
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。