COM开发
潘爱民
http://www.icst.pku.edu.cn/compcourse
内容
? Win32 SDK和MFC介绍
?MFC对COM的支持
? 用MFC开发COM组件
?ATL对COM的支持
? 用ATL开发COM组件
? 布置作业
Win32 SDK: Windows程序结构
? 入口函数WinMain
? 应用初始化
? 主窗口的创建及显示
? 消息分发循环
? 程序结束处理
Win32 SDK对COM的支持
? Win32 SDK包括COM库函数的支持
Win32 SDK提供的一些头文件的说明
头文件 说明
Unknwn.h 标准接口IUnknown和IClassFactory的IID及接口成员函数的定义。
Wtypes.h 包含了COM使用的数据结构的说明。
Objidl.h
所有标准接口的定义,既可用于C语言风格的定义,也可用于C++语言风格
的定义。
Comdef.h 所有标准接口以及COM和OLE内部对象的CLSID。
ObjBase.h 所有的COM API函数的说明。
Ole2.h 所有经过封装的OLE辅助函数。
利用宏描 接口
DECLARE_INTERFACE_(IClassFactory, IUnknown)
{
STDMETHOD(QueryInterface) (THIS_
REFIID riid,
LPVOID FAR* ppvObj) PURE;
STDMETHOD_(ULONG,AddRef) (THIS) PURE;
STDMETHOD_(ULONG,Release) (THIS) PURE;
STDMETHOD(CreateInstance) (THIS_
LPUNKNOWN pUnkOuter,
REFIID riid,
LPVOID FAR* ppvObject) PURE;
STDMETHOD(LockServer)(THIS_
BOOL fLock) PURE;
};
VC提供的用于描 接口的宏
COM 接口有 的一些宏的说明
宏说明
DECLARE_INTERFACE(iface) 明接口iface, 的接口 。
DECLARE_INTERFACE_( iface, baseiface) 明接口iface, 接口baseiface 。
STDMETHOD(method) 明接口成员函数method,函数 HRESULT。
STDMETHOD_(type,method) 明接口成员函数method,函数 type。
MFC
? 应用
–AfxGetApp
– CWinApp::InitInstance
– CWinApp::ExitInstance
– CWinApp::OnIdle
– CWinApp::Run
– CWnd *m_pMainWnd
? 窗口
– AfxGetMainWnd
MFC的消息处理
——消息
? CWnd 定义 入 明:
DECLARE_MESSAGE_MAP()
? 的 文件 入 和 的定义:
BEGIN_MESSAGE_MAP(theClass, baseClass)
......
END_MESSAGE_MAP
消息 示
BEGIN_MESSAGE_MAP(theClass, baseClass)
//{{AFX_MSG_MAP(theClass)
ON_WM_SETFOCUS()
ON_WM_CREATE()
ON_WM_DESTROY()
ON_WM_CLOSE()
ON_WM_SIZE()
ON_MESSAGE(WM_COMMANDHELP, OnCommandHelp)
ON_MESSAGE(WM_HELPHITTEST, OnHelpHitTest)
ON_UPDATE_COMMAND_UI(ID_VIEW_STATUS_BAR,
OnUpdateControlBarMenu)
ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF,
OnToolTipText)
//}}AFX_MSG_MAP
END_MESSAGE_MAP
MFC应用
? 应用:MDI应用 SDI应用 于对 ?程序
?DLL应用:¢£?接MFC库的¥ DLL ?£?接
MFC库的¥ DLL MFC§currency1DLL
? '应用:
– 支持OLE“???包容fi的SDI应用
– 支持OLE“???包容fi的MDI应用
– 支持fl?化(Automation)“?的SDI??MDI程序
– ActiveX 应用(OCX应用)
MFC库结构
CObject
CCmdTarget
CWnd
应用 结构
窗口支持
– 文件“?
文?
??窗口
·
??
对 ? ?
?”?…环‰
支持
Windows 接?
?”对象
`
ODBC支持
DAO支持
′?
:
Internet支持
fl?化
?ˉ?˙对象支持
¨`
结构
支持
?? ?
用于′?的
数组
?
Internet
MFC对COM应用的支持
用ˇ COM接口
class CDictionary
{
…… //构—函数和 构函数
HRESULT __stdcall QueryInterface(REFIID iid, void** ppvObj);
ULONG __stdcall AddRef();
ULONG __stdcall Release();
class XDictionaryObj : public IDictionary {
public:
CDictionary * m_pParent;
virtual HRESULT __stdcall QueryInterface(REFIID iid, void** ppvObj);
virtual ULONG __stdcall AddRef();
virtual ULONG __stdcall Release();
virtual BOOL __stdcall Initialize();
…...
virtual void __stdcall FreeLibrary();
} m_dictionaryObj;
用ˇ COM接口( 一)
class XSpellCheckObj : public ISpellCheck {
public:
CDictionary * m_pParent;
virtual HRESULT __stdcall QueryInterface(REFIID iid, void** ppvObj);
virtual ULONG __stdcall AddRef();
virtual ULONG __stdcall Release();
virtual BOOL __stdcall CheckWord (String word, String *);
} m_spellCheckObj;
private :
struct DictWord *m_pData;
char *m_DictFilename[128];
int m_Ref ;
int m_nWordNumber, m_nStructNumber;
};
用ˇ COM接口( )
CDictionary::CDictionary()
{
....... // Initializtion
m_dictionaryObj. m_pParent = this;
m_spellCheckObj. m_pParent = this;
}
用ˇ COM接口( )
HRESULT CDictionary::QueryInterface(const IID& iid, void **ppvObj)
{
if (iid == IID_IUnknown || iid == IID_Dictionary) {
*ppvObj = &m_dictionaryObj;
AddRef();
return S_OK;
} else if (iid == IID_SpellCheck) {
*ppvObj = &m_spellCheckObj;
AddRef();
return S_OK;
}
*ppv = NULL;
return E_NOINTERFACE ;
}
用ˇ COM接口( )
ULONG CDictionary::XDictionaryObj::QueryInterface(const IID& iid,
void **ppvObj)
{
return m_pParent->QueryInterface(iid, ppvObj);
}
ULONG CDictionary::XDictionaryObj::AddRef()
{
return m_pParent->AddRef();
}
ULONG CDictionary::XDictionaryObj::Release ()
{
return m_pParent->Release ();
}
“用ˇ COM接口” 理
m_pData
m_DictFilename[128]
m_Ref
m_nWordNumber
m_nStructNumber
QueryInterface
AddRef
Release
…….
m_dictionaryObj
m_spellCheckObj
QueryInterface
AddRef
Release
……
QueryInterface
AddRef
Release
……
Vtable for IDictionary
Vtable for ISpellCheck
CDictionary
vptr
vptr
CDictionary的 函数
MFC:接口
? CCmdTarget
? CCmdTarget::m_dwRef 用 数
? 接口 消息
? 接口 : 了CCmdTarget 一?ˇ 的接
口ID以及接口vtable thisa 的 ??
? offsetof宏:成员 的 ?
DECLARE_INTERFACE_MAP
#define DECLARE_INTERFACE_MAP() private: static const AFX_INTERFACEMAP_ENTRY _interfaceEntries[]; protected: static AFX_DATA const AFX_INTERFACEMAP interfaceMap; static const AFX_INTERFACEMAP* PASCAL _GetBaseInterfaceMap(); virtual const AFX_INTERFACEMAP* GetInterfaceMap() const; struct AFX_INTERFACEMAP_ENTRY
{
const void* piid;
size_t nOffset;
};
struct AFX_INTERFACEMAP
{
#ifdef _AFXDLL
const AFX_INTERFACEMAP* (PASCAL
pfnGetBaseMap)();
#else
const AFX_INTERFACEMAP* pBaseMap;
#endif
const AFX_INTERFACEMAP_ENTRY* pEntry;
};
接口 定义
BEGIN_INTERFACE_MAP(CDictionary, CCmdTarget)
INTERFACE_PART(CDictionary, IID_IDictionary, Dictionary)
INTERFACE_PART(CDictionary, IID_ISpellCheck, SpellCheck)
END_INTERFACE_MAP()
接口 的宏定义
#define BEGIN_INTERFACE_MAP(theClass, theBase) const AFX_INTERFACEMAP* PASCAL theClass::_GetBaseInterfaceMap() { return &theBase::interfaceMap; } const AFX_INTERFACEMAP* theClass::GetInterfaceMap() const { return &theClass::interfaceMap; } AFX_COMDAT const AFX_DATADEF AFX_INTERFACEMAP theClass::interfaceMap = { &theClass::_GetBaseInterfaceMap, &theClass::_interfaceEntries[0], }; AFX_COMDAT const AFX_DATADEF
AFX_INTERFACEMAP_ENTRY theClass::_interfaceEntries[] = { #define INTERFACE_PART(theClass, iid, localClass) { &iid, offsetof(theClass, m_x##localClass) }, #define END_INTERFACE_MAP() { NULL, (size_t)-1 } }; MFC?o的? 对象 定义
class CDictionary : public CCmdTarget
{
DECLARE_DYNCREATE(CDictionary)
CDictionary(); // protected constructor used by dynamic creation
DECLARE_INTERFACE_MAP()
......
// IDictionary
BEGIN_INTERFACE_PART(Dictionary, IDictionary)
INIT_INTERFACE_PART(CDictionary, Dictionary)
STDMETHOD_(BOOL, Initialize)();
……
STDMETHOD_(void, FreeLibrary)();
END_INTERFACE_PART_STATIC(Dictionary)
// ISpellCheck
BEGIN_INTERFACE_PART(SpellCheck, ISpellCheck)
INIT_INTERFACE_PART(CDictionary, SpellCheck)
STDMETHOD_(BOOL, CheckWord)(LPOLESTR, LPOLESTR *);
END_INTERFACE_PART_STATIC(SpellCheck)
};
MFC?o的? 对象
STDMETHODIMP_(ULONG) CDictionary::XDictionary::AddRef()
{
METHOD_PROLOGUE_EX_(CDictionary, Dictionary)
return pThis->ExternalAddRef();
}
? METHOD_PROLOGUE_EX_宏定义:
#define METHOD_PROLOGUE_EX(theClass, localClass) theClass* pThis = ((theClass*)((BYTE*)this - m_nOffset)); AFX_MANAGE_STATE(pThis->m_pModuleState) pThis; // avoid warning from compiler CCmdTarget IUnknown
public:
// data used when CCmdTarget is made OLE aware
long m_dwRef;
LPUNKNOWN m_pOuterUnknown; // external controlling unknown if != NULL
DWORD m_xInnerUnknown; // place-holder for inner controlling unknown
public:
// advanced operations
void EnableAggregation(); // call to enable aggregation
void ExternalDisconnect(); // forcibly disconnect
LPUNKNOWN GetControllingUnknown();
// get controlling IUnknown for aggregate creation
CCmdTarget IUnknown( )
public:
// these versions do not delegate to m_pOuterUnknown
DWORD InternalQueryInterface(const void*, LPVOID* ppvObj);
DWORD InternalAddRef();
DWORD InternalRelease();
// these versions delegate to m_pOuterUnknown
DWORD ExternalQueryInterface(const void*, LPVOID* ppvObj);
DWORD ExternalAddRef();
DWORD ExternalRelease();
CCmdTarget QueryInterface
DWORD CCmdTarget::InternalQueryInterface(const void* iid, LPVOID* ppvObj)
{
// check local interfaces
if ((*ppvObj = GetInterface(iid)) != NULL) {
// interface was found -- add a reference
ExternalAddRef();
return S_OK;
}
// check aggregates
if ((*ppvObj = QueryAggregates(iid)) != NULL)
return S_OK;
// interface ID not found, fail the call
return (DWORD)E_NOINTERFACE;
}
CCmdTarget ExternalXXX成员
DWORD CCmdTarget::ExternalAddRef()
{
// delegate to controlling unknown if aggregated
if (m_pOuterUnknown != NULL)
return m_pOuterUnknown->AddRef();
return InternalAddRef();
}
DWORD CCmdTarget::ExternalRelease() // …...
// QueryInterface that is exported to normal clients
DWORD CCmdTarget::ExternalQueryInterface(const void* iid, LPVOID* ppvObj)
{
// delegate to controlling unknown if aggregated
if (m_pOuterUnknown != NULL)
return m_pOuterUnknown->QueryInterface(*(IID*)iid, ppvObj);
return InternalQueryInterface(iid, ppvObj);
}
ˇ 内部 IUnknown的成员函数
STDMETHODIMP_(ULONG) CDictionary::XDictionary::QueryInterface (
const void* iid, LPVOID* ppvObj)
{
METHOD_PROLOGUE_EX_(CDictionary, Dictionary)
return pThis->ExternalQueryInterface (iid, ppvObj);
}
COM 函数和
? AppWizard “Automation” ??
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
return AfxDllGetClassObject(rclsid, riid, ppv);
}
STDAPI DllCanUnloadNow(void)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
return AfxDllCanUnloadNow();
}
// by exporting DllRegisterServer, you can use regsvr.exe
STDAPI DllRegisterServer(void)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
COleObjectFactory::UpdateRegistryAll();
return S_OK;
}
COleObjectFactory
? 用的 , 了IClassFactory2接口
? COleObjectFactory的主 息?对象的CLSID和对象的
息。
? 利用MFC的?£对象创建 :
– DECLARE_DYNCREATE
? 对象 的支持:
– DECLARE_OLECREATE(...),定义??
#define DECLARE_OLECREATE(class_name) public: static AFX_DATA COleObjectFactory factory; static AFX_DATA const GUID guid; MFC 组件对象的创建支持
? DECLARE_OLECREATE(...)
? IMPLEMENT_OLECREATE
#define IMPLEMENT_OLECREATE(class_name, external_name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) AFX_DATADEF COleObjectFactory class_name::factory(class_name::guid, RUNTIME_CLASS(class_name), FALSE, _T(external_name)); AFX_COMDAT const AFX_DATADEF GUID class_name::guid = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }; ? ?£结构:AFX_MODULE_STATE,?了一些 o的 息, 包
括一? 。
? DllGetClassObject- AfxDllGetClassObject-
AfxGetModuleState进一?得到
? 对象的构—函数和 构函数维护
用MFC开发COM应用
? 利用AppWizard创建COM程序工程??
? 利用ClassWizard添 COM对象
AppWizard创建COM工程(一)
AppWizard创建COM工程( )
AppWizard创建COM工程( )
BOOL CDictCompApp::InitInstance()
{
// Register all OLE server (factories) as running. This enables the
// OLE libraries to create objects from other applications.
COleObjectFactory::RegisterAll();
return TRUE;
}
ClassWizard添 COM对象 (一)
ClassWizard添 COM对象 ( )
CDictionaryObj 明 入接口定义
BEGIN_INTERFACE_PART(Dictionary, IDictionary)
INIT_INTERFACE_PART(CDictionary, Dictionary)
STDMETHOD_(BOOL, Initialize)();
STDMETHOD_(BOOL, LoadLibrary)(LPOLESTR);
STDMETHOD_(BOOL, InsertWord)(LPOLESTR, LPOLESTR);
STDMETHOD_(void, DeleteWord)( LPOLESTR);
STDMETHOD_(BOOL, LookupWord)(LPOLESTR, LPOLESTR *);
STDMETHOD_(BOOL, RestoreLibrary)(LPOLESTR);
STDMETHOD_(void, FreeLibrary)();
END_INTERFACE_PART_STATIC(Dictionary)
// ISpellCheck
BEGIN_INTERFACE_PART(SpellCheck, ISpellCheck)
INIT_INTERFACE_PART(CDictionary, SpellCheck)
STDMETHOD_(BOOL, CheckWord)(LPOLESTR, LPOLESTR *);
END_INTERFACE_PART_STATIC(SpellCheck)
DECLARE_INTERFACE_MAP()
CDictionaryObj 文件
入相应的定义
extern "C" const IID IID_Dictionary =
{ 0x54bf6568, 0x1007, 0x11d1,
{ 0xb0, 0xaa, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00} } ;
extern "C" const IID IID_SpellCheck =
{ 0x54bf6569, 0x1007, 0x11d1,
{ 0xb0, 0xaa, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00} } ;
BEGIN_INTERFACE_MAP(CDictionaryObj, CCmdTarget)
INTERFACE_PART(CDictionaryObj, IID_IDictionary, Dictionary)
INTERFACE_PART(CDictionaryObj, IID_ISpellCheck, SpellCheck)
END_INTERFACE_MAP()
支持
? CDictionaryObj 明 入:
DECLARE_OLECREATE(CDictionaryObj)
? CDictionaryObj 文件 入:
// {54BF6567-1007-11D1-B0AA-444553540000}
IMPLEMENT_OLECREATE(CDictionaryObj, " Dictionary.Object ",
0x54bf6567, 0x1007, 0x11d1, 0xb0, 0xaa, 0x44,
0x45, 0x53, 0x54, 0x00, 0x00)
ATL介绍
?ATL COM的 ′于MFC
? 使用多继承技术 多?接口
? 支持多线程
? QueryInterface用到了特殊的技术
? 创建对象 ′于以往的技术
? 优化
ATL概况
? 封装了一些数据
–CComBSTR CComVariant CComPtr,等
? COM接口和COM对象
– 接口 对象 ,等
? 窗口的支持
– CWindow CWindowImpl CDialogImpl,等
? 'COM特征的支持
– 永久?支持
– ?接点支持
– ??对象和枚举fi对象
– ActiveX control and container
– 等
CComBSTR
? 封装了BSTR
? 提供了大?便利的?符串操作
– 构—函数
– 各种操作符以及一般的?符串操作
– 对于流(stream)的支持
? 需 BSTR的地 ,都可以用CComBSTR来
代替
? 注意owership
CComVariant
? 封装了VARIANT ?
? 提供了 用的操作
– 构—函数
– 各种操作符以及一般的管理操作
– 对于流(stream)的支持
? 需 VARIANT的地 ,都可以用
CComVARIANT来代替
CComPtr CComQIPtr
?Smart pointer
template<class T> template<class T, const IID* piid = &__uuidof(T)>
class CComPtr class CComQIPtr
{{
public: public:
T* p; T* p;
…..
}; };
? 优点:
– fl?管理AddRef/Release
– 大多数情况?,可以当作接口a 来使用
? 注意:禁止调用“->Release”和“->AddRef”
CComDispatchDriver
? 封装了IDispatch接口
? ?了对接口a 的管理 外,有? 的功能:
– ?访问函数:
? GetIDOfName/ GetProperty/ PutProperty
? GetPropertyByName/ PutPropertyByName
– 法访问函数:
? by DISPID:Invoke0/Invoke1/Invoke2/InvokeN
?by Name:Invoke0/Invoke1/Invoke2/InvokeN
– 两?¢£函数:
?By DISPID:GetProperty/PutProperty
ATL的 层次
CMyClass
CComObjectRootBase
CComObjectRootEx<TM>
IXxxImpl IMyItf1 IMyItf2
CComObject<T>等
CComXxxThreadModel
CComObjectRootBase
? ObjectMain
? static InternalQueryInterface
? OuterAddRef/OuterRelease/OuterQueryInterface
? InternalFinalConstructAddRef/
InternalFinalConstructRelease
? '一些¢£函数
? 联?:
union
{
long m_dwRef;
IUnknown* m_pOuterUnknown;
};
ATL对象的线程
? 用到了trait技术
? 过编译?˙的 提供just thread-safe enough
? CComSingleThreadModel
? CComMultiThreadModel
? CComMultiThreadNoCS
? 提供了两?¢£成员函数和 ?typedef
– Increment Decrement
– AutoCriticalSection CriticalSection
ThreadModelNoCS
ATL对象 用 数
? CComObjectRootEx
– InternalAddRef
– InternalRelease
– 作用 匿名联?的m_dwRef成员上
? CComObjectRootEx定义了一把锁
– 锁的 AutoCriticalSection
– 对锁的封装ObjectLock,wrapper
? 用于 被聚?的情况?
ATL对象 QueryInterface
? Table-driven QueryInterface
? Interface Map
BEGIN_COM_MAP(class)
COM_INTERFACE_ENTRY(itf)
END_COM_MAP
? 一
struct _ATL_INTMAP_ENTRY {
const IID* piid;
DWORD dw;
_ATL_CREATORARGFUNC *pFunc;
};
ATL 的接口
?IDispatchImpl
? IPersistStreamInitImpl
? IConnectionPointContainerImpl
? 举 :
template<class T, const IID* piid, …> class IDispatchImpl : public T {…};
template <class T> class IConnectionPointContainerImpl : public
IConnectionPointContainer{...};
class CMyObject :
public IDispatchImpl<IMyDispInterface, &IID_IMyDispInterface,... >,
public IConnectionPointContainerImpl< CMyObject >
{…};
真¥的ATL对象
? 决定这?COM对象?何被分配,?否被聚?等
? 区别:
– 线程 ?以 ? 的,per-class,可以封装到
– 对象的 命周期和身份标识?以 ?对象 的,per-object,
延后到最终的 最初决定
?CComObject :
– template <class Base> CComObject : public Base {…};
– 支持聚?:class CComAggObject;
– 支持聚?: class CComPolyObject;
– template <class Base> CComObjectCached : public Base {…};
– template <class Base> CComObjectNoLock : public Base {…};
– template <class Base> CComObjectGlobal : public Base {…};
– template <class Base> CComObjectStack : public Base {…};
ATL对象的创建
? 两??骤:
– 使用CRT的构—fi
– FinalConstruct
? 对应于FinalConstruct有FinalRelease
? 举 :
CMyClassFactory::CreateInstance() {
……
CComObject<CMyObject> *pObj = new CComObject<CMyObject>;
…...
pObj->InternalFinalConstructAddRef();
HRESULT hr = FinalConstruct();
pObj->InternalFinalConstructRelease();
……
}
ATL Creators
? ?creator 有一?¢£CreateInstance函数:
HRESULT WINAPI CreateInstance(void* pv, REFIID riid, LPVOID* ppv);
? 举 :
template <class T> class CComCreator {
public:
static HRESULT WINAPI CreateInstance(void* pv, REFIID riid, LPVOID* ppv) {
……
T *pObj = new T(pv);
…...
pObj->InternalFinalConstructAddRef();
HRESULT hr = FinalConstruct();
pObj->InternalFinalConstructRelease();
……
hr = p->QueryInterface(riid, ppv);
……
}
};
ATL Creators( )
? '的creator 有
– CComCreator2 —— 根据pv参数?否 null 两?对象 择一
– CComFailCreator —— 假的创建
? CMyObject 定义一? _CreatorClass, ?
– typedef CComCreator<CComObject<CMyObject>> _CreatorClass;
?CComCoClass定义:
template<class T, const CLSID* pclsid = &CLSID_NULL>
class CComCoClass {
public:
……
template<class Q> static HRESULT CreateInstance(IUnknown* punkOuter, Q** pp)
{ return T::_CreatorClass::CreateInstance(punkOuter, __uuidof(Q), (void **)pp); }
……
};
聚?情况?对象结构?
CMyClass
CComObjectRootBase
CComObjectRootEx<TM>
IXxxImpl IMyItf1 IMyItf2
CComContainedObject
CComXxxThreadModel
CComAggObject
IUnknown
委托IUnknown
委托IUnknown
ATL 对象聚?的
template <class contained>
class CComAggObject :
public IUnknown,
public CComObjectRootEx< contained::_ThreadModel::ThreadModelNoCS >
{
public :
STDMETHOD_(ULONG, AddRef)() {…}
STDMETHOD_(ULONG, Release)() {…}
STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject){…}
……
CComContainedObject<contained> m_contained;
};
委托IUnknown
委托IUnknown
ATL 对象聚?的 ( )
template <class Base> //Base must be derived from CComObjectRoot
class CComContainedObject : public Base
{
public:
typedef Base _BaseClass;
CComContainedObject(void* pv) {m_pOuterUnknown = (IUnknown*)pv;}
STDMETHOD_(ULONG, AddRef)() {return OuterAddRef();}
STDMETHOD_(ULONG, Release)() {return OuterRelease();}
STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject)
{ …… // 调用 OuterQueryInterface(iid, ppvObject); }
……
IUnknown* GetControllingUnknown() { … }
};
// CComObjectRootBase 联?成员m_pOuterUnknown起作用
接口
? COM_INTERFACE_ENTRY
? COM_INTERFACE_ENTRY_IID(iid, x)
? COM_INTERFACE_ENTRY2(x, x2)
? COM_INTERFACE_ENTRY2_IID(iid, x, x2)
? COM_INTERFACE_ENTRY_FUNC(iid, dw, func)
? COM_INTERFACE_ENTRY_FUNC_BLIND(dw, func)
? COM_INTERFACE_ENTRY_TEAR_OFF(iid, x)
? COM_INTERFACE_ENTRY_CACHED_TEAR_OFF(iid, x, punk)
? COM_INTERFACE_ENTRY_AGGREGATE(iid, punk)
? COM_INTERFACE_ENTRY_AGGREGATE_BLIND(punk)
? COM_INTERFACE_ENTRY_CHAIN(classname)
ATL Servers
? 功能
– Register and Unregister all class
– exposing class object
– managing server’s lifetime
?ATL 结构
– object map
– CComModule
Object Map
? 示
BEGIN_OBJECT_MAP(ObjectMap)
OBJECT_ENTRY(CLSID_DictionaryObj, CDictionaryObj)
OBJECT_ENTRY_NON_CREATEABLE(COtherObj)
END_OBJECT_MAP()
? 宏定义:
#define BEGIN_OBJECT_MAP(x) static _ATL_OBJMAP_ENTRY x[] = {
#define END_OBJECT_MAP() {NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL}};
_ATL_OBJMAP_ENTRY定义
struct _ATL_OBJMAP_ENTRY
{
const CLSID* pclsid;
HRESULT (WINAPI *pfnUpdateRegistry)(BOOL bRegister);
_ATL_CREATORFUNC* pfnGetClassObject;
_ATL_CREATORFUNC* pfnCreateInstance;
IUnknown* pCF;
DWORD dwRegister;
_ATL_DESCRIPTIONFUNC* pfnGetObjectDescription;
_ATL_CATMAPFUNC* pfnGetCategoryMap;
void (WINAPI *pfnObjectMain)(bool bStarting);
};
OBJECT_ENTRY定义
#define OBJECT_ENTRY(clsid, class) {&clsid,
class::UpdateRegistry,
class::_ClassFactoryCreatorClass::CreateInstance,
class::_CreatorClass::CreateInstance, NULL, 0,
class::GetObjectDescription, class::GetCategoryMap,
class::ObjectMain },
#define OBJECT_ENTRY_NON_CREATEABLE(class)
{&CLSID_NULL, class::UpdateRegistry, NULL, NULL,
NULL, 0, NULL, class::GetCategoryMap,
class::ObjectMain },
的注
? OBJECT_ENTRY 的class::UpdateRegistry
– ? 都 提供UpdateRegistry成员
– 宏:
? DECLARE_NO_REGISTRY()
? DECLARE_REGISTRY(class, pid, vpid, nid, flags)
? DECLARE_REGISTRY_RESOURCE(x)
? DECLARE_REGISTRY_RESOURCEID(x)
? 成的工程使用 进ˉ注
– Registry Script File
? OBJECT_ENTRY宏包含:
class::_ClassFactoryCreatorClass::CreateInstance
? DECLARE_CLASSFACTORY_EX宏定义:
#define DECLARE_CLASSFACTORY_EX(cf) typedef CComCreator< CComObjectCached< cf > > _ClassFactoryCreatorClass;
#define DECLARE_CLASSFACTORY() DECLARE_CLASSFACTORY_EX(CComClassFactory)
? CComCoClass定义 包含
DECLARE_CLASSFACTORY()
的创建
? OBJECT_ENTRY宏包含:
class::_CreatorClass::CreateInstance
? DECLARE_AGGREGATABLE(x)宏定义:
#define DECLARE_AGGREGATABLE(x) public:typedef CComCreator2< CComCreator< CComObject< x > >, CComCreator< CComAggObject< x > > > _CreatorClass;
? CComCoClass定义 包含
DECLARE_AGGREGATABLE(T)
的?接
? 的初始化
– in-proc server,DllGetClassObject
– out-of-proc server,RegisterClassObject
? 把 创建函数
– CComClassFactory 有以?成员:
_ATL_CREATORFUNC* m_pfnCreateInstance;
? 的CreateInstance 法调用
m_pfnCreateInstance
CComModule
? ?
– ATL inproc server:CComModule _Module;
– ATL local server:CExeModule _Module;
– service-base server:CServiceModule _Module;
? Init/Term函数
? 注 功能
? 提供 锁功能
编译优化
? ATL_NO_VTABLE
– 止 构—/ 构过程 调 vptr, 于 函数的
vtable 用 ?被构—/ 构函数访问,所以这
接fi优化 函数的vptr
? _ATL_MIN_CRT
– 接标准C/C++?ˉ库
? _ATL_DLL
– ?£ 接atl.dll
? _ATL_STATIC_REGISTRY
– ¢£ 接组件注 功能
? 的ATL对象
class CDictionary :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CDictionary, &CLSID_Dictionary>,
public IDictionary,
public ISpellCheck
{
public:
CDictionary() { }
DECLARE_REGISTRY_RESOURCEID(IDR_DICTIONARY)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CDictionary)
COM_INTERFACE_ENTRY(IDictionary)
COM_INTERFACE_ENTRY(ISpellCheck)
END_COM_MAP()
? 的ATL对象( )
public:
// IDictionary
STDMETHOD_(BOOL, Initialize)();
STDMETHOD_(BOOL, LoadLibrary)(LPOLESTR);
STDMETHOD_(BOOL, InsertWord)(LPOLESTR, LPOLESTR);
STDMETHOD_(void, DeleteWord)( LPOLESTR);
STDMETHOD_(BOOL, LookupWord)(LPOLESTR, LPOLESTR *);
STDMETHOD_(BOOL, RestoreLibrary)(LPOLESTR);
STDMETHOD_(void, FreeLibrary)();
// ISpellCheck
STDMETHOD_(BOOL, CheckWord)(LPOLESTR, LPOLESTR *);
private:
……
};
过 ATL Object Wizard创建对象
过 ATL Object Wizard?置对象名?
过 ATL Object Wizard?置对象 ?
示和作业