从IfileOperation.GetDisplayName中的IShellItem获取文件名
我钩住了从IfileOperation.GetDisplayName中的IShellItem获取文件名,shell,delphi,com,shfileoperation,Shell,Delphi,Com,Shfileoperation,我钩住了IFileOperation的CopyItems方法来监视/拦截windows中的文件复制。 我的问题是如何从IShellItem(CopyItems的最后一个参数)检索完整文件名 psiDestinationFolder有一个名为GetDisplayName的方法,该方法只返回开始复制的当前文件的文件夹名!!但我想得到完整的文件名,却不知道该怎么办!?有没有其他方法可以帮助我获得全名??或者我必须使用另一个API 如果我的英语不好,请原谅 CopyItems方法可能复制多个项目。因此,
IFileOperation
的CopyItems
方法来监视/拦截windows中的文件复制。
我的问题是如何从IShellItem
(CopyItems的最后一个参数)检索完整文件名
psiDestinationFolder
有一个名为GetDisplayName
的方法,该方法只返回开始复制的当前文件的文件夹名!!但我想得到完整的文件名,却不知道该怎么办!?有没有其他方法可以帮助我获得全名??或者我必须使用另一个API
如果我的英语不好,请原谅 CopyItems方法可能复制多个项目。因此,一下子你就错找了一个文件名。这是一个非常复杂的API,您需要仔细阅读并清楚地理解函数的工作原理
psiDestinationFolder
参数是标识目标的IShellItem
。使用GetDisplayName
方法获取文件路径
另一个参数,punkItems
更复杂。记录如下:
指向IShellItemArray、IDataObject或IEnumShellItems对象的IUnknown的指针,该对象表示要复制的项组。您还可以指向IPersistIDList对象来表示单个项,从而有效地实现与IFileOperation::CopyItem相同的功能
这告诉您,在您收到的IUnknown
接口后面可能有IShellItemArray
、IDataObject
、IEnumShellItems
或IPersistIDList
对象。单个对象中可能有多个项目,每个项目都要复制到目标文件夹。您需要依次查询每个可能的接口的punkItems
,直到您找到必须处理的这些可能性。然后用特殊代码处理每一个。为了测试这一点,您需要编写代码,用每个可能的接口调用CopyItems
。您将从四个接口中的每个接口的文档中了解如何完成所有这些。如果您还不熟悉shell编程和COM,请在完成这项工作时完成
最后,我怀疑这是检测文件复制的一种非常好的方法。使用许多不同的API复制文件。而
IFileOperation.CopyItems
只是其中之一。如果你只钩住IFileOperation.CopyItems,那么你会错过很多文件复制操作。这不是TCustomFileDialog.GetItemName所做的吗?@TLama我使用这个方法,但只返回文件路径!而不是完整的文件名!在两种情况下,我得到了相同的结果。Davide,punkItems可以帮助我获得源文件的文件路径!为此,我应该使用punkItems.QueryInterface(IID\u IShellItemArray,\u ShellItemArray)
将punkItems转换为ShellItemArray
,然后从ShellItemArray
获取当前文件路径!但是QueryInterface
总是返回false!你能帮我转换吗?请再次阅读我的答案和文档。仔细阅读并理解punkItems可能是不支持IShellItemArray的对象。我阅读了您的答案,我测试了转换为IDataObject
,但只返回falsepunkItems.QueryInterface(IID\u IDataObject,\u DataObject)
!继续浏览列表。不过,我的最后一段给出了最好的建议。谢谢,关于你的最后一段:我发现挂钩ZwReadFile
和ZwWriteFile
是最好的方法!它工作得很好,但很难将FileCopy/FileCut与其他文件操作区分开来!
function New_CopyItems(p: Pointer; punkItems: IUnknown;psiDestinationFolder: IShellItem): HResult; stdcall;