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"));
本文详细介绍了在C++项目中如何使用ATL模块和全局变量,通过实例展示了Dll、EXE和服务版本的实现,并阐述了RegisterServer和UnregisterServer方法的使用,以及类型库注册的相关步骤。

被折叠的 条评论
为什么被折叠?



