在 Delphi 中繪圖首先需要 TCanvas 實例。除表單/控件自帶 Canvas 屬性外,還可透過 GetDC 獲取裝置上下文並包裝為 TCanvas,或針對無 Canvas 屬性的控件 (如 TPanel) 間接繪圖。本文詳解三種方法的適用場景與資源管理要點。
// TForm, TPaintBox, TImage, TCustomControl 等直接擁有
Form1.Canvas.TextOut(10, 10, 'Hello');
PaintBox1.Canvas.FillRect(PaintBox1.ClientRect);
procedure TForm1.Button1Click(Sender: TObject);
var
Cvs: TCanvas;
begin
// TPanel 無 Canvas 屬性,但有 Handle
Cvs := TCanvas.Create;
try
Cvs.Handle := GetDC(Panel1.Handle); // 獲取裝置上下文
Cvs.Brush.Color := clBlue;
Cvs.FillRect(Panel1.ClientRect); // 在 Panel 上繪圖
finally
ReleaseDC(Panel1.Handle, Cvs.Handle); // 必須釋放 DC
Cvs.Free; // 釋放 TCanvas 包裝器
end;
end;
// TPaintBox 類似 TForm,直接擁有 Canvas
PaintBox1.Canvas.Brush.Color := clRed;
PaintBox1.Canvas.FillRect(PaintBox1.ClientRect);
procedure TForm1.Button1Click(Sender: TObject);
var
Cvs: TCanvas;
begin
// PaintBox1 直接使用 Canvas
PaintBox1.Canvas.Brush.Color := clRed;
PaintBox1.Canvas.FillRect(PaintBox1.ClientRect);
// Panel1 間接獲取 Canvas
Cvs := TCanvas.Create;
try
Cvs.Handle := GetDC(Panel1.Handle);
Cvs.Brush.Color := clBlue;
Cvs.FillRect(Panel1.ClientRect);
finally
ReleaseDC(Panel1.Handle, Cvs.Handle);
Cvs.Free;
end;
end;
| 方法 | 建立責任 | 釋放責任 | DC 所有權 |
|---|---|---|---|
| 控件.Canvas | 控件內部 | 控件銷毀時自動 | 控件管理 |
| TCanvas.Create + GetDC | 開發者 | 開發者 (try/finally) | 開發者必須 ReleaseDC |
| TCanvas.Create + SetWindowDC | 開發者 | 開發者 | 視窗類管理 (較少用) |