首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> Delphi

Delphi 繪圖進階:TPen 類應用與橡皮筋線(Rubber Band)實現

     編輯:Delphi

在 Delphi 圖形繪製中,TPen 類控制線條的顏色、寬度、樣式與繪圖模式。其中 pmXor(異或模式)配合 Canvas.MoveTo/LineTo 可輕鬆實現「橡皮筋線」效果:滑鼠拖曳時線條即時顯示,釋放滑鼠後保留最終位置,再次拖曳可擦除舊線。本文詳細解析原理並提供完整可運行範例。

核心原理:pmXor 異或模式

Canvas.Pen.Mode := pmXor 時,繪圖顏色 = 畫筆顏色 XOR 背景顏色。關鍵特性:

  • 自反性:同一座標重複繪製兩次,畫面恢復原狀(即「擦除」)。
  • 無需背景存儲:不需額外 Bitmap 緩衝,效能極高。

基礎示例:單次異或畫線

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.

關鍵步驟解析

  1. MouseDown:記錄起點,設定畫筆屬性與 pmXor,標記開始拖曳。
  2. MouseMove:若正在拖曳,先以相同座標再畫一次舊線(擦除),再更新終點畫新線。
  3. MouseUp:再次畫舊線擦除動態線,切換至 pmCopy 畫出永久線條,重置旗標。

進階擴展建議

  • 多圖形支援:將端點與圖形類型封裝為類,MouseUp 時加入列表,Paint 事件統一重繪,避免視窗重繪時線條消失。
  • 雙緩衝:在 TPaintBox 或自定義控件上啟用 DoubleBuffered := True,消除閃爍。
  • 撤銷/重做:維護命令堆疊,支援多步驟編輯。

常見問題排查

現象原因解決
線條拖動時殘留未正確擦除舊線確保 MouseMove 先用相同座標畫一次
釋放滑鼠後線條消失未切換 pmCopy 重畫MouseUp 中必須 Canvas.Pen.Mode := pmCopy 再畫一次
視窗最小化恢復後線條不見未處理 OnPaint改用持久化列表並在 OnPaint 重繪

掌握 pmXor 特性,即可用極少代碼實現專業級的橡皮筋選取與繪圖交互,是 Delphi 圖形編程的必備技能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved