Delphi 如何在Explorer和TcxShellListView之间实现无缝剪贴板?
我有一个模仿Windows资源管理器的应用程序,它在其他shell控件中使用了Delphi 如何在Explorer和TcxShellListView之间实现无缝剪贴板?,delphi,devexpress,delphi-xe2,clipboard,explorer,Delphi,Devexpress,Delphi Xe2,Clipboard,Explorer,我有一个模仿Windows资源管理器的应用程序,它在其他shell控件中使用了TcxShellListView 一个非常好的功能是能够在真正的Windows资源管理器和我的应用程序之间复制和粘贴和剪切和粘贴文件 拖放已经可以开箱即用,但DevExpress似乎还没有实现剪贴板端 有什么想法吗?如果您想自己实现复制/粘贴,其机制几乎与拖放相同。您拥有的拖放代码将创建一个IDataObject。要复制,只需调用OleSetClipboard传递IDataObject即可,而不是调用DoDragDro
TcxShellListView
一个非常好的功能是能够在真正的Windows资源管理器和我的应用程序之间复制和粘贴
和剪切和粘贴
文件
拖放
已经可以开箱即用,但DevExpress似乎还没有实现剪贴板端
有什么想法吗?如果您想自己实现复制/粘贴,其机制几乎与拖放相同。您拥有的拖放代码将创建一个
IDataObject
。要复制,只需调用OleSetClipboard
传递IDataObject
即可,而不是调用DoDragDrop
启动拖动。对于粘贴,您可以调用OleGetClipboard
从剪贴板获取IDataObject
。然后您只需使用与drop操作完全相同的代码来解码IDataObject
。就这些
还有另一种方法,在我看来可能是更好的方法。这就是使用IContextMenu
来完成工作。这方面的例子可以在TurboPower tpShellShock项目中找到。在StShlCtl
单元中查找ShellMenuExecute
。只要DevExpress组件使用shell接口,即IShellFolder
,您就可以使用相同的方法。这种基于shell的方法的优点是,您可以让shell完成工作。如果需要显示一个复制对话框,那么shell将这样做。这将为您提供最完整的用户体验
此代码如下所示:
procedure ShellMenuExecute(
const Sender : TObject; const Folder : IShellFolder;
var Pidl : PItemIDList; const Count : Integer;
const AHandle : THandle; ClipboardAction : TStMenuAction);
var
CM : IContextMenu;
CI : TCmInvokeCommandInfo;
begin
if Folder <> nil then begin
if (Folder.GetUIObjectOf(AHandle, Count, Pidl,
IID_IContextMenu, nil, Pointer(CM)) = NOERROR)
then begin
ZeroMemory(@CI, SizeOf(CI));
CI.cbSize := SizeOf(TCmInvokeCommandInfo);
CI.hwnd := AHandle;
case ClipboardAction of
caCut : CI.lpVerb := 'cut';
caCopy : CI.lpVerb := 'copy';
caPaste : CI.lpVerb := 'paste';
caProperties : CI.lpVerb := 'properties';
end;
CM.InvokeCommand(CI);
CM := nil;
end;
end;
end;
过程ShellMenuExecute(
常量发送方:ToObject;常量文件夹:IShellFolder;
变量Pidl:PItemIDList;常量计数:整数;
常量AHandle:THandle;剪贴板操作:TStMenuAction);
变量
CM:IContextMenu;
CI:TCmInvokeCommandInfo;
开始
如果文件夹为零,则开始
if(Folder.GetUIObjectOf)(AHandle、Count、Pidl、,
IID_IContextMenu,无,指针(CM))=无错误)
然后开始
零内存(@CI,SizeOf(CI));
CI.cbSize:=SizeOf(TCmInvokeCommandInfo);
CI.hwnd:=AHandle;
案例剪贴簿
caCut:CI.lpVerb:='cut';
caCopy:CI.lpVerb:=“复制”;
capast:CI.lpVerb:=“粘贴”;
caproperty:CI.lpVerb:=“属性”;
结束;
CM.调用命令(CI);
厘米:=零;
结束;
结束;
结束;
我认为你应该能够很好地使用这段代码。我要指出的是,handle参数的声明不正确。它应该是HWND
。它被用作调用InvokeCommand
期间显示的任何对话框的所有者窗口