Programming 版 (精华区)

发信人: lofe ()感激生活(), 信区: Programming
标  题: ATL接口映射宏详解--(10)
发信站: 哈工大紫丁香 (Sun Sep  3 08:17:24 2000), 转信

所有重要的宏我们都已经讲过了,剩下的都是些很简单的宏了.呵呵,还是把它们都罗列一
下,善始善终嘛.

十、COM_INTERFACE_ENTRY_IID(iid, x)
   #define COM_INTERFACE_ENTRY_IID(iid, x)\
        {&iid,\
        offsetofclass(x, _ComMapClass),\
        _ATL_SIMPLEMAPENTRY},

十一、COM_INTERFACE_ENTRY2_IID(iid, x, x2)
   #define COM_INTERFACE_ENTRY2_IID(iid, x, x2)\
        {&iid,\
        (DWORD)((x*)(x2*)((_ComMapClass*)8))-8,\
        _ATL_SIMPLEMAPENTRY},
从定义上看这两个宏与COM_INTERFACE_ENTRY()和COM_INTERFACE_ENTRY2()相比,都只是
多了一项"iid"。没有别的好处,只不过由用户明确指出接口IID,而不用系统根据接口
名字去转换了。

十二、COM_INTERFACE_ENTRY_FUNC( iid, dw, func )
   #define COM_INTERFACE_ENTRY_FUNC(iid, dw, func)\
        {&iid, \
        dw, \
        func},
   还记得AtlInternalQueryInterface()中的代码吗?如果在接口映射表中找到了我们
要找的接口,并且这个接口不是_ATL_SIMPLEENTRY型的,则执行宏定义中的指定的函数。
这个宏就给我们提供了自己编写处理函数的功能。这个函数必须是如下定义:
   HRESULT WINAPI func(void* pv, REFIID riid, LPVOID* ppv, DWORD dw);
当AtlInternalQueryInterface调用func时,会传进相关的信息。pv是类对象的指针,riid
是要查询的接口,ppv是要返回查询得到的接口指针,dw是在宏定义中指定的参数。
另外如果函数中不打算返回接口指针,则应把ppv赋为NULL,并返回S_FALSE或
E_NOINTERFACE。返回S_FALSE刚会继续查找下去,若返回E_NOINTERFACE则会终止查询。
若返回接口指针,则应返回S_OK.

十三、COM_INTERFACE_ENTRY_FUNC_BLIND(dw, func)
  #define COM_INTERFACE_ENTRY_FUNC_BLIND(dw, func)\
        {NULL, \
        dw, \
        func},
  至于_BLIND类型的特点可以看前面几节。

十四、COM_INTERFACE_ENTRY_NOINTERFACE(x)
  #define COM_INTERFACE_ENTRY_NOINTERFACE(x)\
        {&_ATL_IIDOF(x), \
        NULL, \
        _NoInterface},
  _NoInterface是CComObjectRootBase的成员函数,看看它的定义:
  static HRESULT WINAPI _NoInterface(...)
  {
        return E_NOINTERFACE;
  }
  原来它只是返回E_NOINTERFACE,并且将终止查询。
  哈哈,看来是不想让别人查到这个接口啊!!!

十五、COM_INTERFACE_ENTRY_BREAK(x)
  #define COM_INTERFACE_ENTRY_BREAK(x)\
        {&_ATL_IIDOF(x), \
        NULL, \
        _Break},
  _Break也是CComObjectRootBase的成员函数,看看它的定义:
  static HRESULT WINAPI _Break(...)
  {
        iid;
        _ATLDUMPIID(iid, _T("Break due to QI for interface "), S_OK);
        DebugBreak();
        return S_FALSE;
  }
  如果查到这个接口将调用DebugBreak(),并返回S_FALSE,继续查询下去。
  DebugBreak()是什么效果大家自己试试吧,一定很熟悉的,呵呵。

至此全部十五个接口映射宏我们都已经讲完了,唉,真是不容易,特别是前面几个宏跟
踪起来很麻烦。因为文本方式的限制,所以很多东西不容易表达清楚。有些叫法也是我
自己这么叫的,可能与别人的习惯不同。没办法,大家将就将就了,呵呵。


                ---------------全文完------------
--
才疏学浅,胡言乱语;不对之处,敬请指正。



                路漫漫兮,其修远。
                吾将上下而求索。
※ 修改:.haojs 于 Sep  3 08:15:01 修改本文.[FROM: bbs.hit.edu.cn]
--
※ 转寄:.武汉白云黄鹤站 bbs.whnet.edu.cn.[FROM: bbs.hit.edu.cn]

--
☆ 来源:.哈工大紫丁香 bbs.hit.edu.cn.[FROM: haojs.bbs@bbs.whnet.]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:3.143毫秒