COM_INTERFACE_ENTRY 宏

这些宏将对象的接口输入到其 COM 映射中,以便 QueryInterface 可以访问这些接口。 COM 映射中的入口顺序是在 QueryInterface 期间根据匹配的 IID 检查接口的顺序。

说明
COM_INTERFACE_ENTRY 将接口输入到 COM 接口映射。
COM_INTERFACE_ENTRY2 使用此宏可以消除两个继承分支的歧义。
COM_INTERFACE_ENTRY_IID 使用此宏可将接口输入到 COM 映射并指定其 IID。
COM_INTERFACE_ENTRY2_IID COM_INTERFACE_ENTRY2 相同,唯一的差别是你可以指定不同的 IID。
COM_INTERFACE_ENTRY_AGGREGATE 查询 iid 标识的接口时,COM_INTERFACE_ENTRY_AGGREGATE 将转发到 punk
COM_INTERFACE_ENTRY_AGGREGATE_BLIND COM_INTERFACE_ENTRY_AGGREGATE 相同,唯一的差别是查询任何 IID 会导致将查询转发到 punk
COM_INTERFACE_ENTRY_AUTOAGGREGATE COM_INTERFACE_ENTRY_AGGREGATE 相同,唯一的差别是,如果 punk 为 NULL,则此宏会自动创建 clsid 描述的聚合
COM_INTERFACE_ENTRY_AUTOAGGREGATE_BLIND COM_INTERFACE_ENTRY_AUTOAGGREGATE 相同,唯一的差别是,查询任何 IID 会导致将查询转发到 punk,如果 punk 为 NULL,则自动创建 clsid 描述的聚合
COM_INTERFACE_ENTRY_BREAK 查询指定的接口时导致程序调用 DebugBreak
COM_INTERFACE_ENTRY_CACHED_TEAR_OFF 保存每个实例的接口特定数据。
COM_INTERFACE_ENTRY_TEAR_OFF 公开分离式接口。
COM_INTERFACE_ENTRY_CHAIN 当处理到达 COM 映射中的此入口时处理基类的 COM 映射。
COM_INTERFACE_ENTRY_FUNC 一个用于挂接到 ATL 的 QueryInterface 逻辑的常规机制。
COM_INTERFACE_ENTRY_FUNC_BLIND COM_INTERFACE_ENTRY_FUNC 相同,唯一的差别是,查询任何 IID 会导致调用 func
COM_INTERFACE_ENTRY_NOINTERFACE 返回 E_NOINTERFACE 并在查询指定的接口时终止 COM 映射处理。

要求

标头:atlcom.h

COM_INTERFACE_ENTRY

将接口输入到 COM 接口映射。

语法

COM_INTERFACE_ENTRY( x )

参数

x
[in] 类对象直接派生自的接口的名称。

注解

通常,这是最常用的入口类型。

示例

BEGIN_COM_MAP(CThisExample)
   COM_INTERFACE_ENTRY(IThisExample)
   COM_INTERFACE_ENTRY(IDispatch)
   COM_INTERFACE_ENTRY(ISupportErrorInfo)
END_COM_MAP()

要求

标头:atlcom.h

COM_INTERFACE_ENTRY2

使用此宏可以消除两个继承分支的歧义。

COM_INTERFACE_ENTRY2(x, x2)

参数

x
[in] 要从对象公开的接口的名称。

x2
[in] 从中公开 x 的继承分支的名称

注解

例如,如果从两个双重接口派生类对象,请使用 COM_INTERFACE_ENTRY2 公开 IDispatch,因为可以从任一接口获取 IDispatch

示例

class ATL_NO_VTABLE CEntry2Example :
   public CEntry2ExampleBase, // CEntry2ExampleBase derives from IDispatch
   public IDispatchImpl<IEntry2Example, &IID_IEntry2Example, &LIBID_NVC_ATL_WindowingLib, /*wMajor =*/ 1, /*wMinor =*/ 0>,
   public CComCoClass<CEntry2Example, &CLSID_Entry2Example>
{
public:
   CEntry2Example()
   {
   }

BEGIN_COM_MAP(CEntry2Example)
   COM_INTERFACE_ENTRY(IEntry2Example)
   COM_INTERFACE_ENTRY2(IDispatch, IEntry2Example)
END_COM_MAP()
};

COM_INTERFACE_ENTRY_IID

使用此宏可将接口输入到 COM 映射并指定其 IID。

COM_INTERFACE_ENTRY_IID(iid, x)

参数

iid
[in] 公开的接口的 GUID。

x
[in] 其 vtable 将公开为 iid 标识的接口的类的名称

示例

BEGIN_COM_MAP(CExample)
   COM_INTERFACE_ENTRY(IExample)
   COM_INTERFACE_ENTRY_IID(IID_IDispatch, CExampleDispatch)
   COM_INTERFACE_ENTRY(IExampleBase)
   COM_INTERFACE_ENTRY(ISupportErrorInfo)
END_COM_MAP()

COM_INTERFACE_ENTRY2_IID

COM_INTERFACE_ENTRY2 相同,唯一的差别是你可以指定不同的 IID。

COM_INTERFACE_ENTRY2_IID(iid, x, x2)

参数

iid
[in] 为接口指定的 GUID。

x
[in] 类对象直接派生自的接口的名称。

x2
[in] 类对象直接派生自的另一个接口的名称。

COM_INTERFACE_ENTRY_AGGREGATE

查询 iid 标识的接口时,COM_INTERFACE_ENTRY_AGGREGATE 将转发到 punk

COM_INTERFACE_ENTRY_AGGREGATE(iid, punk)

参数

iid
[in] 查询的接口的 GUID。

punk
[in] IUnknown 指针的名称。

备注

假设 punk 参数指向聚合的内部未知成员或 NULL,在这种情况下,将忽略该入口。 通常,你会对 FinalConstruct 中的聚合运行 CoCreate

示例

BEGIN_COM_MAP(COuter1)
   COM_INTERFACE_ENTRY_AGGREGATE(__uuidof(IAgg), m_punkAgg)
END_COM_MAP()

COM_INTERFACE_ENTRY_AGGREGATE_BLIND

COM_INTERFACE_ENTRY_AGGREGATE 相同,唯一的差别是查询任何 IID 会导致将查询转发到 punk

COM_INTERFACE_ENTRY_AGGREGATE_BLIND(punk)

参数

punk
[in] IUnknown 指针的名称。

备注

如果接口查询失败,则继续处理 COM 映射。

示例

BEGIN_COM_MAP(COuter2)
   COM_INTERFACE_ENTRY_AGGREGATE_BLIND(m_punkAggBlind)
END_COM_MAP()

COM_INTERFACE_ENTRY_AUTOAGGREGATE

COM_INTERFACE_ENTRY_AGGREGATE 相同,唯一的差别是,如果 punk 为 NULL,则此宏会自动创建 clsid 描述的聚合

COM_INTERFACE_ENTRY_AUTOAGGREGATE(iid, punk, clsid)

参数

iid
[in] 查询的接口的 GUID。

punk
[in] IUnknown 指针的名称。 必须是包含 COM 映射的类的成员。

clsid
[in] punk 为 NULL 时要创建的聚合的标识符

备注

示例

BEGIN_COM_MAP(COuter3)
   COM_INTERFACE_ENTRY_AUTOAGGREGATE(__uuidof(IAutoAgg), m_punkAutoAgg, CLSID_CAutoAgg)
END_COM_MAP()

COM_INTERFACE_ENTRY_AUTOAGGREGATE_BLIND

COM_INTERFACE_ENTRY_AUTOAGGREGATE 相同,唯一的差别是,查询任何 IID 会导致将查询转发到 punk,如果 punk 为 NULL,则自动创建 clsid 描述的聚合

COM_INTERFACE_ENTRY_AUTOAGGREGATE_BLIND(punk, clsid)

参数

punk
[in] IUnknown 指针的名称。 必须是包含 COM 映射的类的成员。

clsid
[in] punk 为 NULL 时要创建的聚合的标识符

备注

如果接口查询失败,则继续处理 COM 映射。

示例

BEGIN_COM_MAP(COuter4)
   COM_INTERFACE_ENTRY_AUTOAGGREGATE_BLIND(m_punkAutoAggB, CLSID_CAutoAggB)
END_COM_MAP()

COM_INTERFACE_ENTRY_BREAK

查询指定的接口时导致程序调用 DebugBreak

COM_INTERFACE_ENTRY_BREAK(x)

参数

x
[in] 用于构造接口标识符的文本。

注解

通过将 x 追加到 IID_ 来构造接口 IID。 例如,如果 x 为 IPersistStorage,则 IID 为 IID_IPersistStorage

COM_INTERFACE_ENTRY_CACHED_TEAR_OFF

保存每个实例的接口特定数据。

COM_INTERFACE_ENTRY_CACHED_TEAR_OFF(iid, x, punk)

参数

iid
[in] 分离式接口的 GUID。

x
[in] 实现接口的类的名称。

punk
[in] IUnknown 指针的名称。 必须是包含 COM 映射的类的成员。 应在类对象的构造函数中初始化为 NULL。

备注

如果未使用接口,则这会降低对象的整体实例大小。

示例

BEGIN_COM_MAP(COuter)
   COM_INTERFACE_ENTRY(IOuter)
   COM_INTERFACE_ENTRY_CACHED_TEAR_OFF(IID_ITearOff, CTearOff, punkTearOff)
END_COM_MAP()

COM_INTERFACE_ENTRY_TEAR_OFF

公开分离式接口。

COM_INTERFACE_ENTRY_TEAR_OFF(iid, x)

参数

iid
[in] 分离式接口的 GUID。

x
[in] 实现接口的类的名称。

备注

分离式接口将实现为一个单独的对象,每次查询该对象所代表的接口时,都会实例化该对象。 通常,如果极少使用该接口,则可以将其生成为分离式接口,因为这会在主对象的每个实例中保存一个 vtable 指针。 当分离的引用计数变为零时,将删除该接口。 实现分离式接口的类应派生自 CComTearOffObjectBase 并具有自身的 COM 映射。

示例

BEGIN_COM_MAP(CBeeper)
   COM_INTERFACE_ENTRY(IBeeper)
   COM_INTERFACE_ENTRY(IDispatch)
   COM_INTERFACE_ENTRY_TEAR_OFF(IID_ISupportErrorInfo, CBeeper2)
END_COM_MAP()

COM_INTERFACE_ENTRY_CHAIN

当处理到达 COM 映射中的此入口时处理基类的 COM 映射。

COM_INTERFACE_ENTRY_CHAIN(classname)

参数

classname
[in] 当前对象的基类。

备注

例如,在以下代码中:

BEGIN_COM_MAP(COuterObject)
   COM_INTERFACE_ENTRY2(IDispatch, IOuterObject)
   COM_INTERFACE_ENTRY_CHAIN(CBase)
END_COM_MAP()

请注意,COM 映射中的第一个入口必须是包含 COM 映射的对象上的接口。 因此,不能使用 COM_INTERFACE_ENTRY_CHAIN 作为 COM 映射入口的开头,这会导致在对象的 COM 映射中出现 COM_INTERFACE_ENTRY_CHAIN(COtherObject) 的位置搜索不同对象的 COM 映射。 如果你想要先搜索另一个对象的 COM 映射,请将 IUnknown 的接口入口添加到 COM 映射,然后链接另一个对象的 COM 映射。 例如:

BEGIN_COM_MAP(CThisObject)
   COM_INTERFACE_ENTRY(IUnknown)
   COM_INTERFACE_ENTRY_CHAIN(CBase)
END_COM_MAP()

COM_INTERFACE_ENTRY_FUNC

一个用于挂接到 ATL 的 QueryInterface 逻辑的常规机制。

COM_INTERFACE_ENTRY_FUNC(iid, dw, func)

参数

iid
[in] 公开的接口的 GUID。

dw
[in] 传递给 func 的参数

func
[in] 将返回 iid 的函数指针

备注

如果 iid 与查询的接口的 IID 匹配,则调用 func 指定的函数。 函数的声明应该是:

HRESULT WINAPI func(void* pv, REFIID riid, LPVOID* ppv, DWORD_PTR dw);

调用你的函数时,pv 指向你的类对象。 riid 参数引用要查询的接口,ppv 是指向位置的指针(函数应在此位置存储指向接口的指针),dw 是在入口中指定的参数。 如果函数选择不返回接口,则应将 * ppv 设置为 NULL 并返回 E_NOINTERFACE 或 S_FALSE。 如果返回 E_NOINTERFACE,则 COM 映射处理将会终止。 如果返回 S_FALSE,则 COM 映射处理将继续,即使未返回接口指针。 如果函数返回接口指针,则应返回 S_OK。

COM_INTERFACE_ENTRY_FUNC_BLIND

COM_INTERFACE_ENTRY_FUNC 相同,唯一的差别是,查询任何 IID 会导致调用 func

COM_INTERFACE_ENTRY_FUNC_BLIND(dw, func)

参数

dw
[in] 传递给 func 的参数

func
[in] 处理 COM 映射中的此入口时调用的函数。

注解

发生任何失败都会导致在 COM 映射上继续处理。 如果函数返回接口指针,则应返回 S_OK。

COM_INTERFACE_ENTRY_NOINTERFACE

返回 E_NOINTERFACE 并在查询指定的接口时终止 COM 映射处理。

COM_INTERFACE_ENTRY_NOINTERFACE(x)

参数

x
[in] 用于构造接口标识符的文本。

备注

可以使用此宏来防止在特定情况下使用接口。 例如,可以在 COM 映射中紧靠在 COM_INTERFACE_ENTRY_AGGREGATE_BLIND 的前面插入此宏,以防止将接口查询转发到聚合的内部未知成员。

通过将 x 追加到 IID_ 来构造接口 IID。 例如,如果 x 为 IPersistStorage,则 IID 为 IID_IPersistStorage