COM聚合完整实例.docx
《COM聚合完整实例.docx》由会员分享,可在线阅读,更多相关《COM聚合完整实例.docx(47页珍藏版)》请在冰点文库上搜索。
COM聚合完整实例
///Aggre/CompA
///Aggre/CompA/CompA.cpp
//CompA.cpp:
DefinestheentrypointfortheDLLapplication.
//
#include"stdafx.h"
#include
#include
#include"objbase.h"
#include"olectl.h"
#include"CompA.h"
#include"factory.h"
#include"registry.h"
ULONGg_LockNumber=0;
ULONGg_CompANumber=0;
HANDLEg_hModule;
//{16DCB981-BEEB-11d2-B362-00104B08CC22}
extern"C"constGUIDCLSID_CompA=
{0x16dcb981,0xbeeb,0x11d2,
{0xb3,0x62,0x0,0x10,0x4b,0x8,0xcc,0x22}};
//{16DCB982-BEEB-11d2-B362-00104B08CC22}
extern"C"constGUIDIID_SomeInterface=
{0x16dcb982,0xbeeb,0x11d2,
{0xb3,0x62,0x0,0x10,0x4b,0x8,0xcc,0x22}};
BOOLAPIENTRYDllMain(HANDLEhModule,
DWORDul_reason_for_call,
LPVOIDlpReserved
)
{
g_hModule=hModule;
returnTRUE;
}
extern"C"HRESULT__stdcallDllGetClassObject(constCLSID&clsid,constIID&iid,void**ppv)
{
if(clsid==CLSID_CompA){
CAFactory*pFactory=newCAFactory;
if(pFactory==NULL){
returnE_OUTOFMEMORY;
}
HRESULTresult=pFactory->QueryInterface(iid,ppv);
returnresult;
}else{
returnCLASS_E_CLASSNOTAVAILABLE;
}
}
extern"C"HRESULT__stdcallDllCanUnloadNow(void)
{
if((g_CompANumber==0)&&(g_LockNumber==0))
returnS_OK;
else
returnS_FALSE;
}
//
//Serverregistration
//
extern"C"HRESULT__stdcallDllRegisterServer()
{
charszModule[1024];
DWORDdwResult=:
:
GetModuleFileName((HMODULE)g_hModule,szModule,1024);
if(dwResult==0)
returnSELFREG_E_CLASS;
returnRegisterServer(CLSID_CompA,
szModule,
"CompA.Object",
"CompAComponent",
NULL);
}
//
//Serverunregistration
//
extern"C"HRESULT__stdcallDllUnregisterServer()
{
returnUnregisterServer(CLSID_CompA,
"CompA.Object",NULL);
}
//ImplementionofclassCA
CA:
:
CA(IUnknown*pUnknownOuter)
{
m_Ref=0;
g_CompANumber++;
m_pUnknownOuter=pUnknownOuter;
}
CA:
:
~CA()
{
}
ULONGCA:
:
NondelegatingAddRef()
{
m_Ref++;
return(ULONG)m_Ref;
}
ULONGCA:
:
NondelegationRelease()
{
m_Ref--;
if(m_Ref==0)
{
g_CompANumber--;
deletethis;
return0;
}
return(ULONG)m_Ref;
}
HRESULTCA:
:
NondelegationQueryInterface(constIID&iid,void**ppv)
{
if(iid==IID_IUnknown)
{
*ppv=(INondelegatingUnknown*)this;
((IUnknown*)(*ppv))->AddRef();
}elseif(iid==IID_SomeInterface)
{
*ppv=(ISomeInterface*)this;
((ISomeInterface*)(*ppv))->AddRef();
}
else
{
*ppv=NULL;
returnE_NOINTERFACE;
}
returnS_OK;
}
ULONGCA:
:
AddRef()
{
if(m_pUnknownOuter!
=NULL)
returnm_pUnknownOuter->AddRef();
else
returnNondelegatingAddRef();
}
ULONGCA:
:
Release()
{
if(m_pUnknownOuter!
=NULL)
returnm_pUnknownOuter->Release();
else
returnNondelegationRelease();
}
HRESULTCA:
:
QueryInterface(constIID&iid,void**ppv)
{
if(m_pUnknownOuter!
=NULL)
returnm_pUnknownOuter->QueryInterface(iid,ppv);
else
returnNondelegationQueryInterface(iid,ppv);
}
HRESULTCA:
:
SomeFunction()
{
printf("ThisisCA:
:
SomeFunction!
\n");
returnS_OK;
}
///Aggre/CompA/CompA.def
;CompA.def:
DeclaresthemoduleparametersfortheDLL.
LIBRARY"CompA"
DESCRIPTION'CompAComponentWindowsDynamicLinkLibrary'
EXPORTS
;Explicitexportscangohere
DllGetClassObject@1PRIVATE
DllRegisterServer@2PRIVATE
DllUnregisterServer@3PRIVATE
DllCanUnloadNow@4PRIVATE
///Aggre/CompA/CompA.H
#ifndef__CompA_H__
#define__CompA_H__
#ifndef__ISomeInterface_H__
#include"SomeIFace.h"
#endif
classINondelegatingUnknown
{
public:
virtualHRESULT__stdcallNondelegationQueryInterface(constIID&iid,void**ppv)=0;
virtualULONG__stdcallNondelegatingAddRef()=0;
virtualULONG__stdcallNondelegationRelease()=0;
};
classCA:
publicISomeInterface,publicINondelegatingUnknown
{
protected:
ULONGm_Ref;
public:
CA(IUnknown*pUnknownOuter);
~CA();
public:
//DelegatingIUnknown
virtualHRESULT__stdcallQueryInterface(constIID&iid,void**ppv);
virtualULONG__stdcallAddRef();
virtualULONG__stdcallRelease();
//NondelegatingIUnknown
virtualHRESULT__stdcallNondelegationQueryInterface(constIID&iid,void**ppv);
virtualULONG__stdcallNondelegatingAddRef();
virtualULONG__stdcallNondelegationRelease();
virtualHRESULT__stdcallSomeFunction();
private:
IUnknown*m_pUnknownOuter;//pointertoouterIUnknown
};
#endif__CompA_H__
///Aggre/CompA/Factory.cpp
#include"stdafx.h"
#include"factory.h"
#include"CompA.h"
externULONGg_LockNumber;
externULONGg_CompANumber;
CAFactory:
:
CAFactory()
{
m_Ref=0;
}
CAFactory:
:
~CAFactory()
{
}
HRESULTCAFactory:
:
QueryInterface(constIID&iid,void**ppv)
{
if(iid==IID_IUnknown)
{
*ppv=(IUnknown*)this;
((IUnknown*)(*ppv))->AddRef();
}elseif(iid==IID_IClassFactory)
{
*ppv=(IClassFactory*)this;
((IClassFactory*)(*ppv))->AddRef();
}
else
{
*ppv=NULL;
returnE_NOINTERFACE;
}
returnS_OK;
}
ULONGCAFactory:
:
AddRef()
{
m_Ref++;
return(ULONG)m_Ref;
}
ULONGCAFactory:
:
Release()
{
m_Ref--;
if(m_Ref==0){
deletethis;
return0;
}
return(ULONG)m_Ref;
}
HRESULTCAFactory:
:
CreateInstance(IUnknown*pUnknownOuter,
constIID&iid,void**ppv)
{
HRESULThr;
//iidmustbeIID_IUnknownforaggregating
if((pUnknownOuter!
=NULL)&&(iid!
=IID_IUnknown))
{
returnCLASS_E_NOAGGREGATION;
}
*ppv=NULL;
hr=E_OUTOFMEMORY;
//Createtheobjectpassingfunctiontonotifyondestruction.
CA*pObj=newCA(pUnknownOuter);
if(NULL==pObj)
returnhr;
//Obtainthefirstinterfacepointer(whichdoesanAddRef)
hr=pObj->NondelegationQueryInterface(iid,ppv);
if(hr!
=S_OK){
//KilltheobjectifinitialcreationorFInitfailed.
g_CompANumber--;//Referencecountg_CompANumberbeaddedinconstructor
deletepObj;
}
returnhr;
}
HRESULTCAFactory:
:
LockServer(BOOLbLock)
{
if(bLock)
g_LockNumber++;
else
{
g_LockNumber--;
}
returnNOERROR;
}
///Aggre/CompA/Factory.h
#ifndef__CompA_FACTORY__
#define__CompA_FACTORY__
#include"Unknwn.h"
classCAFactory:
publicIClassFactory
{
protected:
ULONGm_Ref;
public:
CAFactory();
~CAFactory();
//IUnknownmembers
HRESULT__stdcallQueryInterface(constIID&iid,void**ppv);
ULONG__stdcallAddRef();
ULONG__stdcallRelease();
//IClassFactorymembers
HRESULT__stdcallCreateInstance(IUnknown*,constIID&iid,void**ppv);
HRESULT__stdcallLockServer(BOOL);
};
#endif//__CompA_FACTORY__
///Aggre/CompA/Registry.cpp
//
//Registry.cpp
//
#include
#include
#include"Registry.h"
////////////////////////////////////////////////////////
//
//Internalhelperfunctionsprototypes
//
//-Thesehelperfunctionswereborrowedandmodifedfrom
//DaleRogerson'sbookInsideCOM.
//Setthegivenkeyanditsvalue.
BOOLSetKeyAndValue(constchar*pszPath,
constchar*szSubkey,
constchar*szValue);
//ConvertaCLSIDintoacharstring.
voidCLSIDtoString(constCLSID&clsid,
char*szCLSID,
intlength);
//DeleteszKeyChildandallofitsdescendents.
LONGDeleteKey(HKEYhKeyParent,constchar*szKeyString);
////////////////////////////////////////////////////////
//
//Constants
//
//SizeofaCLSIDasastring
constintCLSID_STRING_SIZE=39;
/////////////////////////////////////////////////////////
//
//Publicfunctionimplementation
//
//
//Registerthecomponentintheregistry.
//
HRESULTRegisterServer(constCLSID&clsid,//ClassID
constchar*szFileName,//DLLmodulehandle
constchar*szProgID,//IDs
constchar*szDescription,//DescriptionString
constchar*szVerIndProgID)//optional
{
//ConverttheCLSIDintoachar.
charszCLSID[CLSID_STRING_SIZE];
CLSIDtoString(clsid,szCLSID,sizeof(szCLSID));
//BuildthekeyCLSID\\{...}
charszKey[64];
strcpy(szKey,"CLSID\\");
strcat(szKey,szCLSID);
//AddtheCLSIDtotheregistry.
SetKeyAndValue(szKey,NULL,szDescription);
//AddtheserverfilenamesubkeyundertheCLSIDkey.
SetKeyAndValue(szKey,"InprocServer32",szFileName);
//AddtheProgIDsubkeyundertheCLSIDkey.
if(szProgID!
=NULL){
SetKeyAndValue(szKey,"ProgID",szProgID);
SetKeyAndValue(szProgID,"CLSID",szCLSID);
}
if(szVerIndProgID){
//Addtheversion-independentProgIDsubkeyunderCLSIDkey.
SetKeyAndValue(szKey,"VersionIndependentProgID",
szVerIndProgID);
//Addtheversion-independentProgIDsubkeyunderHKEY_CLASSES_ROOT.
SetKeyAndValue(szVerIndProgID,NULL,szDescription);
SetKeyAndValue(szVerIndProgID,"CLSID",szCLSID);
SetKeyAndValue(szVerIndProgID,"CurVer",szProgID);
//AddtheversionedProgIDsubkeyunderHKEY_CLASSES_ROOT.
SetKeyAndValue(szProgID,NULL,szDescription);
SetKeyAndValue(szProgID,"CLSID",szCLSID);
}
returnS_OK;
}
//
//Removethecomponentfromtheregistry.
//
HRESULTUnregisterServer(constCLSID&clsid,//ClassID
constchar*szProgID,//IDs
constchar*szVerIndProgID)//Programmatic
{
//ConverttheCLSIDintoachar.
charszCLSID[CLSID_STRING_SIZE];
CLSIDtoString(clsid,szCLSID,sizeof(szCLSID));
//BuildthekeyCLSID\\{...}
charszKey[64];
strcpy(szKey,"CLSID\\");
strcat(szKey,szCLSID);
//DeletetheCLSIDKey-CLSID\{...}
LONGlResult=DeleteKey(HKEY_CLASSES_ROOT,szKey);
//Deletetheversion-independentProgIDKey.
if(szVerIndProgID!
=NULL)
lResult=DeleteKey(HKEY_CLASSES_ROOT,szVerIndProgID);
//DeletetheProgIDkey.
if(szProgID!
=NULL)
lResult=DeleteKey(HKEY_CLASSES_ROOT,szProgID);
returnS_OK;
}
///////////////////////////