在 Delphi 圖形繪製中,TPen 類控制線條的顏色、寬度、樣式與繪圖模式。其中 pmXor(異或模式)配合 Canvas.MoveTo/LineTo 可輕鬆實現「橡皮筋線」效果:滑鼠拖曳時線條即時顯示,釋放滑鼠後保留最終位置,再次拖曳可擦除舊線。本文詳細解析原理並提供完整可運行範例。
Canvas.Pen.Mode := pmXor 時,繪圖顏色 = 畫筆顏色 XOR 背景顏色。關鍵特性:
procedure TForm1.Button1Click(Sender: TObject);
begin
Canvas.Pen.Color := clYellow;
Canvas.Pen.Width := 20;
Canvas.Pen.Mode := pmXor; { 異或模式 }
Canvas.MoveTo(0, 0);
Canvas.LineTo(ClientWidth, ClientHeight);
end;
連續點擊按鈕,線條會在「顯示」與「消失」之間切換。
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
procedure FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
var
x1, y1, x2, y2: Integer; { 線段兩端點 }
fDrawing: Boolean; { 是否正在拖曳 }
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
x1 := X; y1 := Y;
x2 := X; y2 := Y;
Canvas.Pen.Color := clRed;
Canvas.Pen.Width := 2;
Canvas.Pen.Mode := pmXor;
fDrawing := True;
end;
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
if fDrawing then
begin
{ 1. 擦除舊線 }
Canvas.MoveTo(x1, y1);
Canvas.LineTo(x2, y2);
{ 2. 更新終點並重繪新線 }
x2 := X; y2 := Y;
Canvas.MoveTo(x1, y1);
Canvas.LineTo(x2, y2);
end;
end;
procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if fDrawing then
begin
{ 最後一次擦除動態線 }
Canvas.MoveTo(x1, y1);
Canvas.LineTo(x2, y2);
{ 以 pmCopy 模式畫出確定線條 }
Canvas.Pen.Mode := pmCopy;
Canvas.MoveTo(x1, y1);
Canvas.LineTo(x2, y2);
fDrawing := False;
end;
end;
end.
pmXor,標記開始拖曳。pmCopy 畫出永久線條,重置旗標。MouseUp 時加入列表,Paint 事件統一重繪,避免視窗重繪時線條消失。TPaintBox 或自定義控件上啟用 DoubleBuffered := True,消除閃爍。| 現象 | 原因 | 解決 |
|---|---|---|
| 線條拖動時殘留 | 未正確擦除舊線 | 確保 MouseMove 先用相同座標畫一次 |
| 釋放滑鼠後線條消失 | 未切換 pmCopy 重畫 | MouseUp 中必須 Canvas.Pen.Mode := pmCopy 再畫一次 |
| 視窗最小化恢復後線條不見 | 未處理 OnPaint | 改用持久化列表並在 OnPaint 重繪 |
掌握 pmXor 特性,即可用極少代碼實現專業級的橡皮筋選取與繪圖交互,是 Delphi 圖形編程的必備技能。