Delphi实现复制和剪切文件以及复制文件到剪贴板

5bug 2018-01-07 47人围观 ,发现0个评论 Delphi剪切文件RegisterClipboardFormatDROPEFFECT_COPYDROPEFFECT_MOVESetClipboardData

在做云盘功能的时候,要实现一个在云盘里对着云盘文件进行Ctrl+C/Ctrl+X的时候能够在本地资源管理器里进行粘贴的操作,当时的想法是先检查文件是否下载到本地,如果已经下载了那么就模拟资源管理器的复制或者剪切动作就行了,既然是Windows的操作那么应该会有相关的API可以用,当时查阅了一些资料后,成功实现了该功能,这里把当时的研究结果分享出来:

复制或剪切某文件

procedure CutOrCopyFiles(const AFileName: String; const IsCopy, IsEmptyClipboard: Boolean);
var
  hGblFileList: hGlobal;
  pFileListDate: Pbyte;
  HandleDropEffect: UINT;
  hGblDropEffect: hGlobal;
  pdwDropEffect: PDWORD;
  iLen: Integer;
  LFileName: AnsiString;
begin
  LFileName := AnsiString(AFileName) + #0;
  iLen := Length(LFileName) * SizeOf(AnsiChar);
  hGblFileList := GlobalAlloc(GMEM_ZEROINIT or GMEM_MOVEABLE or GMEM_SHARE, SizeOf(TDropFiles) + iLen + 1);
  pFileListDate := GlobalLock(hGblFileList);
  try
    PDropFiles(pFileListDate)^.pfiles := SizeOf(TDropFiles);
    PDropFiles(pFileListDate)^.pt.Y := 0;
    PDropFiles(pFileListDate)^.pt.X := 0;
    PDropFiles(pFileListDate)^.fNC := False;
    PDropFiles(pFileListDate)^.fwide := False;
    Inc(pFileListDate, SizeOf(TDropFiles));
    CopyMemory(pFileListDate, @LFileName[1], iLen);
    Inc(pFileListDate, iLen);
    PAnsiChar(pFileListDate)^ := #0;
  finally
    GlobalUnlock(hGblFileList);
  end;
  HandleDropEffect := RegisterClipboardFormat('Preferred DropEffect');
  hGblDropEffect := GlobalAlloc(GMEM_ZEROINIT or GMEM_MOVEABLE or GMEM_SHARE, SizeOf(DWORD));
  pdwDropEffect := GlobalLock(hGblDropEffect);
  try
    if IsCopy then
      pdwDropEffect^ := DROPEFFECT_COPY
    else
      pdwDropEffect^ := DROPEFFECT_MOVE;
  finally
    GlobalUnlock(hGblDropEffect);
  end;
  if OpenClipboard(0) then
  begin
    if IsEmptyClipboard then
      EmptyClipboard();
    SetClipboardData(HandleDropEffect, hGblDropEffect);
    SetClipboardData(CF_HDROP, hGblFileList);
    CloseClipboard();
  end;
end;

复制某个文件内容到剪贴板

procedure CopyFileToClipbrd(const AFileName: string);
var
  FE: TFormatEtc;
  Medium: TStgMedium;
  dropfiles: PDropFiles;
  pFile: PAnsiChar;
  LFileName: AnsiString;
begin
  LFileName := AnsiString(AFileName);
  FE.cfFormat := CF_HDROP;
  FE.dwAspect := DVASPECT_CONTENT;
  FE.tymed := TYMED_HGLOBAL;
  Medium.hGlobal := GlobalAlloc(GMEM_SHARE or GMEM_ZEROINIT, SizeOf(TDropFiles) + Length(LFileName) *
    SizeOf(AnsiChar) + 1);
  if Medium.hGlobal <> 0 then
  begin
    Medium.tymed := TYMED_HGLOBAL;
    dropfiles := GlobalLock(Medium.hGlobal);
    try
      dropfiles^.pfiles := SizeOf(TDropFiles);
      dropfiles^.fwide := False;
      LongInt(pFile) := LongInt(dropfiles) + SizeOf(TDropFiles);
      lstrcatA(pFile, PAnsiChar(LFileName));
      Inc(pFile, Length(LFileName) * SizeOf(AnsiChar) + 1);
      pFile^ := #0;
    finally
      GlobalUnlock(Medium.hGlobal);
    end;
    Clipboard.Clear;
    Clipboard.Open;
    Clipboard.SetAsHandle(CF_HDROP, Medium.hGlobal);
    Clipboard.Close;
  end;
end;


请扫码加入QQ群
微信二维码
不容错过
Powered By Z-BlogPHP