Recent

Author Topic: [SOLVED] Copy file to clipboard  (Read 956 times)

rvk

  • Hero Member
  • *****
  • Posts: 4329
Re: Copy file to clipboard
« Reply #15 on: September 28, 2020, 09:07:17 pm »
The problem with InsertImageFromFile is that the image isn't rendered (just an icon appears), but works with copy / paste.
Is that also true if you safe and reload the file?
If that's the case it is inserted as object, not as image.

Does pasting a file in richmemo work?
I only tried a text document and that also just got an icon in wordpad.
Will test further tomorrow.

pcurtis

  • Sr. Member
  • ****
  • Posts: 311
Re: Copy file to clipboard
« Reply #16 on: September 28, 2020, 10:25:34 pm »
Quote
Is that also true if you safe and reload the file?
If that's the case it is inserted as object, not as image.
Yes

Quote
Does pasting a file in richmemo work?
I only tried a text document and that also just got an icon in wordpad.
Will test further tomorrow.

Copy / paste only seems to work for images, text files create an icon.
« Last Edit: September 28, 2020, 10:29:42 pm by pcurtis »
Windows 10 / Linux Mint 20
Laz 2.10.0
FPC 3.2.0

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 825
    • Lebeau Software
Re: Copy file to clipboard
« Reply #17 on: September 28, 2020, 10:45:18 pm »
I don't know how Lazarus's TRichEdit works, but in a standard Win32 RichEdit control (such as wrapped in Delphi's TRichEdit), you insert images by using the EM_GETOLEINTERFACE message to get the RichEdit's IRichEditOle interface, and then call its InsertObject() method, giving it an IOleObject interface for the image data.  See How to Use OLE in Rich Edit Controls.
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

jamie

  • Hero Member
  • *****
  • Posts: 3665
Re: Copy file to clipboard
« Reply #18 on: September 28, 2020, 11:11:10 pm »
Is this all about the shell operation of dragging and dropping file list of names and where as the receiving window needs to be registered to accept or receive WM_DROPFILE messages ?

 If this is the case, the TFORM has a OnDropFiles event, you need to enable it. "AllowDropFiles"..

 If you are trying to initiate a drop operation then let me know, cause I think I have the code somewhere around here for that.
The only true wisdom is knowing you know nothing

pcurtis

  • Sr. Member
  • ****
  • Posts: 311
Re: Copy file to clipboard
« Reply #19 on: September 29, 2020, 02:41:12 am »
OK All I think it's time for a recap.

1. Get a clipboard viewer. I use https://www.freeclipboardviewer.com/FreeClipViewer.zip

2. Run the program.

3. Open Explorer, and find an image file and copy it to the clipboard.

4. Note the changes in the clipboard viewer.

5. Open Wordpad. You should be able to paste the previously copied image into Wordpad.

6. My opening question was

Quote
Hi All,
How do I copy a file to the clipboard?

To which it was suggested to try the following code

Code: Pascal  [Select][+][-]
  1. procedure CopyFileToClipboard(FileList : string);
  2. var
  3.   DropFiles: PDropFiles;
  4.   hGlobal: THandle;
  5.   iLen: integer;
  6.   CFSTR_FILEDESCRIPTOR, CFSTR_FILECONTENTS : UINT;
  7. begin
  8.   //CFSTR_FILEDESCRIPTOR := RegisterClipboardFormat();
  9.   iLen := Length(FileList) + 2;
  10.   FileList := FileList + #0#0;
  11.   hGlobal := GlobalAlloc(GMEM_SHARE or GMEM_MOVEABLE or GMEM_ZEROINIT,
  12.     SizeOf(TDropFiles) + iLen);
  13.   if (hGlobal = 0) then
  14.     raise Exception.Create('Could not allocate memory.');
  15.   begin
  16.     DropFiles := GlobalLock(hGlobal);
  17.     DropFiles^.pFiles := SizeOf(TDropFiles);
  18.     Move(FileList[1], (PChar(DropFiles) + SizeOf(TDropFiles))^, iLen);
  19.     GlobalUnlock(hGlobal);
  20.     OpenClipboard(Form1.Handle);
  21.     EmptyClipboard;
  22.     SetClipboardData(CF_HDROP, hGlobal);
  23.     CloseClipboard;
  24.    end;
  25. end;
  26.  
  27.  
  28.  
  29. procedure TForm1.Button1Click(Sender: TObject);
  30. begin
  31.   CopyFileToClipboard('d:\Lazarus\Icons\bug-64.ico');
  32. end;  
  33.  

Which copies a list of files to the clipboard. Which is NOT what I need.

I need a way to copy the file as in step 1.

I was advised to look at https://docs.microsoft.com/en-us/windows/win32/controls/using-rich-edit-com which looks promising but I don't speak 'C'.
« Last Edit: September 29, 2020, 09:19:35 am by pcurtis »
Windows 10 / Linux Mint 20
Laz 2.10.0
FPC 3.2.0

rvk

  • Hero Member
  • *****
  • Posts: 4329
Re: Copy file to clipboard
« Reply #20 on: September 29, 2020, 11:12:33 am »
Ok, this might work (it worked for me).

Code: Pascal  [Select][+][-]
  1. uses Windows, ShlObj, ComObj, ActiveX;
  2.  
  3. function SHBindToObject(const psf: IShellFolder; pidl: PItemIDList;
  4.   const pbc: IBindCtx; const riid: TIID; var ppv: Pointer): HResult; stdcall; external 'shell32' name 'SHBindToObject';
  5.  
  6. procedure CopyFilesToClipboard2(const Folder: widestring; FileNames: TStrings);
  7. var
  8.   SF: IShellFolder;
  9.   PidlFolder: PItemIDList;
  10.   PidlChildren: array of PItemIDList;
  11.   Eaten: UINT;
  12.   Attrs: DWORD;
  13.   Obj: IDataObject;
  14.   I: Integer;
  15.   Filename: widestring;
  16. begin
  17.   if (Folder = '') or (FileNames = nil) or (FileNames.Count = 0) then Exit;
  18.   OleCheck(SHParseDisplayName(PWideChar(Folder), nil, PidlFolder, 0, @Attrs));
  19.   try
  20.     OleCheck(SHBindToObject(nil, PidlFolder, nil, IShellFolder, Pointer(SF)));
  21.   finally
  22.     CoTaskMemFree(PidlFolder);
  23.   end;
  24.   SetLength(PidlChildren, FileNames.Count);
  25.   for I := Low(PidlChildren) to High(PidlChildren) do
  26.     PidlChildren[i] := nil;
  27.   try
  28.     for I := 0 to FileNames.Count-1 do
  29.     begin
  30.       Filename := Filenames[i];
  31.       OleCheck(SF.ParseDisplayName(0, nil, PWideChar(FileName), Eaten, PidlChildren[i], Attrs));
  32.  
  33.     end;
  34.     OleCheck(SF.GetUIObjectOf(0, FileNames.Count, PIdlChildren[0], IDataObject, nil, obj));
  35.   finally
  36.     for I := Low(PidlChildren) to High(PidlChildren) do
  37.     begin
  38.       if PidlChildren[i] <> nil then
  39.         CoTaskMemFree(PidlChildren[i]);
  40.     end;
  41.   end;
  42.   OleCheck(OleSetClipboard(obj));
  43.   OleCheck(OleFlushClipboard);
  44. end;
  45.  
  46. procedure TForm1.Button1Click(Sender: TObject);
  47. var
  48.   FileNames: TStringList;
  49. begin
  50.   FileNames := TStringList.Create;
  51.   try
  52.     FileNames.Add('file1.jpg');
  53.     CopyFilesToClipboard2('C:\Your_directory_with_the_files', FileNames);
  54.   finally
  55.     FileNames.Free;
  56.   end;
  57. end;

pcurtis

  • Sr. Member
  • ****
  • Posts: 311
Re: Copy file to clipboard
« Reply #21 on: September 29, 2020, 12:08:07 pm »
rvk - Your the man! It works perfectly.

Thank you so much.
Windows 10 / Linux Mint 20
Laz 2.10.0
FPC 3.2.0

 

TinyPortal © 2005-2018