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

unit clipbak;  interfaceuses    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.