1、 ) g_hModule = hModule; return TRUE; HRESULT _stdcall DllGetClassObject(const CLSID& clsid, const IID& iid, void *ppv) if (clsid = CLSID_CompA) CAFactory *pFactory = new CAFactory; if (pFactory = NULL) return E_OUTOFMEMORY ; HRESULT result = pFactory-QueryInterface(iid, ppv); return result; else ret
2、urn CLASS_E_CLASSNOTAVAILABLE; HRESULT _stdcall DllCanUnloadNow(void) if (g_CompANumber = 0) & (g_LockNumber = 0) return S_OK; else return S_FALSE;/ Server registration HRESULT _stdcall DllRegisterServer() char szModule1024; DWORD dwResult = :GetModuleFileName(HMODULE)g_hModule, szModule, 1024); if
3、(dwResult = 0) return SELFREG_E_CLASS; return RegisterServer(CLSID_CompA, szModule, CompA.Object,CompA Component NULL);/ Server unregistration HRESULT _stdcall DllUnregisterServer() return UnregisterServer(CLSID_CompA, ,NULL);/ Implemention of class CACA:CA (IUnknown *pUnknownOuter) m_Ref = 0; g_Com
4、pANumber + ; m_pUnknownOuter = pUnknownOuter;CA()ULONG CA:NondelegatingAddRef() m_Ref +; return (ULONG) m_Ref;NondelegationRelease () m_Ref -; if (m_Ref = 0 ) g_CompANumber - ; delete this; return 0;HRESULT CA:NondelegationQueryInterface(const IID& if ( iid = IID_IUnknown ) *ppv = (INondelegatingUnk
5、nown *) this ; (IUnknown *)(*ppv)-AddRef() ; else if ( iid = IID_SomeInterface ) *ppv = (ISomeInterface *) this ; (ISomeInterface *)(*ppv)- *ppv = NULL; return E_NOINTERFACE ; return S_OK;AddRef () if ( m_pUnknownOuter != NULL ) return m_pUnknownOuter-AddRef(); return NondelegatingAddRef();Release (
6、)Release (); return NondelegationRelease();QueryInterface(const IID& return NondelegationQueryInterface(iid, ppv);SomeFunction() printf(This is CA:SomeFunction!n);/Aggre/CompA/CompA.def; CompA.def : Declares the module parameters for the DLL.LIBRARY CompADESCRIPTION CompA Component Windows Dynamic L
7、ink LibraryEXPORTS ; Explicit exports can go here DllGetClassObject 1 PRIVATE DllRegisterServer 2 PRIVATE DllUnregisterServer 3 PRIVATE DllCanUnloadNow 4 PRIVATE/Aggre/CompA/CompA.H#ifndef _CompA_H_#define _CompA_H_#ifndef _ISomeInterface_H_SomeIFace.h#endifclass INondelegatingUnknownpublic: virtual
8、 HRESULT _stdcall NondelegationQueryInterface(const IID& iid, void *ppv) = 0 ; virtual ULONG _stdcall NondelegatingAddRef() = 0; virtual ULONG _stdcall NondelegationRelease() = 0;class CA : public ISomeInterface, public INondelegatingUnknownprotected: ULONG m_Ref; CA(IUnknown *pUnknownOuter); CA();p
9、ublic : / Delegating IUnknown virtual HRESULT _stdcall QueryInterface(const IID& iid, void *ppv) ; virtual ULONG _stdcall AddRef() ; virtual ULONG _stdcall Release() ; / Nondelegating IUnknown iid, void *ppv); virtual ULONG _stdcall NondelegatingAddRef(); virtual ULONG _stdcall NondelegationRelease(
10、); virtual HRESULT _stdcall SomeFunction( ) ; private : IUnknown *m_pUnknownOuter; / pointer to outer IUnknown#endif _CompA_H_/Aggre/CompA/Factory.cppextern ULONG g_LockNumber;extern ULONG g_CompANumber;CAFactory:CAFactory()CAFactory()HRESULT CAFactory: *ppv = (IUnknown *) this ; else if ( iid = IID
11、_IClassFactory) *ppv = (IClassFactory *) this ; (IClassFactory *)(*ppv)-ULONG CAFactory:AddRef()Release() if (m_Ref = 0 ) CreateInstance(IUnknown *pUnknownOuter, const IID& HRESULT hr; / iid must be IID_IUnknown for aggregating if ( ( pUnknownOuter != NULL ) & ( iid != IID_IUnknown ) ) return CLASS_
12、E_NOAGGREGATION; *ppv=NULL; hr=E_OUTOFMEMORY; /Create the object passing function to notify on destruction. CA *pObj=new CA (pUnknownOuter); if (NULL=pObj) return hr; /Obtain the first interface pointer (which does an AddRef) hr = pObj-NondelegationQueryInterface(iid, ppv); if (hr != S_OK) /Kill the
13、 object if initial creation or FInit failed. g_CompANumber -; / Reference count g_CompANumber be added in constructor delete pObj; return hr;LockServer(BOOL bLock) if (bLock) g_LockNumber +; g_LockNumber -; return NOERROR;/Aggre/CompA/Factory.h#ifndef _CompA_FACTORY_#define _CompA_FACTORY_Unknwn.hcl
14、ass CAFactory : public IClassFactory protected: public: CAFactory (); CAFactory (); /IUnknown members HRESULT _stdcall QueryInterface(const IID& ULONG _stdcall AddRef(); ULONG _stdcall Release(); /IClassFactory members HRESULT _stdcall CreateInstance(IUnknown *, const IID& HRESULT _stdcall LockServe
15、r(BOOL);#endif / _CompA_FACTORY_/Aggre/CompA/Registry.cpp/ Registry.cppobjbase.hassert.hRegistry.h/ Internal helper functions prototypes/ - These helper functions were borrowed and modifed from/ Dale Rogersons book Inside COM./ Set the given key and its value.BOOL SetKeyAndValue(const char* pszPath,
16、 const char* szSubkey, const char* szValue) ;/ Convert a CLSID into a char string.void CLSIDtoString(const CLSID& clsid, char* szCLSID, int length) ;/ Delete szKeyChild and all of its descendents.LONG DeleteKey(HKEY hKeyParent, const char* szKeyString) ;/ Constants/ Size of a CLSID as a stringconst
17、int CLSID_STRING_SIZE = 39 ;/ Public function implementation/ Register the component in the registry.HRESULT RegisterServer(const CLSID& clsid, / Class ID const char *szFileName, / DLL module handle const char* szProgID, / IDs const char* szDescription, / Description String const char* szVerIndProgI
18、D) / optional / Convert the CLSID into a char. char szCLSIDCLSID_STRING_SIZE ; CLSIDtoString(clsid, szCLSID, sizeof(szCLSID) ; / Build the key CLSID. char szKey64 ; strcpy(szKey, CLSID) ; strcat(szKey, szCLSID) ; / Add the CLSID to the registry. SetKeyAndValue(szKey, NULL, szDescription) ; / Add the
19、 server filename subkey under the CLSID key. SetKeyAndValue(szKey, InprocServer32, szFileName) ; / Add the ProgID subkey under the CLSID key. if (szProgID != NULL) SetKeyAndValue(szKey, ProgID, szProgID) ; SetKeyAndValue(szProgID, CLSID, szCLSID) ; if (szVerIndProgID) / Add the version-independent P
20、rogID subkey under CLSID key.VersionIndependentProgID szVerIndProgID) ; / Add the version-independent ProgID subkey under HKEY_CLASSES_ROOT. SetKeyAndValue(szVerIndProgID, NULL, szDescription) ; SetKeyAndValue(szVerIndProgID, CurVer / Add the versioned ProgID subkey under HKEY_CLASSES_ROOT. SetKeyAn
21、dValue(szProgID, NULL, szDescription) ; return S_OK ;/ Remove the component from the registry.HRESULT UnregisterServer(const CLSID& const char* szVerIndProgID) / Programmatic / Delete the CLSID Key - CLSID. LONG lResult = DeleteKey(HKEY_CLASSES_ROOT, szKey) ; / Delete the version-independent ProgID Key. if (szVerIndProgID != NULL) lResult = DeleteKey(HKEY_CLASSES_ROOT, szVerIndProgID) ; / Delete the ProgID key. lResult = DeleteKey(HKEY_CLASSES_ROOT, szProgID) ;/