请问如何编程实现资源管理器中的文件复制/粘贴功能(300分)

  • 主题发起人 主题发起人 kde
  • 开始时间 开始时间
K

kde

Unregistered / Unconfirmed
GUEST, unregistred user!
我仔细察看了以前关于该问题的回答,发现有以下几种回答:
1. 使用TClipBoard类实现。我看了Delphi提供的这个类,发现它并没有专门为文件复制提
供相应的格式,函数以及例子。所以我还是不知道具体如何实现。
2. 在《Delphi3从入门到精通》上有述及此问题。问题是,这本书现在不好找,书店里也
没了,网上也没电子书,所以也不好解决。
3. “复制任意文件或文件夹到剪贴板”就是复制了文件路径到剪贴板。其实好像没有这么
简单,我复制了一个路径(而非文件)到剪贴版,然后在资源管理器中就无法象正常情况下
那样粘贴。
4. 用拖放操作模拟相应的复制/粘贴操作,如沈前卫兄的贴子。但是拖放操作并不能很好地
模拟所有情况下的操作,如复制/粘贴到同一目录下。我所希望的是和资源管理器完全相同的
操作,而不是模拟。

据此,我只好再次提出此问题,希望大侠们能给我一个满意的回答。
 
你可以直接把复制了的文件路径放到一个变量里,可以用TStrings的变量,这样能一次
操作多个文件。我做过类似的程序,这是个好办法
 
D6提供了一组 Shell 的控件, 如TShellListView等,本身具有Windows Shell窗口
的所有属性,使用很方便。如果是低版本的Delphi可以使用 ShellAPI 单元中的
function DragQueryFile(Drop: HDROP; FileIndex: UINT; FileName: PChar; cb: UINT): UINT;
function DragQueryPoint(Drop: HDROP; var Point: TPoint): BOOL;
procedure DragFinish(Drop: HDROP);
procedure DragAcceptFiles(Wnd: HWND; Accept: BOOL);
编写文件拖拽的程序。
 
to C-xy:
您的方法与我问题中的回答3类似,但是这种方法与操作系统不兼容。也就是说,如果在
你的程序里复制了一个文件,然后跑到Windows的资源管理器中粘贴它,就不行了。

to OopsWare:
我用的是Delphi 5.0,所以恐怕无法使用6.0的新特性。至于使用ShellAPI中的拖放操作,
我程序中需要的不是这个,而是复制/粘贴(注意这两个操作是分开来进行的,而拖放相当
于同时执行了这两个操作)。
 
這是兩個毫不相干的程序在通信﹐是有點困難的。
至于復制﹑粘貼是分開的兩個動作可以成功﹐是因為它們共享了剪貼板這塊內存。
如果是其它程序有提供接口﹐可以使用ole或com﹐但似乎資源管理器沒有。
 
要监视简帖版可以 override TWinControl 的 WndProc
case Message.Msg of
WM_DRAWCLIPBOARD: // ....
end;

或者使用单元:
unit MyClipBoard;
interface
uses
Windows, Messages, SysUtils, ClipBrd;
procedure StartClipMonitor(Handle: THandle);
procedure EndClipMonitor(Handle: THandle);
procedure ProcessClipMessage(var Message: TMessage);
implementation
uses
CGConsts, Main, MiscFuncs, AddUrlOne;
var
NextClipHwnd: THandle;
procedure StartClipMonitor(Handle: THandle);
begin //
NextClipHwnd:=SetClipBoardViewer(Handle);
end;
procedure EndClipMonitor(Handle: THandle);
begin
ChangeClipboardChain(Handle,NextClipHwnd);
SendMessage(NextClipHwnd, WM_CHANGECBCHAIN, Handle, NextClipHwnd);
NextClipHwnd := 0;
end;
procedure ProcessClipMessage(var Message: TMessage);
var url: string;
begin
SendMessage(NextClipHwnd, Message.Msg, Message.WParam, Message.LParam);
if (Clipboard.HasFormat(CF_TEXT) or Clipboard.HasFormat(CF_OEMTEXT)) then begin
// Text Clipboard data ...
end;
end;
end.

多数情况下,简帖板中的文件信息不是纯文本,最好使用
CF_IDLIST := RegisterClipboardFormat(CFSTR_SHELLIDLIST);
获得简帖版中的内容,这将用到许多 ShellAPI ShlObj 单元的东西,代码较多,不便贴出了。
 
 那位大虾有源代码,可以拿出来吧 lzj_29@163.com
 
复制任意文件/文件夹到剪贴板(还是沈前卫的答案):
procedure CopyToClipBoard(FileName:string);
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(MainForm.Handle);
EmptyClipboard;
SetClipboardData(CF_HDROP, DataHandle);
CloseClipboard;
end;

其中FileName是完整路径名。如有多个文件,可用#0隔开,例如:
FileName:='c:/a.txt'+#0+'c:/b.txt'+#0;
绝对可行。
 
后退
顶部