复制任意文件或文件夹到剪贴板usesShlObj, ClipBrd; procedure CopyFilesToClipboard(FileList: string); var DropFiles: PDropFiles; hGlobal: THandle; iLen: Integer; begin iLen := Length(FileList) + 2; FileList := FileList + #0#0; hGlobal := GlobalAlloc(GMEM_SHARE or GMEM_MOVEABLE or GMEM_ZEROINIT, SizeOf(TDropFiles) + iLen); if (hGlobal = 0) then raise Exception.Create('Could not allocate memory.'); begin DropFiles := GlobalLock(hGlobal); DropFiles^.pFiles := SizeOf(TDropFiles); Move(FileList[1], (PChar(DropFiles) + SizeOf(TDropFiles))^, iLen); GlobalUnlock(hGlobal); Clipboard.SetAsHandle(CF_HDROP, hGlobal); end; end; // Example: procedure TForm1.Button1Click(Sender: TObject); begin CopyFilesToClipboard('C:\Bootlog.Txt'#0'C:\AutoExec.Bat'); end; { Separate the files with a #0. } ******************************** 沈前卫的回答 : unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls,ShlObj; type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.DFM} procedure TForm1.Button1Click(Sender: TObject); const FileName:string='c:\netlog.txt'; var DataHandle: THandle; DataPointer: PDROPFILES; begin DataHandle := GlobalAlloc(GMEM_DDESHARE or GMEM_MOVEABLE,SizeOf(DROPFILES)+2+Length(FileName)); DataPointer := PDROPFILES(GlobalLock(DataHandle)); FillChar(DataPointer^,SizeOf(DROPFILES)+2+Length(FileName),0); DataPointer.pFiles:=SizeOf(DROPFILES); DataPointer.pt:=Point(0,0); DataPointer.fNC:=False; DataPointer.fWide:=False; Move(FileName[1],Pointer(Integer(DataPointer)+SizeOf(DROPFILES))^,Length(FileName)); GlobalUnlock(DataHandle); OpenClipboard(Form1.Handle); EmptyClipboard; SetClipboardData(CF_HDROP, DataHandle); CloseClipboard; end; end. *************************** 在 Windows 的资源管理器中 ,选中一个或多个文件 ,在文件上单击鼠标右键 ,在弹出菜单中选复制。再切换到另外的目录 ,单击鼠标右键 ,点粘贴。就这样执行了一次文件的拷贝操作 ,那么 Windows 在拷贝过程中执行了什么操作 ,是否将整个文件拷贝到剪贴板上了呢?当然没有。实际上 ,Windows 只是将一个文件结构拷贝到了剪贴版 ,这个结构如下 : tDropFile+ 文件 1 文件名 +vbNullChar+ 文件 2 文件名 +vbNullChar …… + 文件 N 文件名 +vbNullChar,其中 tDropFile 是一个 DROPFILES 结构 ,这个结构在 Windows API 中有定义。在粘贴文件时 ,利用 API 函数 DragQueryFile 就可以获得拷贝到剪贴板的文件全路径名 ,然后就可以根据获得的文件名执行文件拷贝函数 ,实现对文件的粘贴操作。 那么如何从剪切板或取复制的文件内容呢?请参看下面的例子 : /// Author:Peter Below uses clipbrd, shellapi; {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); var f: THandle; buffer: array [0..MAX_PATH] of Char; i, numFiles: Integer; begin if not Clipboard.HasFormat(CF_HDROP) then Exit; Clipboard.Open; try f := Clipboard.GetAsHandle(CF_HDROP); if f <> 0 then begin numFiles := DragQueryFile(f, $FFFFFFFF, nil, 0); memo1.Clear; for i := 0 to numfiles - 1 do begin buffer[0] := #0; DragQueryFile(f, i, buffer, SizeOf(buffer)); memo1.Lines.Add(buffer); end; end; finally Clipboard.Close; end; end; |
|