| 函數 | 參數形式 | 填充 | 邊框 | 特殊行為 |
| Rectangle | (X1,Y1,X2,Y2) 或 Rect | Brush | Pen | 標準矩形,支援 TRect 重載 |
| RoundRect | (X1,Y1,X2,Y2, X3,Y3) | Brush | Pen | 圓角矩形,X3/Y3 為橢圓寬高 |
| DrawFocusRect | Rect | 無 (XOR 模式) | 無 (系統虛線) | 焦點虛線框,不受 Pen/Brush 影響 |
| FrameRect | Rect | 無 | Brush (非 Pen!) | 用畫刷描邊,寬度固定 1 像素 |
完整範例:五個按鈕對應五種繪製
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton; // Rectangle (座標)
Button2: TButton; // Rectangle (TRect)
Button3: TButton; // RoundRect
Button4: TButton; // DrawFocusRect
Button5: TButton; // FrameRect
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure Button5Click(Sender: TObject);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
var
Btn: TButton;
const
Y1 = 10;
Y2 = 80;
procedure TForm1.FormCreate(Sender: TObject);
begin
Canvas.Pen.Width := 4;
Canvas.Pen.Color := clRed;
Canvas.Brush.Color := clWhite;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Btn := TButton(Sender);
Canvas.Rectangle(Btn.Left, Y1, Btn.Left + Btn.Width, Y2);
end;
procedure TForm1.Button2Click(Sender: TObject);
var
R: TRect;
begin
Btn := TButton(Sender);
R := Rect(Btn.Left, Y1, Btn.Left + Btn.Width, Y2);
Canvas.Rectangle(R);
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
Btn := TButton(Sender);
Canvas.RoundRect(Btn.Left, Y1, Btn.Left + Btn.Width, Y2, 20, 20);
end;
procedure TForm1.Button4Click(Sender: TObject);
var
R: TRect;
begin
Btn := TButton(Sender);
R := Rect(Btn.Left, Y1, Btn.Left + Btn.Width, Y2);
Canvas.DrawFocusRect(R);
end;
procedure TForm1.Button5Click(Sender: TObject);
var
R: TRect;
begin
Btn := TButton(Sender);
R := Rect(Btn.Left, Y1, Btn.Left + Btn.Width, Y2);
Canvas.FrameRect(R);
end;
end.
視覺效果詳細解析
- Rectangle (座標/TRect):白色填充矩形 + 紅色 4px 邊框 (兩種參數形式等價)
- RoundRect:白色填充圓角矩形 + 紅色邊框,圓角半徑 20x20 (X3=水平半徑, Y3=垂直半徑)
- DrawFocusRect:黑白虛線框 (系統焦點樣式),不受 Pen/Brush 影響,重疊區域顏色反轉 (XOR 模式)
- FrameRect:用 Brush 顏色 (白色) 描 1px 邊框,內部不填充,Pen 設定完全被忽略
關鍵差異深度解析
Rectangle vs RoundRect
- RoundRect 額外兩參數
X3, Y3:圓角橢圓的寬度和高度
X3=Y3=0 等同 Rectangle
X3=Y3=Width/2 可畫圓/橢圓 (但用 Ellipse 更直觀)
DrawFocusRect 獨特行為
- 專為焦點指示設計,繪製 1px 寬虛線框
- 使用
pmXor 模式:背景亮→框暗,背景暗→框亮,保證可見性
- 不消耗 GDI 畫筆/畫刷物件,極輕量
- 呼叫兩次同一矩形可「擦除」 (XOR 可逆性)
FrameRect 反直覺點:用 Brush 不用 Pen
FrameRect(Rect) 相當於:在 Rect 邊界向內畫 1px 寬的線,顏色 = Brush.Color
Pen.Width、Pen.Style、Pen.Color 全部無效
- 等效代碼:
Canvas.Brush.Color := clRed; Canvas.FrameRect(R); → 紅色 1px 邊框
常見陷阱與避坑
- FrameRect 忽略 Pen:以為用紅筆畫框,實際用白刷畫框 → 幾乎不可見
- DrawFocusRect 不受控:嘗試設定 Pen.Color 改變顏色 → 無效
- RoundRect 圓角過大:X3 > Width/2 或 Y3 > Height/2 時行為未定義
- Rectangle 參數順序:Left < Right, Top < Bottom,否則不繪製
進階:自定義寬度描邊 (替代 FrameRect)
procedure FrameRectEx(ACanvas: TCanvas; const R: TRect; Width: Integer);
var
Outer, Inner: TRect;
begin
Outer := R;
Inner := Rect(R.Left + Width, R.Top + Width, R.Right - Width, R.Bottom - Width);
ACanvas.Brush.Style := bsSolid;
// 外框填充
ACanvas.FillRect(Outer);
// 內框挖空 (用 bsClear 或反向填充)
ACanvas.Brush.Style := bsClear;
ACanvas.FillRect(Inner);
// 或用 ExcludeClipRect + FillRect
end;
效能提示
- 四函數皆為單次 GDI 調用,效能極高
- 大量矩形批次繪製:考慮
PolyPolygon 或組合 FillRect + FrameRectEx
- DrawFocusRect 最輕量,適合高頻閃爍焦點提示
搞清「Rectangle/圓角用 Pen+Brush、焦點框用 XOR、描邊用 Brush」這條核心分工線,能避開 90% 的矩形繪製顏色/寬度不可控問題。
- 上一篇文章: Delphi 圓弧類圖形繪製:Ellipse、Pie、Chord、Arc 完整指南
- 下一篇文章: Delphi 繪圖入門:Canvas、Pen、Brush 基礎操作與直線矩形範例
Copyright ©
程式碼之家 All Rights Reserved