Copy Files To Clipboard - Delphi

DarkCoderSc personal avatar
DarkCoderSc

Jean-Pierre LESUEUR

uses
  Generics.Collections, System.SysUtils, Winapi.Windows, Winapi.ShlObj;

// ...

function CopyFilesToClipboard(const AFiles : TList<String>) : Cardinal;
begin
  result := 0;
  ///

  if not Assigned(AFiles) or (AFiles.Count = 0) then
    Exit();

  if not OpenClipboard(0) then
    raise EWindowsException.Create('OpenClipboard');
  try
    if not EmptyClipboard() then
      raise EWindowsException.Create('EmptyClipboard');

    var ADataLength := 0;
    for var AFile in AFiles do
      Inc(ADataLength, (Length(AFile)+1) * SizeOf(WideChar));
    Inc(ADataLength, SizeOf(TDropFiles));
    Inc(ADataLength); // Extra NULL byte

    var hMem := GlobalAlloc(GHND {GMEM_MOVEABLE + GMEM_ZEROINIT}, ADataLength);
    try
      var pMem := GlobalLock(hMem);
      try
        var ADropFiles : TDropFiles;
        ZeroMemory(@ADropFiles, SizeOf(TDropFiles));
        ADropFiles.pFiles := SizeOf(TDropFiles); // First file path offset
        ADropFiles.fWide := True;
        ///

        var pOffset := pMem;

        CopyMemory(pOffset, @ADropFiles, SizeOf(TDropFiles));

        pOffset := Pointer(NativeUInt(pOffset) + SizeOf(TDropFiles));

        for var I := 0 to AFiles.Count -1 do begin
          var AFilePathLength := (Length(AFiles[I])+1) * SizeOf(WideChar);

          CopyMemory(pOffset, PWideChar(AFiles[I]), AFilePathLength);

          ///
          pOffset := Pointer(NativeUInt(pOffset) + AFilePathLength);
        end;

        if SetClipboardData(CF_HDROP, hMem) = 0 then
          raise EWindowsException.Create('SetClipboardData');

        ///
        result := AFiles.Count;
      finally
        GlobalUnlock(hMem);
      end;
    finally
      GlobalFree(hMem);
    end;
  finally
    CloseClipboard();
  end;
end;

// ...

var AFiles := TList<String>.Create();
try
  AFiles.Add('C:\Temp\file1.txt');
  AFiles.Add('C:\Temp\file2.txt');

  ///
  CopyFilesToClipboard(AFiles);
finally
  FreeAndNil(AFiles);
end;

// ...

Creating and researching code snippets takes time and effort. You’re welcome to share them through your own platforms, but please don’t forget to credit the original author, here: Jean-Pierre LESUEUR.

Depends On


Created

May 9, 2025

Last Revised

May 14, 2025