TClipboard.SetComponent/GetComponent 讓你在應用內或應用間以二進制組件流形式複製粘貼任意 VCL 組件(含屬性、子控件樹)。比文本/圖片格式強大得多,是構建可視化設計器、模板系統的核心 API。
| 方法 | 類型 | 說明 |
|---|---|---|
SetComponent(Component) | 過程 | 將組件序列化放入剪貼簿(格式 CF_COMPONENT) |
GetComponent(AOwner, AParent) | 函數 | 反序列化並返回新組件實例 |
HasFormat(CF_COMPONENT) | 函數 | 檢查剪貼簿是否包含組件格式 |
Edit1:源編輯框Panel1:目標容器btnCopy、btnPaste、btnDelete 三按鈕unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
type
TForm1 = class(TForm)
Edit1: TEdit;
Panel1: TPanel;
btnCopy: TButton;
btnPaste: TButton;
btnDelete: TButton;
procedure btnCopyClick(Sender: TObject);
procedure btnPasteClick(Sender: TObject);
procedure btnDeleteClick(Sender: TObject);
private
FPastedComponent: TComponent;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
uses Clipbrd;
procedure TForm1.btnCopyClick(Sender: TObject);
begin
// 一鍵放入剪貼簿
Clipboard.SetComponent(Edit1);
btnCopy.Caption := '已複製';
end;
procedure TForm1.btnPasteClick(Sender: TObject);
begin
// 1. 格式檢查
if not Clipboard.HasFormat(CF_COMPONENT) then Exit;
// 2. 反序列化:Owner=Self(Form), Parent=Panel1
FPastedComponent := Clipboard.GetComponent(Self, Panel1);
if Assigned(FPastedComponent) then
begin
// 3. 微調位置避免重疊
with FPastedComponent as TControl do
SetBounds(Left + 20, Top + 20, Width, Height);
btnPaste.Caption := '已粘貼';
end;
end;
procedure TForm1.btnDeleteClick(Sender: TObject);
begin
if Assigned(FPastedComponent) then
begin
FPastedComponent.Free; // 釋放副本
FPastedComponent := nil;
btnDelete.Caption := '已刪除';
end;
end;
initialization
// 關鍵:註冊 TEdit 類,否則 GetComponent 拋出 ClassNotFound
RegisterClasses([TEdit]);
end.
CF_COMPONENT:Delphi 專有格式Windows 預定義格式(CF_TEXT、CF_BITMAP 等)不含組件流。CF_COMPONENT 是 Delphi 內部註冊的私有格式(RegisterClipboardFormat('Delphi Component')),僅 Delphi 應用間互通。
RegisterClasses 必須性EClassNotFound 異常。initialization 區塊集中註冊,避免重複調用與遺漏。GetComponent(AOwner, AParent) 參數詳解| 參數 | 傳值 | 效果 |
|---|---|---|
| AOwner | Self (Form) | 新組件歸 Form 管理,Form 銷毀時自動釋放 |
| AOwner | nil | 需手動 Free,適合臨時對象 |
| AParent | Panel1 | 新組件視覺掛載到 Panel1,座標相對 Panel1 |
| AParent | nil | 無父容器,需手動設 Parent 才可見 |
| 現象 | 原因 | 解決 |
|---|---|---|
| 粘貼後組件不可見 | AParent=nil 或 Parent 未設 | 傳有效 Parent 或粘貼後手動 Parent := Panel1 |
| ClassNotFound 異常 | 忘記 RegisterClasses | initialization 區塊註冊所有涉及類 |
| 事件失效 | 流式不保存方法指針 | 粘貼後代碼重新綁定 OnClick 等 |
| 跨應用粘貼失敗 | 目標應用未註冊相同類 | 雙方共用組件單元或運行時包含相同類定義 |
SetComponent/GetComponent 是 Delphi 組件級複製粘貼的「核武器」。掌握 註冊類、Owner/Parent 語義、格式檢查、事件重綁 四要素,即可構建強大的可視化編輯、模板復用、組件庫拖放等高級功能。