TRect参数如何传递与使用?

99ANYc3cd6
预计阅读时长 16 分钟
位置: 首页 参数 正文

TRect 是 Delphi 中一个非常基础且重要的结构,用于表示一个矩形区域,无论是在 VCL 框架(用于 Windows 桌面应用)还是 FMX 框架(用于跨平台应用)中,它都无处不在。

delphi trect 参数
(图片来源网络,侵删)

TRect 是什么?

TRect 是一个记录类型,在 System.Types 单元中定义,它由四个整型(或其子类型,如 Single, Double)属性组成,用于定义一个矩形在二维空间中的位置和大小。

核心属性

  • Left: 矩形左边缘的 X 坐标。
  • Top: 矩形上边缘的 Y 坐标。
  • Right: 矩形右边缘的 X 坐标。
  • Bottom: 矩形下边缘的 Y 坐标。

重要概念TRect 的坐标是左闭右开的,这意味着矩形包含 (Left, Top) 点,但不包含 (Right, Bottom) 点。

  • 宽度: Width = Right - Left
  • 高度: Height = Bottom - Top

常用方法

TRect 还提供了一些非常实用的方法:

  • Contains(Point: TPoint): Boolean: 判断一个点是否在矩形内部。
  • InflateBy(DeltaX, DeltaY: Integer): 向外或向内扩展矩形。DeltaX/DeltaY 为正则扩大,为负则缩小。
  • Intersect(Rect: TRect): 将当前矩形修改为与另一个矩形的交集。
  • Union(Rect: TRect): 将当前矩形修改为与另一个矩形的并集。
  • IsEmpty: Boolean: 判断矩形是否为空(Left >= RightTop >= Bottom)。

如何传递 TRect 作为参数?

当函数或过程需要接收一个矩形区域时,你可以将 TRect 作为参数传递,主要有两种方式:值传递引用传递

delphi trect 参数
(图片来源网络,侵删)

值传递

这是最常见、最安全的方式,当你传递一个 TRect 时,函数内部会创建该矩形的一个副本,函数内部对这个副本的任何修改(例如调用 InflateBy)都不会影响到原始的矩形变量。

语法:

procedure MyProcedure(const ARect: TRect);

强烈建议使用 const 关键字,这有以下好处:

  1. 高效TRect 的大小很小(4个整数),传递副本的开销极小。
  2. 安全:防止函数意外修改调用者传入的原始数据。
  3. 可读性:明确表示该参数是输入参数,函数不会修改它。

示例:

delphi trect 参数
(图片来源网络,侵删)
uses
  System.Types, System.SysUtils;
// 这个函数只读取矩形信息,不修改它
function GetRectArea(const ARect: TRect): Integer;
begin
  // 如果矩形为空,面积为0
  if ARect.IsEmpty then
    Result := 0
  else
    Result := ARect.Width * ARect.Height;
end;
var
  MyRect: TRect;
begin
  MyRect := TRect.Create(10, 10, 100, 100);
  ShowMessage(Format('原始矩形: (%d, %d, %d, %d)', [MyRect.Left, MyRect.Top, MyRect.Right, MyRect.Bottom]));
  var Area := GetRectArea(MyRect);
  ShowMessage(Format('矩形面积: %d', [Area]));
  // MyRect 的值没有被改变
  ShowMessage(Format('调用函数后矩形: (%d, %d, %d, %d)', [MyRect.Left, MyRect.Top, MyRect.Right, MyRect.Bottom]));
end.

引用传递

当你需要在函数内部修改原始矩形,并将这些修改“带回来”给调用者时,就应该使用引用传递。

语法:

procedure MyProcedure(var ARect: TRect);

使用 var 关键字,传递的是变量的内存地址,函数内部对 ARect 的所有操作都会直接作用于原始变量。

示例:

uses
  System.Types, System.SysUtils;
// 这个函数会修改传入的矩形
procedure ExpandRect(var ARect: TRect; DeltaX, DeltaY: Integer);
begin
  // 直接修改原始矩形
  ARect.InflateBy(DeltaX, DeltaY);
end;
var
  MyRect: TRect;
begin
  MyRect := TRect.Create(10, 10, 100, 100);
  ShowMessage(Format('原始矩形: (%d, %d, %d, %d)', [MyRect.Left, MyRect.Top, MyRect.Right, MyRect.Bottom]));
  // 调用函数,传入 var 参数
  ExpandRect(MyRect, 10, 5);
  // MyRect 的值已经被改变
  ShowMessage(Format('调用函数后矩形: (%d, %d, %d, %d)', [MyRect.Left, MyRect.Top, MyRect.Right, MyRect.Bottom]));
end.

输出:

原始矩形: (10, 10, 100, 100)
调用函数后矩形: (0, 5, 110, 105)

注意InflateBy(10, 5) 会将 Left 减 10,Top 减 5,Right 加 10,Bottom 加 5。


TRect 在实际开发中的应用场景

TRect 几乎无处不在,尤其是在处理 UI 相关的逻辑时。

场景1:控件和窗体的位置与大小

  • TControl.BoundsRect: 获取或设置控件在父坐标系中的矩形区域。
  • TControl.ClientRect: 获取控件客户区的矩形区域(不包括边框、标题栏等)。
  • TForm.ClientRect: 获取窗体客户区的矩形区域。

示例:判断鼠标点击是否在按钮上

procedure TForm1.Button1Click(Sender: TObject);
var
  MousePos: TPoint;
begin
  // 获取鼠标在窗体客户区内的坐标
  MousePos := ScreenToClient(Mouse.CursorPos);
  // 判断点击是否在按钮1的客户区内
  if Button1.ClientRect.Contains(MousePos) then
  begin
    ShowMessage('点击了按钮1的客户区内部!');
  end;
end;

场景2:绘图操作

TCanvas 上绘制图形时,TRect 是定义绘制区域的基本参数。

示例:在窗体上画一个矩形

procedure TForm1.FormPaint(Sender: TObject);
var
  R: TRect;
begin
  R := ClientRect; // 使用整个客户区作为绘制区域
  Canvas.Brush.Color := clBlue;
  Canvas.FrameRect(R); // 画一个空心矩形
end;

场景3:屏幕和显示器的操作

  • Screen.Monitors: 一个数组,包含了系统中所有显示器的信息,每个 TMonitor 对象都有一个 WorkareaRect 属性,表示该显示器的工作区(通常不包括任务栏)。

示例:将窗体移动到主显示器的工作区中心

procedure CenterFormOnMainScreen(Form: TForm);
var
  MainWorkArea: TRect;
begin
  // 获取主显示器的工作区
  MainWorkArea := Screen.PrimaryMonitor.WorkareaRect;
  // 计算窗体左上角的目标坐标
  Form.Left := MainWorkArea.Left + (MainWorkArea.Width - Form.Width) div 2;
  Form.Top := MainWorkArea.Top + (MainWorkArea.Height - Form.Height) div 2;
end;
// 调用示例
procedure TForm1.Button2Click(Sender: TObject);
begin
  CenterFormOnMainScreen(Self);
end;

场景4:GDI+ 和第三方库

许多高级绘图库(如 GDI+、OpenGL 等)在 Delphi 中的封装也广泛使用 TRect 或类似的结构来定义裁剪区域、绘制目标等。


总结与最佳实践

  1. 优先使用 const:对于绝大多数只需要读取矩形信息的函数,使用 const ARect: TRect 是最佳实践,它既安全又高效。
  2. 明确使用 var:当函数的目的是修改原始矩形时,才使用 var ARect: TRect,这清晰地表达了函数的“副作用”。
  3. 理解坐标系统:始终记住 TRectRightBottom开区间,这在处理像素、裁剪区域时尤其重要。
  4. 利用 IsEmpty:在计算面积、交集或并集之前,先用 IsEmpty 判断矩形是否有效,可以避免很多潜在的错误。
  5. 熟悉常用方法InflateBy, Contains, Intersect, Union 等方法非常实用,能极大简化你的代码。

希望这份详细的解释能帮助你更好地理解和使用 Delphi 中的 TRect 参数!

-- 展开阅读全文 --
头像
2025人工智能基金,该选哪些?
« 上一篇 今天
非智能4K电视,功能是否已过时?
下一篇 » 今天

相关文章

取消
微信二维码
支付宝二维码

最近发表

标签列表

目录[+]