ATL Internals 2ed复习.chapter 5.CAtlModule

来源:互联网 发布:logo制作软件怎么用 编辑:程序博客网 时间:2024/06/06 05:00

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"));