系列专题:【附源码】Windows Shell接口之VB实现(一):ICopyHook接口【源码下载地址】:http://210.33.90.250/download/vbsrc/vbcopyhook.rarShell有很多很多的接口,不过由于种种原因,在VB里面实现起来不是那么的简单,弄的人少了,这方面的资料也自然不是很多……最可气的是,国内竟然找不到那本可以说具有指导意义的Visual Basic Shell Programming卖……前几个星期突然想到是否做个windows外壳的系列,一方面提高自己的COM水平,另一方面也充实一下这互联网的资料库,呵呵 ^_^第1集是ICopyHook接口。ICopyHook是在系统进行文件夹和打印机操作前回调的一个具有确认效果的接口。举例来说,文件夹改名、复制、删除的时候系统就会调用这个接口。关于这个接口的其他语言的实现网上已经有很多了,而VB的却很少见,因此,关于这个接口的意义及用法,我这里就不多说了,主要谈谈我在VB中实现这个接口时的碰到的一些问题。问题1、ICopyHook的声明
这个问题是没有什么小道道好走了,只能老老实实的做个idl文件,然后编译成类型库问题2、CopyCallBack方法的返回值问题
CopyCallBack应该返回IDYES,IDNO或者IDCANCEL(分别对应VB中的vbYes,vbNo和vbCancel),而在VB中,COM的方法只能返回HRESULT,否则就拜拜了。解决的办法是,函数地址替换。用自己函数的地址替换掉ICopyHook接口VTable中的CopyCallBack方法的地址。
这个工作又碰到另外一个问题,那就是如何得到ICopyHook接口的对象指针。我们知道用ObjPtr(Me)可以得到当前类的对象指针,当我们执行下面的语句时,好玩的事情就发生了:Dim oICopyHookA As ICopyHookA
Set oICopyHookA = Me这里的这个Set语句就相当于在当前的类上调用了QueryInterface(IID_ICopyHookA,....),于是乎,很轻松得,我们得到了想要的东西。接下去只要把自己的函数地址写到该写的地方就OK了。问题3、多线程问题
当我解决了上面两个问题后就改了文件夹个名字来验证效果,呵呵,挺好,没有什么问题。但是,当我复制、删除文件夹的时候,Explorer刷刷得就拜拜了。后来,经过一翻跟踪分析,结果发现原来问题出在多线程上。当windows进行文件夹操作的时候会使用多线程,而在每次ExitThread的时候vb运行库就会开始回收对象,因此,在第2次调用的时候,原先的地址就变成了不可访问,最终也就连累了Explorer。思考良久,然后又分析了shell32.dll,终于看到了一丝的曙光。在呼叫CopyHook对象之前,系统会生成一个包含所有CopyHook对象的链表。每次在执行前会通过判断这个链表首地址是否有效来决定是否生成对象及链表。所以,如果在调用完毕之后把链表给喀嚓掉,那么系统就会重新生成一个有效的对象及链表。呵呵,虽然这么做不是十分理想,但的确能解决这个不大不小的问题。基本问题就是上面那么多,还有很多其他的乱七八糟的问题,以后再讲,呵呵我提供的例子的用法是:
1、注册dll
2、双击 .reg文件,导入注册表。这个注册表文件里只包含了和文件夹相关的入口,如果要钩到打印机,可以添加下面这段
[HKEY_CLASSES_ROOT\Printers\Shellex\CopyHookHandlers\CopyMonitor]
@="{4F07BFB0-B9FC-4BF7-BA17-0343C27C8A9E}"

解决方案 »

  1.   

    supergreenbean你真是越来越厉害了,下一个mvp就是你了
      

  2.   

    恐怖阿,我6月18号发的帖子,到了今天才出现……我以为这帖子永远不会浮上来了呢……//楼主对于COM颇有研究,能否指点小弟一二,
    呵呵,我COM还差远了呢,只是看了点皮毛而已,不过切磋可以哦
    //哎~~豆子,考慮是否做個整合動作:)
    整合?咋整合阿?整合啥阿?
      

  3.   

    豆子的帖子,呵呵,顶,学习ing
      

  4.   

    最近我在看潘爱民的<Com原理与应用>以及DON BOX著的Essential COM (译名:COM 本质论)
    虽然有收获,但是觉得这都要用C++来实现,
    象楼主这样用VB来实现的书籍好象没有
    楼主能否推荐一二,最好有电子版,呵呵,穷人呀