元件開發是 Delphi 進階的分水嶺。本文以倒數計時器元件 TTimeCount 為完整案例,演示從繼承層級選擇、成員/屬性/方法/事件設計、祖先屬性顯化、封裝安裝與圖示製作 的標準化流程。所有程式碼經 Delphi 7 驗證。
TPanel 只是將 TCustomPanel 的 protected 屬性在 published 區重新宣告(顯化)TCustomPanel 並按需顯化,更乾淨type
TInterval = (TenM, TwentyM, ThirtyM, FortyM, FiftyM, SixtyM); // 觸發間隔列舉
TTimeCount = class(TCustomPanel)
private
FTimer: TTimer; // 核心計時器
FCount: Integer; // 秒數計數器(0-3599 循環)
FInterval: TInterval; // 觸發間隔設定
FActive: Boolean; // 是否啟用間隔事件
TimeLen: Integer; // 間隔對應秒數(內部用)
TimeNum: Integer; // 已計秒數(內部用)
FTimeOut: TNotifyEvent; // 間隔事件代理
procedure SetInterval(I: TInterval);
procedure SetActive(A: Boolean);
procedure FTimerTimer(Sender: TObject); // TTimer.OnTimer 處理
protected
procedure DoTimeOut; dynamic; // 事件調度器
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure Start; // 從 0 開始
procedure Stop; // 歸零停止
procedure Pause; // 暫停
procedure Resume; // 繼續
property Count: Integer read FCount; // 唯讀屬性,僅運行期取值
published
property Interval: TInterval read FInterval write SetInterval default TenM;
property Active: Boolean read FActive write SetActive default False;
property OnTimeOut: TNotifyEvent read FTimeOut write FTimeOut;
// 按需顯化祖先屬性
property BevelInner; property BevelOuter; property BevelWidth;
property Color; property Font; property PopupMenu; property ShowHint;
property TabOrder; property TabStop; property Visible;
property OnClick; property OnDblClick; property OnMouseDown;
property OnMouseMove; property OnMouseUp;
end;
constructor TTimeCount.Create(AOwner: TComponent);
procedure CreateTimer;
begin
FTimer := TTimer.Create(Self);
FTimer.Enabled := False;
FTimer.Interval := 1000; // 1 秒
FTimer.OnTimer := FTimerTimer;
end;
procedure SetView; // 預設外觀
begin
Width := 100; Height := 50;
Color := clBlack; Font.Color := clWhite; Font.Size := 14;
Font.Style := [fsBold, fsUnderline];
BevelOuter := bvLowered; Caption := '0';
end;
begin
inherited Create(AOwner);
FCount := 0; FInterval := TenM; FActive := False;
TimeLen := 600; TimeNum := 0; // 預設 10 分鐘
CreateTimer; SetView;
end;
destructor TTimeCount.Destroy;
begin
FTimer.Free;
inherited Destroy;
end;
procedure TTimeCount.FTimerTimer(Sender: TObject);
begin
Inc(FCount);
if (FCount mod 3600) = 0 then FCount := 0; // 1 小時歸零
Caption := IntToStr(FCount); // 直接顯示於 Panel Caption
Inc(TimeNum);
if (TimeNum = TimeLen) and FActive then begin
DoTimeOut; // 觸發間隔事件
TimeNum := 0;
end;
end;
procedure TTimeCount.DoTimeOut;
begin
if Assigned(FTimeOut) then FTimeOut(Self);
end;
procedure TTimeCount.Start;
begin
if (not FTimer.Enabled) and (TimeNum = 0) then FTimer.Enabled := True;
end;
procedure TTimeCount.Stop;
begin
FTimer.Enabled := False; FCount := 0; TimeNum := 0; Caption := '0';
end;
procedure TTimeCount.Pause;
begin
if FTimer.Enabled then FTimer.Enabled := False;
end;
procedure TTimeCount.Resume;
begin
if not FTimer.Enabled then FTimer.Enabled := True;
end;
procedure TTimeCount.SetInterval(I: TInterval);
begin
if FInterval <> I then begin
FInterval := I;
case FInterval of
TenM: TimeLen := 600; TwentyM: TimeLen := 1200; ThirtyM: TimeLen := 1800;
FortyM: TimeLen := 2400; FiftyM: TimeLen := 3000; SixtyM: TimeLen := 3600;
end;
end;
end;
procedure TTimeCount.SetActive(A: Boolean);
begin
if FActive <> A then begin
FActive := A; TimeNum := 0;
end;
end;
TimeCount.pas,放入專用資料夾(如 $(DELPHI)\MyCom\)TCustomPanelTTimeCountSamples(或自訂)TimeCountMyCom 路徑Register 程序)TimeCount.pas,Package 選 dclusr.dpk,確定編譯安裝Image Editor → 新建 .dcr → 建立 24×24 位圖 → 名稱 TTIMECOUNT(大寫類別名) → 存檔為 TIMECOUNT.dcr 放入單元目錄 → 重新安裝File → Open → dclusr.dpk → Contains 選中 TimeCount.pas → Remove → Compile
procedure TForm1.FormCreate(Sender: TObject);
begin
TimeCount1.Interval := ThirtyM; // 30 分鐘觸發
TimeCount1.Active := True;
TimeCount1.OnTimeOut := TimeCount1TimeOut;
TimeCount1.Start;
end;
procedure TForm1.TimeCount1TimeOut(Sender: TObject);
begin
Beep; // 或 ShowMessage('休息時間到!');
end;
此元件結構清晰、邏輯自洽,是學習 VCL 元件開發流程的最佳範本。掌握此流程,即可著手開發更複雜的資料感知、圖形繪製、複合型元件。