这个问题一直困扰着我。
拿Shell Interface IContextMenu 来说,在VC6中COM映射宏是这么写的:
BEGIN_COM_MAP(CCountLines)
...
COM_INTERFACE_ENTRY(IContextMenu)
...
END_COM_MAP()COM类,或者叫ATL Object 类是这样继承的:
class ATL_NO_VTABLE CCountLines : 
...
public IContextMenu在VC6中编译/连接都没有问题。
而在VC2003/2005中编译总会提示错误,错误定位在COM映射宏中的 COM_INTERFACE_ENTRY(IContextMenu)
提示信息为:
error C2787: 'IContextMenu' : no GUID has been associated with this object
error C2440: 'initializing' : cannot convert from 'DWORD_PTR' to 'const IID *'
error C2440: 'initializing' : cannot convert from 'ATL::_ATL_CREATORARGFUNC (__stdcall *)' to 'DWORD_PTR'我试过用其它映射宏来代替 COM_INTERFACE_ENTRY,比如:
COM_INTERFACE_ENTRY_IID()
这样,编译是通过了,可是程序没有效果,也就是说程序不会走到实现 IContextMenu 的接口函数中。这个问题对于很多 Shell Interface 都遇见过,比如还有 IShellExecuteHook。还有,VC2003/2005中的 实现COM 类接口的 Wizard 中,选择继承于 shell32.dll 中接口类时,怎么没有 IContextMenu 、IShellExecuteHook 这些类。如果能找到VC2003/2005正确的实现COM 类接口的 Wizard,看看VC是怎么自动生成代码的,也许以上问题就可以解决。

解决方案 »

  1.   

    There are two <comdef.h> header files in VC.NET, one in Vc7/include and the other in Vc7/PlatformSDK/include. The former splits off the smart pointer typedefs into comdefsp.h, and it doesn't include IContextMenu. The latter does. You can try to #include the PlatformSDK header directly, change your INCLUDE path order, or supply the missing typedef yourself, e.g. 
    struct __declspec(uuid("000214e4-0000-0000-c000-000000000046"))
    IContextMenu; _COM_SMARTPTR_TYPEDEF(IContextMenu, __uuidof(IContextMenu));
      

  2.   

    感谢jiangsheng(蒋晟.Net[MVP])
    按照你的第2种方法,即自己定义接口的GUID,我在VC2005下调试通过了,这里还有些细节问题和你交流一下:
    1、怎样找到Interface的GUID?
    我在注册表 HKCR\Interface\ 下可以找到形式为
    {aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee}的键,如果其下有默认项="Interface",则说明这个
    键就是该Interface的GUID。
    有没有其它方法?
    (1) VC6\common\Tools 下有个OLE/COM Object Viewer 很方便,但在VC2005下就没找到这个工具(VC2003也有这个工具,我的VC2005是Team Edition,可能是我没有默认安装的原因)
    (2) PlatformSDK\include\comdef.h 中应该也有GUID的定义吧?2、我的PlatformSDK\include 下没有comdef.h 文件,这也可能和我没有默认安装VC2005有关,在Microsoft的网站上有下载PlatformSDK的地址,那个上面应该包括comdef.h 吧?3、我按照你的第2种方法,调试通过了,但为什么还要#include Vc7\include 下的那个<comdef.h>,如果不 #include 的话,编译时会出错,其中有个错误叫:
    error C2059: syntax error : '__uuidof'
    我想是不是在 Vc7\include\comdef.h 中有符号__uuidof的定义。4、你提到的smart pointer是什么含义,可以在哪里查到资料?
     
    就说这么多了,再次谢谢你的帮助,至少一直困扰着我的这个问题终于被你解决了。
      

  3.   

    差点忘了个重要的问题,VC2005下的ATL Object Implement Interface wizard(就是右键点击ATL Object 类出现的那个)下,选择哪一个是对应实现shell extension的type lib,我找到的最接近的是Microsoft Shell Controls and Automation<1.0>(shell32.dll)但是里面的接口没有
    IContextMenu、IShellExecuteHook、IShellExtInit 这些,而是一大堆 IShellDispatch。
    我很想看看wizard是怎样生成代码的!
      

  4.   

    #include <comdef.h>
    #include <initguid.h>
    #include <shlobj.h>
      

  5.   

    自己回答一些问题:
    1、VC2005中的 OLE/Obj Viewer 在Common7\Tools\Bin下而且默认没有集成在IDE中。
    Platform SDK中的comdef.h中确实有Shell Extension Interface的GUID定义。
    2、从微软网站上下了个Platform SDK for Windows Server 2003 R2,其中确实有comdef.h,在VC中重设一下include路径就可以了。
    3、__uuidof并非是comdef.h或是其它文件中预定义的符号,它是C++ 运算符,在MSDN中可以查到。
    另外,生成Shell Extension Implemented Class的Wizard方法还是没找到。
    Over.