描述:
这个问题一直困扰着我。
拿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));