备份还原剪切板

发布时间 2023-11-24 09:28:52作者: Tag

忘记是抄谁的了,这里改进了一下。还原后没有clear 并再一次备份。
因为还原一次后,如果再还原,会句柄无效的。

unit clipbak;
  
interface
uses  
  SysUtils, Classes, Clipbrd, Windows, Contnrs, Dialogs;
  
type
  TClipData = class
    Format: WORD;  
    Data: THANDLE;  
  end;  
  
  TClipBackuper = class  
  private  
    ClipList: TList;  
  public  
    constructor Create;  
    destructor Destroy; override;  
    procedure BackupClip();
    function RestoreClip:Boolean;
  end;  
  

implementation  


constructor TClipBackuper.Create;  
begin  
  Cliplist := TObjectList.Create;  
end;  
  
destructor TClipBackuper.Destroy;  
begin  
  ClipList.Free;  
end;     
  
procedure TClipBackuper.BackupClip;  
var  
  i: Integer;
  Data: THANDLE;  
  pcd: TClipData;  
  DataMem: Pointer;
  FileName : array [0..255] of Char;
  FileStr:string;
begin  
  ClipList.Clear;
  Clipboard.Open;
  try  
    for i := 0 to Clipboard.FormatCount - 1 do
    begin
      pcd := TClipData.Create;  

      pcd.Format := Clipboard.Formats[i];
      Data := THANDLE(Clipboard.GetAsHandle( pcd.Format));
//      GetClipboardFormatName(pcd.Format, FileName, 255);
//      FileStr := string(FileName);
//      OutputDebugString(pchar(FileStr));
      if (Data = 0) then
      begin
        pcd.free;
        continue;
      end;
      //分配内存
      pcd.Data := GlobalAlloc(GMEM_MOVEABLE or GMEM_DDESHARE, GlobalSize(Data));
      //锁定内存
      DataMem := GlobalLock(pcd.Data);
      //有分配成功的话,复制当前剪切板的内存数据
      if (DataMem <> nil) then
      begin
        CopyMemory(DataMem, GlobalLock(Data), GlobalSize(Data));
        //解锁
        GlobalUnlock(THANDLE(pcd.Data));
        GlobalUnlock(THANDLE(Data));
      end;
      ClipList.Add(pcd);
    end;  
  finally  
    Clipboard.Close;
  end;
end;


//还原回去后,要再一次backup 不然再RestoreClip 不会再一次还原不会成功
function TClipBackuper.RestoreClip:Boolean;
var  
  pcd: TClipData;  
  i: Integer;
begin  
  Clipboard.Open();  
  try
    Clipboard.Clear();  
    for i := 0 to ClipList.Count - 1 do  
    begin
      pcd := TClipData(ClipList[i]);
      if SetClipboardData(pcd.Format, pcd.Data) <= 0 then
      begin
       Result := False;
       Exit;
      end;
    end;
  finally
    Clipboard().Close();
  end;
  BackupClip; //再备份一次
  Result := True;
end;
  
end.