TextRect 兩大重載版本深度解析:矩形裁剪與豐富格式化
Canvas.TextRect 提供比 TextOut 更強大的矩形區域文字輸出功能。它有兩種重載:簡單版 (指定座標) 與進階版 (支援 TTextFormat 格式化選項)。掌握它們能實現自動換行、對齊、省略號、垂直置中等專業排版效果。
重載 1:簡單座標版
procedure TextRect(Rect: TRect; X, Y: Integer; const Text: string);
- Rect:裁剪矩形,超出部分不顯示
- X, Y:相對視窗原點的輸出起始座標
- Text:輸出文字
範例:裁剪效果演示
procedure TForm1.Button1Click(Sender: TObject);
const
R: TRect = (Left: 0; Top: 0; Right: 60; Bottom: 60);
S = '萬一的 Delphi 博客';
begin
Canvas.Brush.Color := clWhite;
Canvas.FillRect(R); // 白底便於觀察
Canvas.TextRect(R, 10, 10, S); // 僅顯示矩形內部分
end;
重載 2:進階格式化版 (核心功能)
procedure TextRect(var Rect: TRect; var Text: string; TextFormat: TTextFormat = []);
- Rect:
var 參數,tfCalcRect 時返回實際需求矩形
- Text:
var 參數,tfModifyString 時可能修改 (如添加省略號)
- TextFormat:
TTextFormat 集合,組合多種排版選項
TTextFormat 完整選項對照表
| 常數 | 效果 | 備註 |
| tfTop | 頂部對齊 | 預設 |
| tfBottom | 底部對齊 | |
| tfVerticalCenter | 垂直置中 | |
| tfLeft | 左對齊 | 預設 |
| tfRight | 右對齊 | |
| tfCenter | 水平置中 | |
| tfSingleLine | 單行模式 | 不換行,超出裁剪 |
| tfWordBreak | 單詞換行 | 英文單詞不拆分 |
| tfEndEllipsis | 尾部省略號 | 截斷處顯示 ... |
| tfPathEllipsis | 路徑省略號 | 保留檔名,中間 ... |
| tfExpandTabs | 展開 Tab 鍵 | 轉為空格 |
| tfNoClip | 不裁剪 | 允許超出 Rect 繪製 |
| tfNoPrefix | 不處理 & 前綴 | 避免快捷鍵下劃線 |
| tfModifyString | 允許修改 Text | 配合省略號使用 |
| tfRtlReading | 右到左閱讀序 | 阿拉伯/希伯來文 |
| tfCalcRect | 僅計算矩形 | 不實際繪製,Rect 返回需求大小 |
| tfExternalLeading | 包含外部行距 | 行高計算包含 ExternalLeading |
| tfEditControl | 編輯控件模式 | 模擬 Edit 控件繪製行為 |
實戰範例 1:預設對齊 (左上)
procedure TForm1.FormPaint(Sender: TObject);
var
R: TRect; S: string;
begin
R := ClientRect;
InflateRect(R, -10, -10); // 內縮 10px
S := 'Delphi';
Canvas.Brush.Color := clWhite;
Canvas.FillRect(R);
Canvas.TextRect(R, S); // 預設 tfTop + tfLeft
end;
實戰範例 2:單行水平垂直置中
procedure TForm1.FormPaint(Sender: TObject);
var
R: TRect; S: string;
begin
R := ClientRect;
InflateRect(R, -10, -10);
S := 'Delphi';
Canvas.Brush.Color := clWhite;
Canvas.FillRect(R);
Canvas.TextRect(R, S, [tfSingleLine, tfCenter, tfVerticalCenter]);
end;
實戰範例 3:多行自動換行 + 省略號
procedure TForm1.FormPaint(Sender: TObject);
var
R: TRect; S: string;
begin
R := Rect(10, 10, 200, 100);
S := '這是一段很長的文字,用於演示自動換行和省略號功能,當空間不足時會在末尾顯示三個點。';
Canvas.Brush.Color := clWhite;
Canvas.FillRect(R);
Canvas.TextRect(R, S, [tfWordBreak, tfEndEllipsis, tfModifyString]);
// 超出高度時自動截斷並加 ...
end;
實戰範例 4:tfCalcRect 計算所需高度 (自適應高度)
function GetTextHeight(ACanvas: TCanvas; const Text: string; Width: Integer): Integer;
var
R: TRect; S: string;
begin
R := Rect(0, 0, Width, 0);
S := Text;
ACanvas.TextRect(R, S, [tfCalcRect, tfWordBreak]);
Result := R.Bottom - R.Top;
end;
// 使用
var H := GetTextHeight(Canvas, '長文字...', 200);
關鍵差異對照
| 特性 | 重載 1 (座標版) | 重載 2 (格式化版) |
| 裁剪 | 硬性裁剪 (超出不畫) | 可控 (tfNoClip / tfEndEllipsis) |
| 對齊 | 無 (固定 X,Y) | 全方位 (9 種組合) |
| 換行 | 不支援 | tfWordBreak / tfSingleLine |
| 省略號 | 不支援 | tfEndEllipsis / tfPathEllipsis |
| 計算尺寸 | 無 | tfCalcRect |
| 修改文字 | 無 | tfModifyString |
| 底層 API | ExtTextOut | DrawTextEx |
常見陷阱
- var 參數不能傳常量:
TextRect(Rect, 'Hello', [...]) 編譯錯誤,需用變數
- tfCalcRect 時不實際繪製:僅更新 Rect,需再次調用不帶 tfCalcRect 才畫
- tfEndEllipsis 需 tfSingleLine 或 tfModifyString:多行模式下省略號行為未定義
- 高 DPI 下 Rect 單位為邏輯像素:配合
MulDiv 換算
TextRect 進階版本是 Delphi 內建最接近專業排版引擎的 API,善用 TTextFormat 組合能解決 90% 的 UI 文字顯示需求。
- 上一篇文章: Delphi TFont 字體屬性完全指南:Name、Size、Color、Style、Charset、Orientation
- 下一篇文章: Delphi Canvas.TextOut 文字輸出實戰:逐字繪製古詩與度量應用
Copyright ©
程式碼之家 All Rights Reserved