Image 組件內容或窗體圖形直接拷貝到剪貼板,使用 Clipboard.Assign:
Clipboard.Assign(Image1.Picture); // 將 Image1 圖像拷貝到剪貼板
先拷貝到剪貼板,再用空白圖像覆蓋原位置:
procedure TForm1.Cut1Click(Sender: TObject);
var ARect: TRect;
begin
Clipboard.Assign(Image1.Picture);
with Image1.Canvas do
begin
CopyMode := cmWhiteness;
ARect := Rect(0, 0, Image1.Width, Image1.Height);
CopyRect(ARect, Image1.Canvas, ARect);
CopyMode := cmSrcCopy;
end;
end;
檢測格式為 CF_BITMAP,調用目標位圖 Assign 方法:
procedure TForm1.PasteButtonClick(Sender: TObject);
var Bitmap: TBitmap;
begin
if Clipboard.HasFormat(CF_BITMAP) then
begin
Bitmap := TBitmap.Create;
try
Bitmap.Assign(Clipboard);
Image1.Canvas.Draw(0, 0, Bitmap);
finally
Bitmap.Free;
end;
end;
end;
try...finally 保護資源(詳見第十二章)。
Windows 允許用戶建立觀察程序並加入觀察器鏈。鏈首程序直接接收消息,靠前程序有義務傳遞消息給下一個。Delphi 用 message 關鍵字響應特定 Windows 消息:
procedure WMDrawClipboard(var Msg: TWMDrawClipboard);
message WM_DRAWCLIPBOARD;
TWMDrawClipboard 為消息類子類,Delphi 重新定義所有消息,提供便利數據成員,無需手工分解。
主窗口 TClipSaveForm 定義私有成員:MyBitmap: TBitmap(保存截獲位圖)、View: Boolean(是否顯示)、NextViewerHandle: HWND(下一觀察器句柄)。消息響應方法:
procedure WMDrawClipboard(var Msg: TWMDrawClipboard); message WM_DRAWCLIPBOARD;
procedure WMChangeCBChain(var Msg: TWMChangeCBChain); message WM_CHANGECBCHAIN;
procedure TClipSaveForm.FormCreate(Sender: TObject);
begin
View := False; SpeedButton2.Down := True;
MyBitmap := TBitmap.Create;
try MyBitmap.Width := 0; MyBitmap.Height := 0; except Application.Terminate; end;
Clipboard.Clear;
NextViewerHandle := SetClipboardViewer(Handle); // 註冊觀察器
end;
procedure TClipSaveForm.FormDestroy(Sender: TObject);
begin
ChangeClipboardChain(Handle, NextViewerHandle); // 退出觀察器鏈
MyBitmap.Free;
end;
SetClipboardViewer/ChangeClipboardChain 為 Windows API。
procedure TClipSaveForm.WMDrawClipboard(var Msg: TWMDrawClipboard);
var FileName: String;
begin
if NextViewerHandle <> 0 then
SendMessage(NextViewerHandle, Msg.Msg, 0, 0); // 傳遞消息給下一觀察器
if Clipboard.HasFormat(CF_BITMAP) then
begin
MyBitmap.Assign(Clipboard); // 保存位圖
if SaveDialog1.Execute then
begin
FileName := SaveDialog1.FileName;
MyBitmap.SaveToFile(FileName); // 保存到文件
end;
if View then
begin
WindowState := wsNormal;
Image1.Picture.Bitmap := MyBitmap; // 顯示位圖
end;
end;
Msg.Result := 0;
end;
義務傳遞消息 → 判斷位圖格式 → 保存到 MyBitmap → 彈出保存對話框存文件 → View=True 時顯示窗口並賦值給 Image1。