The _AtlModule Global Variable
每一个项目,wizard都会生成一个全局变量_AtlModule,用户可以通过全局指针_pAtlModule来访问它,例如:
class CMathModule : public CAtlDllModuleT< CMathModule > { public: DECLARE_LIBID(LIBID_Math) DECLARE_REGISTRY_APPID_RESOURCEID(IDR_MATH, "{9CB95B71-536A-476a-9244-61363F5C60CA}") }; CMathModule _AtlModule;
Dll版中定义了default的RegisterAppId和RegisterServer,全局入口将会调用:
HRESULT DllRegisterServer(BOOL bRegTypeLib = TRUE) { T* pT = static_cast<T*>(this); HRESULT hr = pT->RegisterAppId(); if (SUCCEEDED(hr)) hr = pT->RegisterServer(bRegTypeLib); return hr; }
同样,EXE版本例子:
class CMathModule : public CAtlExeModuleT< CMathModule > { public: DECLARE_LIBID(LIBID_Math) DECLARE_REGISTRY_APPID_RESOURCEID(IDR_MATH, "{9CB95B71-536A-476a-9244-61363F5C60CA}") }; CMathModule _AtlModule;
Service版本例子:
class CMathModule : public CAtlServiceModuleT< CMathModule, IDS_SERVICENAME > { public: DECLARE_LIBID(LIBID_Math) DECLARE_REGISTRY_APPID_RESOURCEID(IDR_MATH, "{9CB95B71-536A-476a-9244-61363F5C60CA}") }; CMathModule _AtlModule;
The RegisterServer and UnregisterServer Methods
在inproc中:
STDAPI DllRegisterServer(void) { return _AtlModule.DllRegisterServer(); } STDAPI DllUnregisterServer(void) { return _AtlModule.DllUnregisterServer(); }
其中用到了下列函数:
template <class T> class ATL_NO_VTABLE CAtlDllModuleT : public CAtlModuleT<T> { public : ... HRESULT DllRegisterServer(BOOL bRegTypeLib = TRUE) { T* pT = static_cast<T*>(this); // server script HRESULT hr = pT->RegisterAppId(); if (SUCCEEDED(hr)) // all class scripts hr = pT->RegisterServer(bRegTypeLib); return hr; } HRESULT DllUnregisterServer(BOOL bUnRegTypeLib = TRUE) { T* pT = static_cast<T*>(this); // all class scripts HRESULT hr = pT->UnregisterServer(bUnRegTypeLib); if (SUCCEEDED(hr)) // server script hr = pT->UnregisterAppId(); return hr; } ... };
而在local server中:
bool CAtlExeModuleT< T >::ParseCommandLine(LPCTSTR lpCmdLine, HRESULT* pnRetCode) { ... if (WordCmpI(lpszToken, _T("UnregServer"))==0) { *pnRetCode = pT->UnregisterServer(TRUE); if (SUCCEEDED(*pnRetCode)) *pnRetCode = pT->UnregisterAppId(); return false; } // Register as Local Server if (WordCmpI(lpszToken, _T("RegServer"))==0) { *pnRetCode = pT->RegisterAppId(); if (SUCCEEDED(*pnRetCode)) *pnRetCode = pT->RegisterServer(TRUE); return false; } ... return true; }
The UpdateRegistryFromResource Methods
在注册class之前,COM server首先调用RegisterAppId(),这个函数会调用UpdateRegistryAppId(),真正工作的是UpdateRegistryFromResource()
如果编译前定义了_ATL_STATIC_REGISTRY,会使用atlbase.h中的UpdateRegistryFromResourceS
如果未定义,则使用atl80.dll中的UpdateRegistryFromResourceD
The Type Library Registration Methods
// Registry support (helpers) HRESULT RegisterTypeLib(); HRESULT RegisterTypeLib(LPCTSTR lpszIndex); HRESULT UnRegisterTypeLib(); HRESULT UnRegisterTypeLib(LPCTSTR lpszIndex);
如果要使用RegisterTypeLib(),应该在.rc中添加
1 TYPELIB "ATLInternals.tlb"
或者
1 TYPELIB "ATLInternals.tlb" 2 TYPELIB "ATLInternalsEx.tlb"
调用注册:
_AtlModule.RegisterTypeLib (); _AtlModule.RegisterTypeLib (_T ("\\2"));