如何创建“Shell IDList Array”以支持将虚拟文件从C#拖放到Wind
我开始尝试使用
this codeproject tutorial实现对虚拟文件(来自C#4 / WPF应用程序)的拖放.在花了一些时间
trying to figure out a DV_E_FORMATETC错误后,我发现我需要支持“Shell IDList Array”数据格式.但是关于这种格式实际上做了什么似乎只有零文档.
经过一些搜索,我发现this page on advanced data transfer表示Shell IDList数组是指向CIDA structure的指针.这个CIDA结构然后包含PIDL的数量,以及它们的偏移列表.那究竟是什么PIDL?经过一些搜索后,this page意味着它是一个指向ITEMIDLIST的指针,它本身包含一个SHITEMID列表的成员. 我做了一些阅读,我仍然无法分辨多个PIDL是什么,但路径中的每个“级别”都有一个SHITEMID.至少那个谜团已经解决了. 我的下一个想法是尝试使用虚拟文件(WinSCP)从另一个应用程序拖动文件.我刚刚为这种格式安装了一个MemoryStream.至少我知道要为这个东西提供什么类,但这根本不能解释放入它的内容.我尝试根据上面链接中的格式检查这个MemoryStream,但是我没有成功.我刚拿回垃圾数据,其中一个’cb’字段告诉我,当整个流只有539字节时,它是18000字节长. 另外,在进一步阅读时,this page似乎暗示PIDL中包含的数据实际上是一个路径,并且在十六进制编辑器中检查所述MemoryStream的内容在我的本地Temp目录中产生了一条路径(分成几部分,无论如何). 似乎WinSCP只是使用shell扩展来处理在资源管理器上的丢弃,这是我真的不想诉诸的.但是,它有一个替代模式,它会中止dragdrop,直到它转移到临时文件夹 – 这对我来说是可以接受的,但我不知道如何做到这一点. 我现在的问题是: >什么是SHITEMID的有效“abID”成员?这些虚拟文件仅与我的程序一起存在;他们被拖动的东西会在以后执行GetData时传回“abID”吗?他们必须是系统独特的吗? 任何帮助甚至链接解释我应该做什么将不胜感激. 编辑:所以这就是我最终实际做到的方式: 我从上面的CodeProject教程中删除了大部分代码,保留了创建FileGroupDescriptor的功能.然后我重新实现了.Net IDataObject接口(实际上,我根本不必使用COM IDataObject接口).然后我被迫在后台同步下载文件,并从GetData()传回MemoryStream.方便的是,实际复制在后台,但等待数据在前台.谢谢,探险家.任何相当大的文件都很慢,但是现在它“有效”,这比过去几周我说的还要多. 我确实试过传递我在内部使用的PipeStream类进行传输,但是资源管理器对此并不满意: >它试图寻求,尽管这个类有CanSeek是假的. 所以,我不确定理想的情况是否真的可行.不过,谢谢你的帮助.我正在给予JPW赏金,因为他的回复最终让我走上了正确的道路. 解决方法
免责声明:我既不是Windows Shell编程专家也不是COM编程专家,特别是在使用.NET的COM编程中.
免责声明2:Shell编程相当复杂,Windows资源管理器可能会崩溃. (请务必阅读有关调试shell扩展的MSDN上的信息.) 这是我能回答你的问题: > SHITEMID的abID值由包含相应项的文件夹确定.因此,没有有效或无效的信息,因为此数据仅对该文件夹有用. Windows资源管理器将传递此数据以标识特定项目. abID不能是系统唯一的,但它在包含文件夹中可能是唯一的(虽然这不能保证).在某些情况下,SHITEMID可能会被持久化,因此在某些情况下它必须在重新启动后有效(因为应该避免在abID中使用此内存引用). 我希望一些信息对你有用. 编辑:您还可以适当地实现QueryGetData和EnumerableFormatEtc,以指示您的对象不支持相关格式.也许Windows资源管理器会尝试不同的格式. 编辑2:虽然你已经确定了一个解决方案,但这里有一些关于如何异步拖放的信息(对于大文件),也许你(或者至少有人在寻找类似问题的答案,谁读取发现它很有用:http://msdn.microsoft.com/en-us/library/bb776904(VS.85).aspx#async (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |