ATL库组件

ATL库的使用

    1 ATL(Active Template Library)库

是一个模板库,封装了COM SDK相关细节,以及接口和组件实现的相关的机制

    2 ATL接口的相关类

    内部封装了IUnknown接口
2.1 CComObjectRootBase模板类
封装了引用计数,以及内部接口函数等相关的内部调用函数
2.2 CComObjectRootEx
父类是CComObjectRootBase,是一个模板类,封装了对引用计 数的增加和减少函数
2.3 CComSingleThreadModel
实现了对引用计数的++和--操作(用于单线程)
2.4 CComMultiThreadModel
实现了对引用计数的原子锁的++和——操作(用于多线程)
2.5 CComObject 模板类
实现了组件、IUnknown接口的函数,提供了组件创建函数

CComSingleThreadModel和CComMultiThreadModel作为模板参数构造CComObjectRootEx对象

    3 使用ATL编写组件

    #include "atlbase.h"   //必须在前面
    #include "atlcom.h"
3.1 IDL定义接口  必须import "objidl.idl";
3.2 增加ATL库的头文件
#include "atlbase.h"
#include "atlcom.h"
3.3 添加组件的实现类,并且继承CComObjectRootEx和IMath接口
3.4 添加接口查询宏
BEGIN_COM_MAP(CMath)
COM_INTERFACE_ENTRY(IMath)
END_COM_MAP()
3.5 添加和实现IMath接口的函数
IUnknown* pIUnknown = NULL;
CComObject* pMath = NULL;
CComObject::CreateInstance(&pMath);
pMath->QueryInterface(IID_IUnknown, (LPVOID*)&pIUnknown);
return pIUnknown;
3.3 导出接口

    4 代码过程

4.1 CComObject;实际是基于组件CMath派生子CComObject,
例如 class CComObject:public CMath
在CComObject类当中实现了IUnknown接口的3个函数,
4.2 在CComObject中AddRdf和Release函数分别调用CMath的父类
CComObjectRootEx提供的InternalAddRef/InternalRelease实现引用计 数的加减
4.3 在InternalAddRef/InternalRelease中会调用CComObjectRootEx的 模板参数所提供的加减函数完成引用计数的加减
模板参数
CComSingleThreadModel
CComMultiThreadModel
例如    CComObjectRootEx
{
   InternalAddRef()
   {
CComMultiThreadModel::InCreme
   }
}
4.4 在CComObject中QueryInterace函数会调用CMath::_InternalQueryInterace,

4.5 CMath::_InternalQueryInterace是通过BEGIN_COM_MAP/END_COM_MAP添加,并且内部调用了父类CComObjectRootBase提供的InternalQueryInterace函数

代码示例:

comobj.idl

import "oaidl.idl";
import "ocidl.idl";
import "objidl.idl";


[
	object,
	uuid(033F167D-6FFD-47EC-A450-34A3E45E55CE)
]
interface IMath :IUnknown
{
	HRESULT Add(long nAdd1, long nAdd2, long* pnAdd) = 0;
	HRESULT Sub(long nSub1, long nSub2, long* pnSub) = 0;
};
[
	uuid(77B18693-AE5A-409D-9C01-5FEAE163153D)
]
coclass ComObj
{
	interface IMath;
};

Math.h

#pragma once
//ATL库头文件
#include "atlbase.h"
#include "atlcom.h"
#include "comobj_h.h"
extern const CLSID CLSID_Math;
class CMath :public CComObjectRootEx,
	public IMath,
	public CComCoClass
{
public:
	CMath();
	~CMath();
	
public:
	//用于接口查询等相关信息的宏
	BEGIN_COM_MAP(CMath)
		COM_INTERFACE_ENTRY(IMath)
	END_COM_MAP()
	//IMath接口的函数
public:
	STDMETHOD(Add)(long nAdd1, long nAdd2, long* pnAdd);
	STDMETHOD(Sub)(long nSub1, long nSub2, long* pnSub);
};

Math.cpp

#include "stdafx.h"
#include "Math.h"


CMath::CMath()
{
}


CMath::~CMath()
{
}

STDMETHODIMP CMath::Add(long nAdd1,
	long nAdd2,
	long* pnAdd)
{
	*pnAdd = nAdd1 + nAdd2;
	return S_OK;
}
STDMETHODIMP CMath::Sub(long nSub1,
	long nSub2,
	long* pnSub)
{
	*pnSub = nSub1 - nSub2;
	return S_OK;
}

组件创建函数

IUnknown* MyCreateInstance()
{
	IUnknown* piUnknown = NULL;
	//定义组件对象的指针
	CComObject* pMath = NULL;
	//创建组件对象
	CComObject::CreateInstance(&pMath);
	//获取IUnknown接口
	pMath->QueryInterface(IID_IUnknown,
		(LPVOID*)&piUnknown);

	return piUnknown;
}



你可能感兴趣的:(ActiveX相关)