TClipboard 定義在 Clipbrd 單元,提供三組文本操作介面,滿足從簡單到進階的不同需求。
| 方式 | API | 特點 | 適用場景 |
|---|---|---|---|
| 屬性式 | AsText: string | 最簡單,自動編碼轉換,Unicode 就緒 | 90% 日常文本複製粘貼 |
| 緩衝區式 | SetTextBuf/GetTextBuf(PChar, Len) | 直接操作 PChar 緩衝區,無額外字串分配 | 高頻大量文本、C/C++ 互操作 |
| 手動內存 | GetMem/FreeMem + GetTextBuf | 完全控制內存生命週期 | 特殊編碼、超大文本流式處理 |
uses Clipbrd;
procedure TForm1.btnSimpleClick(Sender: TObject);
begin
// 寫入:隱式創建全局 Clipboard 實例
Clipboard.AsText := 'Hello, Delphi 剪貼簿!';
// 讀取:同一進程內可跨單元訪問
ShowMessage('剪貼簿內容: ' + Clipboard.AsText);
end;
Clipboard 全局函數的單例模式// Clipbrd.pas 核心實現簡化版
var
FClipboard: TClipboard;
function Clipboard: TClipboard;
begin
if FClipboard = nil then
FClipboard := TClipboard.Create; // 首次調用創建
Result := FClipboard;
end;
// 程式結束時自動釋放(在單元 finalization 區)
finalization
FClipboard.Free;
關鍵認知:Clipboard 是無參函數,返回進程級單例 TClipboard。不要手動 Create/Free,也不要以為它是像 Screen 那樣的全局變量。
SetTextBuf/GetTextBufuses Clipbrd;
procedure TForm1.btnBufferClick(Sender: TObject);
var
Buf: array[0..1023] of Char; // 固定棧上緩衝區
Len: Integer;
begin
// 寫入:PChar 轉換
Clipboard.SetTextBuf(PChar('直接寫入緩衝區文本'));
// 讀取:雙緩衝區模式(先查長度再讀取更安全)
Len := Clipboard.GetTextBuf(nil, 0); // 獲取所需長度
if Len > 0 then
begin
if Len > SizeOf(Buf) then Len := SizeOf(Buf); // 防溢出
Clipboard.GetTextBuf(@Buf[0], Len);
ShowMessage('讀取: ' + string(Buf));
end;
end;
GetTextBuf 參數陷阱GetTextBuf(Dest, DestSize):最多複製 DestSize-1 字符,自動添加 #0 結束符。GetTextBuf(nil, 0) 查實際長度。procedure TForm1.btnManualMemClick(Sender: TObject);
var
P: PChar;
Len: Integer;
begin
Clipboard.AsText := '手動內存測試';
Len := Clipboard.GetTextBuf(nil, 0); // 查長度
if Len = 0 then Exit;
GetMem(P, Len + 1); // +1 留結束符
try
Clipboard.GetTextBuf(P, Len + 1);
ShowMessage('手動內存讀取: ' + string(P));
finally
FreeMem(P);
end;
end;
string = UnicodeString,AsText 內部自動處理 Unicode ↔ 系統代碼頁/UTF-8 轉換。SetTextBuf 接受 PChar(即 PWideChar),寫入 Unicode 文本無需轉碼。CF_UNICODETEXT (Unicode) 和 CF_TEXT (ANSI),目標應用自行選擇讀取。| 錯誤代碼 | 問題 | 修正 |
|---|---|---|
var C: TClipboard; C := TClipboard.Create; | 創建第二個實例,破壞單例 | 直接用 Clipboard 函數 |
Clipboard.Free | 釋放全局單例,後續調用 AV | 絕不手動 Free |
GetTextBuf(Buf, 256) 不檢查長度 | 長文本截斷無感知 | 先 GetTextBuf(nil,0) 查長度 |
用 AsText 處理 10MB+ 大文本 | 字串雙倍內存、性能差 | 用流式分塊或緩衝區模式 |
uses Clipbrd, Winapi.Messages;
type
TForm1 = class(TForm)
private
procedure WMClipboardUpdate(var Msg: TMessage); message WM_CLIPBOARDUPDATE;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
// Win8+ 支持,需調用 AddClipboardFormatListener(Handle)
// 老版本需 SetClipboardViewer 串聯鏈表
end;
procedure TForm1.WMClipboardUpdate(var Msg: TMessage);
begin
// 剪貼簿內容發生變化
Log('Clipboard changed: ' + Clipboard.AsText);
end;
Delphi 文本剪貼簿操作核心就三句話:
Clipboard.AsText := ... / Clipboard.AsText 最省心。SetTextBuf/GetTextBuf,注意雙緩衝區查長度。Clipboard 是單例函數,絕不手動 Create/Free。掌握這三點,應對所有文本剪貼簿場景綽綽有餘。