Search code examples
delphiclipboardtstream

How to load a stream with a file copied in Windows clipboard


I've copied a file into the Windows clipboard (By simply clicking right, copy). I would like to load a TStream descendant with the file currently stored in the clipboard.

uses
  Classes, Clipbrd;

MyStream := TMemoryStream.Create;
try
  //here I would like to load the clipboard file into MyStream
finally
  MyStream.Free;
end;

Solution

  • When you copy a file onto the clipboard from the hard drive, it simply copies the file's full path and filename in CF_HDROP format. You can use the DragQueryFile() function to read the filenames, eg:

    uses
      Classes, Clipbrd, ShellAPI;
    
    var
      hDrop: THandle
      MyStream: TMemoryStream;
      Files: TStringList;
      NumFiles, FileIdx: DWORD;
      FileName: array[0..MAX_PATH] of Char;
      I: Integer;
    begin
      Files := TStringList.Create;
      try
        Clipboard.Open;
        try
          if Clipboard.HasFormat(CF_HDROP) then
          begin
            // DO NOT free this handle, the clipboard owns it!
            hDrop := Clipboard.GetAsHandle(CF_HDROP);
            NumFiles := DragQueryFile(hDrop, $FFFFFFFF, nil, 0);
            if NumFiles <> 0 then
            begin
              for FileIdx := 0 to NumFiles-1 do
              begin
                if DragQueryFile(hDrop, FileIdx, FileName, MAX_PATH) <> 0 then
                  Files.Add(FileName);
              end;
            end;
          end;
        finally
          Clipboard.Close;
        end;
        for I := 0 to Files.Count-1 do
        begin
          MyStream := TMemoryStream.Create;
          try
            MyStream.LoadFromFile(Files[I]);
            MyStream.Position := 0;
            // use MyStream as needed...
          finally
            MyStream.Free;
          end;
        end;
      finally
        Files.Free;
      end;
    end;