Download - Implementing COM Objects
![Page 1: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/1.jpg)
Implementing COM Objects
主講人:虞台文
![Page 2: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/2.jpg)
Content
Types of COM Servers Objects with Single interface
– Example Enumerators Objects with Multiple interfaces
– Example Personal Account Server Modules of COM Class Factory & IClassFactory Example Simple Object Self-Registration InProcess Severs by MFC
![Page 3: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/3.jpg)
OLEObject Linking & Embedding
Types of
COM Servers
![Page 4: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/4.jpg)
Using COM Object
ClientClient
COMLibrary
COMLibrary
ServerServer
Object
Create object of a CLSID
CoCreateInstance()
Locate implementation, and load or launch server
Get object interface pointer, and return to
Client
Call interface members
![Page 5: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/5.jpg)
Where is the server located?
ClientClient
COMLibrary
COMLibrary
ServerServer
Object
Create object of a CLSID
CoCreateInstance()
Locate implementation, and load or launch server
Get object interface pointer, and return to
Client
Call interface members
![Page 6: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/6.jpg)
Server Types
Client Process
ClientClient
In-processserver
In-processserver
In-processobject
COMCOM
Localobjectproxy
Remoteobjectproxy
Local server process
Local serverLocal server
Localobject
COMCOM
Stub
Remote server process
COMCOM
Stub
Remote MachineRPC
RPCRemote server
Remote server
Remoteobject
![Page 7: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/7.jpg)
OLEObject Linking & Embedding
Objects with Single Interface
![Page 8: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/8.jpg)
Template of Enumerators
template <class ELT_T> interface IEnum : IUnknown
{
virtual HRESULT Next(ULONG celt, ELT_T *rgelt, ULONG *pceltFetched)=0;
virtual HRESULT Skip(ULONG celt)=0;
virtual HRESULT Reset(void)=0;
virtual HRESULT Clone(IEnum<ELT_T> ** ppEnum)=0;
};
template <class ELT_T> interface IEnum : IUnknown
{
virtual HRESULT Next(ULONG celt, ELT_T *rgelt, ULONG *pceltFetched)=0;
virtual HRESULT Skip(ULONG celt)=0;
virtual HRESULT Reset(void)=0;
virtual HRESULT Clone(IEnum<ELT_T> ** ppEnum)=0;
};
![Page 9: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/9.jpg)
IEnumXxx
![Page 10: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/10.jpg)
Example: Enumerate Rectangles
![Page 11: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/11.jpg)
Example: Enumerate Rectangles
![Page 12: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/12.jpg)
Example: Enumerate Rectangles
![Page 13: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/13.jpg)
IEnumRECT// IEmnuRect.h#if !defined(IEnumRECT_HEARDER)#define IEnumRECT_HEARDER
#include <objbase.h>#undef INTERFACE#define INTERFACE IEnumRECT
DECLARE_INTERFACE_(IEnumRECT, IUnknown){ // IUnknown methods STDMETHOD(QueryInterface)(THIS_ REFIID, void **) PURE; STDMETHOD_(ULONG, AddRef)(THIS) PURE; STDMETHOD_(ULONG, Release)(THIS) PURE; // IEnumRECT methods STDMETHOD(Next)(THIS_ DWORD, LPRECT, LPDWORD) PURE; STDMETHOD(Skip)(THIS_ DWORD) PURE; STDMETHOD(Reset)(THIS) PURE; STDMETHOD(Clone)(THIS_ IEnumRECT **) PURE;};
// {6E699FBF-5ED3-44f2-A547-1481C54E130A}DEFINE_GUID(IID_IEnumRECT, 0x6e699fbf, 0x5ed3, 0x44f2, 0xa5, 0x47, 0x14, 0x81, 0xc5, 0x4e, 0x13, 0xa);
typedef IEnumRECT * LPENUMRECT;
#endif // !defined(IEnumRECT_HEARDER)
// IEmnuRect.h#if !defined(IEnumRECT_HEARDER)#define IEnumRECT_HEARDER
#include <objbase.h>#undef INTERFACE#define INTERFACE IEnumRECT
DECLARE_INTERFACE_(IEnumRECT, IUnknown){ // IUnknown methods STDMETHOD(QueryInterface)(THIS_ REFIID, void **) PURE; STDMETHOD_(ULONG, AddRef)(THIS) PURE; STDMETHOD_(ULONG, Release)(THIS) PURE; // IEnumRECT methods STDMETHOD(Next)(THIS_ DWORD, LPRECT, LPDWORD) PURE; STDMETHOD(Skip)(THIS_ DWORD) PURE; STDMETHOD(Reset)(THIS) PURE; STDMETHOD(Clone)(THIS_ IEnumRECT **) PURE;};
// {6E699FBF-5ED3-44f2-A547-1481C54E130A}DEFINE_GUID(IID_IEnumRECT, 0x6e699fbf, 0x5ed3, 0x44f2, 0xa5, 0x47, 0x14, 0x81, 0xc5, 0x4e, 0x13, 0xa);
typedef IEnumRECT * LPENUMRECT;
#endif // !defined(IEnumRECT_HEARDER)
![Page 14: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/14.jpg)
CEnumRect// EnumRect.cpp//.....................................#include <afxtempl.h>#include "IEnumRect.h"
class CEnumRect : public IEnumRECT{private: DWORD m_cRef; //Reference count DWORD m_iCur; //Current enum position CArray<RECT, RECT> m_rects; //RECTS we enumerate
public: CEnumRect(CArray<RECT, RECT>& rects); virtual ~CEnumRect();
//IUnknown members STDMETHODIMP QueryInterface(REFIID, void **); STDMETHODIMP_(ULONG) AddRef(void); STDMETHODIMP_(ULONG) Release(void);
//IEnumRECT members STDMETHODIMP Next(ULONG, LPRECT, ULONG *); STDMETHODIMP Skip(ULONG); STDMETHODIMP Reset(void); STDMETHODIMP Clone(LPENUMRECT *);};//.....................................
// EnumRect.cpp//.....................................#include <afxtempl.h>#include "IEnumRect.h"
class CEnumRect : public IEnumRECT{private: DWORD m_cRef; //Reference count DWORD m_iCur; //Current enum position CArray<RECT, RECT> m_rects; //RECTS we enumerate
public: CEnumRect(CArray<RECT, RECT>& rects); virtual ~CEnumRect();
//IUnknown members STDMETHODIMP QueryInterface(REFIID, void **); STDMETHODIMP_(ULONG) AddRef(void); STDMETHODIMP_(ULONG) Release(void);
//IEnumRECT members STDMETHODIMP Next(ULONG, LPRECT, ULONG *); STDMETHODIMP Skip(ULONG); STDMETHODIMP Reset(void); STDMETHODIMP Clone(LPENUMRECT *);};//.....................................
![Page 15: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/15.jpg)
Constructor/Destructor
CEnumRect::CEnumRect(CArray<RECT, RECT>& rects){ m_rects.Copy(rects); //Ref counts always start at zero m_cRef=0;
//Current pointer is the first element m_iCur=0;}
CEnumRect::~CEnumRect(void){}
CEnumRect::CEnumRect(CArray<RECT, RECT>& rects){ m_rects.Copy(rects); //Ref counts always start at zero m_cRef=0;
//Current pointer is the first element m_iCur=0;}
CEnumRect::~CEnumRect(void){}
![Page 16: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/16.jpg)
CEnumRect::QueryInterface
STDMETHODIMP CEnumRect::QueryInterface(REFIID riid, void** ppv){ //Always NULL the out-parameters *ppv=NULL;
// No explicit typecast necessary since we singly derive // from IEnumRECT. if (IID_IUnknown==riid || IID_IEnumRECT==riid) *ppv= this; // == (LPUNKNOWN) this;
if (NULL==*ppv) return ResultFromScode(E_NOINTERFACE);
//AddRef any interface we'll return. ((LPUNKNOWN)*ppv)->AddRef();
return NOERROR;}
STDMETHODIMP CEnumRect::QueryInterface(REFIID riid, void** ppv){ //Always NULL the out-parameters *ppv=NULL;
// No explicit typecast necessary since we singly derive // from IEnumRECT. if (IID_IUnknown==riid || IID_IEnumRECT==riid) *ppv= this; // == (LPUNKNOWN) this;
if (NULL==*ppv) return ResultFromScode(E_NOINTERFACE);
//AddRef any interface we'll return. ((LPUNKNOWN)*ppv)->AddRef();
return NOERROR;}
![Page 17: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/17.jpg)
CEnumRect::AddRef, Release
STDMETHODIMP CEnumRect::AddRef(void){ return ++m_cRef;}
STDMETHODIMP_(ULONG) CEnumRect::Release(void){ if (0 != --m_cRef) return m_cRef; delete this; return 0;}
STDMETHODIMP CEnumRect::AddRef(void){ return ++m_cRef;}
STDMETHODIMP_(ULONG) CEnumRect::Release(void){ if (0 != --m_cRef) return m_cRef; delete this; return 0;}
![Page 18: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/18.jpg)
Exercise
1. Implementing objects with interfaces IEnumSentence and and IEnumWord for enumerating the sentences and words from a text file.
![Page 19: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/19.jpg)
OLEObject Linking & Embedding
Objects with Multiple Interfaces
![Page 20: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/20.jpg)
Three Methods
Interface Implementations
Contained Interface Classes
Multiple Inheritance
![Page 21: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/21.jpg)
Example: Personal Account
PersonalAccount
IUnknown
IBanking
IPettyCash
![Page 22: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/22.jpg)
IBanking and IPettyCash// Account.h#if !defined(IBanking_IPettyCash_HEARDER)#define IBanking_IPettyCash_HEARDER
#include <objbase.h>#undef INTERFACE#define INTERFACE IBanking
DECLARE_INTERFACE_(IBanking, IUnknown){ // IUnknown methods STDMETHOD(QueryInterface)(THIS_ REFIID, void **) PURE; STDMETHOD_(ULONG, AddRef)(THIS) PURE; STDMETHOD_(ULONG, Release)(THIS) PURE; // IBanking methods STDMETHOD(Deposit)(THIS_ UINT) PURE; STDMETHOD(Withdraw)(THIS_ UINT) PURE; STDMETHOD(Balance)(THIS_ UINT *) PURE;};
// {8B5D2FC3-5633-423e-B846-4315F10F7C4A}DEFINE_GUID(IID_IBanking, 0x8b5d2fc3, 0x5633, 0x423e, 0xb8, 0x46, 0x43, 0x15, 0xf1, 0xf, 0x7c, 0x4a);
typedef IBanking * LPBANKING;
// Account.h#if !defined(IBanking_IPettyCash_HEARDER)#define IBanking_IPettyCash_HEARDER
#include <objbase.h>#undef INTERFACE#define INTERFACE IBanking
DECLARE_INTERFACE_(IBanking, IUnknown){ // IUnknown methods STDMETHOD(QueryInterface)(THIS_ REFIID, void **) PURE; STDMETHOD_(ULONG, AddRef)(THIS) PURE; STDMETHOD_(ULONG, Release)(THIS) PURE; // IBanking methods STDMETHOD(Deposit)(THIS_ UINT) PURE; STDMETHOD(Withdraw)(THIS_ UINT) PURE; STDMETHOD(Balance)(THIS_ UINT *) PURE;};
// {8B5D2FC3-5633-423e-B846-4315F10F7C4A}DEFINE_GUID(IID_IBanking, 0x8b5d2fc3, 0x5633, 0x423e, 0xb8, 0x46, 0x43, 0x15, 0xf1, 0xf, 0x7c, 0x4a);
typedef IBanking * LPBANKING;
![Page 23: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/23.jpg)
IBanking and IPettyCash// Account.h#if !defined(IBanking_IPettyCash_HEARDER)#define IBanking_IPettyCash_HEARDER
#include <objbase.h>#undef INTERFACE#define INTERFACE IBanking
DECLARE_INTERFACE_(IBanking, IUnknown){ // IUnknown methods STDMETHOD(QueryInterface)(THIS_ REFIID, void **) PURE; STDMETHOD_(ULONG, AddRef)(THIS) PURE; STDMETHOD_(ULONG, Release)(THIS) PURE; // IBanking methods STDMETHOD(Deposit)(THIS_ UINT) PURE; STDMETHOD(Withdraw)(THIS_ UINT) PURE; STDMETHOD(Balance)(THIS_ UINT *) PURE;};
// {8B5D2FC3-5633-423e-B846-4315F10F7C4A}DEFINE_GUID(IID_IBanking, 0x8b5d2fc3, 0x5633, 0x423e, 0xb8, 0x46, 0x43, 0x15, 0xf1, 0xf, 0x7c, 0x4a);
typedef IBanking * LPBANKING;
// Account.h#if !defined(IBanking_IPettyCash_HEARDER)#define IBanking_IPettyCash_HEARDER
#include <objbase.h>#undef INTERFACE#define INTERFACE IBanking
DECLARE_INTERFACE_(IBanking, IUnknown){ // IUnknown methods STDMETHOD(QueryInterface)(THIS_ REFIID, void **) PURE; STDMETHOD_(ULONG, AddRef)(THIS) PURE; STDMETHOD_(ULONG, Release)(THIS) PURE; // IBanking methods STDMETHOD(Deposit)(THIS_ UINT) PURE; STDMETHOD(Withdraw)(THIS_ UINT) PURE; STDMETHOD(Balance)(THIS_ UINT *) PURE;};
// {8B5D2FC3-5633-423e-B846-4315F10F7C4A}DEFINE_GUID(IID_IBanking, 0x8b5d2fc3, 0x5633, 0x423e, 0xb8, 0x46, 0x43, 0x15, 0xf1, 0xf, 0x7c, 0x4a);
typedef IBanking * LPBANKING;
#undef INTERFACE#define INTERFACE IPettyCash
DECLARE_INTERFACE_(IPettyCash, IUnknown){
// IUnknown methodsSTDMETHOD(QueryInterface)(THIS_ REFIID, void **) PURE;STDMETHOD_(ULONG, AddRef)(THIS) PURE;STDMETHOD_(ULONG, Release)(THIS) PURE;// IPettyCash methodsSTDMETHOD(Income)(THIS_ UINT) PURE;STDMETHOD(Pay)(THIS_ UINT) PURE;STDMETHOD(Cash)(THIS_ UINT *) PURE;
};
// {7DCD4D1B-085E-40a7-93FE-4123E6F4C726}DEFINE_GUID(IID_IPettyCash, 0x7dcd4d1b, 0x85e, 0x40a7, 0x93, 0xfe, 0x41, 0x23, 0xe6, 0xf4, 0xc7, 0x26);
typedef IPettyCash * LPPETTYCASH;
#endif // !defined(IBanking_IPettyCash_HEARDER)
#undef INTERFACE#define INTERFACE IPettyCash
DECLARE_INTERFACE_(IPettyCash, IUnknown){
// IUnknown methodsSTDMETHOD(QueryInterface)(THIS_ REFIID, void **) PURE;STDMETHOD_(ULONG, AddRef)(THIS) PURE;STDMETHOD_(ULONG, Release)(THIS) PURE;// IPettyCash methodsSTDMETHOD(Income)(THIS_ UINT) PURE;STDMETHOD(Pay)(THIS_ UINT) PURE;STDMETHOD(Cash)(THIS_ UINT *) PURE;
};
// {7DCD4D1B-085E-40a7-93FE-4123E6F4C726}DEFINE_GUID(IID_IPettyCash, 0x7dcd4d1b, 0x85e, 0x40a7, 0x93, 0xfe, 0x41, 0x23, 0xe6, 0xf4, 0xc7, 0x26);
typedef IPettyCash * LPPETTYCASH;
#endif // !defined(IBanking_IPettyCash_HEARDER)
![Page 24: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/24.jpg)
Three Methods
Interface Implementations
Contained Interface Classes
Multiple Inheritance
![Page 25: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/25.jpg)
Exercise
2. Define interfaces for an object which manages personal data used in usual life, e.g., personal information and address book. You also need an interface (e.g., IPersistFile) to access the information from a file.
3. Implement the personal-data object including the interfaces you defined using the three methods described in this lecture.
4. Write an MFC application using the personal-data object.
![Page 26: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/26.jpg)
OLEObject Linking & Embedding
Server Modules of
COM
![Page 27: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/27.jpg)
The Generic Structure of a Server Module
ObjectObject interfaces
(as many as desired)
Class factory:Creates objects
Registration
Sever module
IClassFactory(2)
Exposure forClass factory
Unloadingmechanism
Implementation differs between DLL and EXE servers.
Implementation can be independent of execution context.
![Page 28: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/28.jpg)
Registry Entries
In-process servers: InprocServer32=<path to DLL>
Object handlers: InprocHandler32=<path to DLL>
Local servers: LocalServer32=<path to EXE>
![Page 29: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/29.jpg)
Self-Registration
DLL Servers– DllRegisterServer– DllUnregisterServer
EXE servers Command arguments– /RegServer – /UnregServer
![Page 30: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/30.jpg)
Server Emulation
\
CLSID
{42754580-16b7-11ce-80eb-00aa003d7352} = Original Component
TreatAs = {6fa820f0-2e48-11ce-80eb-00aa003d7352}
AutoTreatAs = {6fa820f0-2e48-11ce-80eb-00aa003d7352}
InprocServer32 = c:\older\original.dll
{6fa820f0-2e48-11ce-80eb-00aa003d7352} = New Emulating Component
InprocServer32 = c:\newer\emulator.dll
\
CLSID
{42754580-16b7-11ce-80eb-00aa003d7352} = Original Component
TreatAs = {6fa820f0-2e48-11ce-80eb-00aa003d7352}
AutoTreatAs = {6fa820f0-2e48-11ce-80eb-00aa003d7352}
InprocServer32 = c:\older\original.dll
{6fa820f0-2e48-11ce-80eb-00aa003d7352} = New Emulating Component
InprocServer32 = c:\newer\emulator.dll
![Page 31: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/31.jpg)
Some API’s
CoGetClassObject
CoCreateInstance(Ex)
CoGetTreatAsClass
CoTreatAsClass
![Page 32: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/32.jpg)
Exercises
5. Read the APIs for server emulations.
6. Lookup system registry to find some entries with TreatAs and AutoTreatAs keys.
![Page 33: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/33.jpg)
OLEObject Linking & Embedding
Class Factory & I
ClassFactory
![Page 34: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/34.jpg)
ServerServer
Class factory(an object)
The Class-Factory Object
ObjectFactory returnsNew interfacePointer to client
IClassFactory-::CreateInstance
Factory manufacturesobject.
ClientClient
![Page 35: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/35.jpg)
IClassFactory
interface IClassFactory : IUnknown
{
HRESULT CreateInstance(IUnknown *pUnkOuter, REFIID riid,
void **ppv);
HRESULT LockServer(BOOL fLock);
};
interface IClassFactory : IUnknown
{
HRESULT CreateInstance(IUnknown *pUnkOuter, REFIID riid,
void **ppv);
HRESULT LockServer(BOOL fLock);
};
![Page 36: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/36.jpg)
Licensing with IClassFactory2
interface IClassFactory2 : IClassFactory
{
HRESULT GetLicInfo(LPLICINFO pLicInfo);
HRESULT RequestLicKey(DWORD dwResrved, BSTR FAR* pbstrKey);
HRESULT CreateInstanceLic(IUnknown *pUnkOuter,
IUnknown *pUnkReserved, REFIID riid, BSTR bstrKey,
void **ppvObject);
};
interface IClassFactory2 : IClassFactory
{
HRESULT GetLicInfo(LPLICINFO pLicInfo);
HRESULT RequestLicKey(DWORD dwResrved, BSTR FAR* pbstrKey);
HRESULT CreateInstanceLic(IUnknown *pUnkOuter,
IUnknown *pUnkReserved, REFIID riid, BSTR bstrKey,
void **ppvObject);
};
![Page 37: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/37.jpg)
Exposing the Class Factory In-Process Server
Implement DllGetClassObject
Implement DllCanUnloadNow
STDAPI DllGetClassObject(REFCLSID rclsid,
REFIID riid,
void **ppv);
STDAPI DllGetClassObject(REFCLSID rclsid,
REFIID riid,
void **ppv);
STDAPI DllCanUnloadNow(void);STDAPI DllCanUnloadNow(void);
![Page 38: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/38.jpg)
Exposing the Class Factory Local Server
CoRegisterClassObject
CoRevokeClassObject
HRESULT CoRevokeClassObject(DWORD dwRegister);HRESULT CoRevokeClassObject(DWORD dwRegister);
STDAPI CoRegisterClassObject(
REFCLSID rclsid,
IUnknown * pUnk,
DWORD dwClsContext,
DWORD flags,
LPDWORD lpdwRegister
);
STDAPI CoRegisterClassObject(
REFCLSID rclsid,
IUnknown * pUnk,
DWORD dwClsContext,
DWORD flags,
LPDWORD lpdwRegister
);
![Page 39: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/39.jpg)
In-Process-Server Creation
![Page 40: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/40.jpg)
Local-Server Creation
![Page 41: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/41.jpg)
Create Multiple COM Objects
Step1. Get IClassFactory by
Step2. Call IClassFactory::CreateInstance(…) a number of time if multiple objects are neededStep3. Call IClassFactory::Release().
STDAPI CoGetClassObject(
REFCLSID rclsid, //CLSID associated with the class object
DWORD dwClsContext, //Context for running executable code
COSERVERINFO * pServerInfo, //Pointer to machine on which the object is to
// be instantiated
REFIID riid, //Reference to the identifier of the interface
LPVOID * ppv //Address of output variable that receives the
// interface pointer requested in riid
);
STDAPI CoGetClassObject(
REFCLSID rclsid, //CLSID associated with the class object
DWORD dwClsContext, //Context for running executable code
COSERVERINFO * pServerInfo, //Pointer to machine on which the object is to
// be instantiated
REFIID riid, //Reference to the identifier of the interface
LPVOID * ppv //Address of output variable that receives the
// interface pointer requested in riid
);
![Page 42: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/42.jpg)
Create Single COM Objects
STDAPI CoCreateInstance(
REFCLSID rclsid, //Class identifier (CLSID) of the object
LPUNKNOWN pUnkOuter, //Pointer to controlling IUnknown
DWORD dwClsContext, //Context for running executable code
REFIID riid, //Reference to the identifier of the interface
LPVOID * ppv //Address of output variable that receives
// the interface pointer requested in riid
);
STDAPI CoCreateInstance(
REFCLSID rclsid, //Class identifier (CLSID) of the object
LPUNKNOWN pUnkOuter, //Pointer to controlling IUnknown
DWORD dwClsContext, //Context for running executable code
REFIID riid, //Reference to the identifier of the interface
LPVOID * ppv //Address of output variable that receives
// the interface pointer requested in riid
);
![Page 43: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/43.jpg)
CoGetClassObject() vs. CoCreateInstance()
STDAPI CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwContext, REFIID iid, void **ppv){ HRESULT hr; IClassFactory *pCF;
*ppv=NULL;
hr=CoGetClassObject(rclsid, dwContext, NULL, IID_IClassFactory, (void **) &pCF);
if (FAILED(hr)) return hr;
hr=pCF->CreateInstance(pUnkOuter, iid, ppv);
pCF->Release();
return hr;}
STDAPI CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwContext, REFIID iid, void **ppv){ HRESULT hr; IClassFactory *pCF;
*ppv=NULL;
hr=CoGetClassObject(rclsid, dwContext, NULL, IID_IClassFactory, (void **) &pCF);
if (FAILED(hr)) return hr;
hr=pCF->CreateInstance(pUnkOuter, iid, ppv);
pCF->Release();
return hr;}
![Page 44: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/44.jpg)
OLEObject Linking & Embedding
Example
Simple Object
![Page 45: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/45.jpg)
Example: Simple Object In-Process Sever
![Page 46: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/46.jpg)
Exercises
7. The above example create COM object using CoCreateInstance(). Modify it by using class factory.
8. Modify the server of the above example so that it can create multiple classes of COM object.
9. Code the problem in Exercise 3 as an in-process server, and write an MFC application to use the object.
![Page 47: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/47.jpg)
OLEObject Linking & Embedding
Self-Registration
![Page 48: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/48.jpg)
Some Registry Functions
RegCreateKey(Ex) RegSetValue(Ex) RegCloseKey RegOpenKey(Ex) RegEnumKey(Ex) RegEnumValue RegQueryInfoKey RegDeleteKey
![Page 49: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/49.jpg)
RegSvr32.EXE
![Page 50: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/50.jpg)
DEF File
;DSimpleObject.def : 聲明動態庫 DLL 的模組參數 .
LIBRARY DSimpleObjectDESCRIPTION ' 我的第一個純 C++ COM 對象 '
EXPORTS DllRegisterServer PRIVATE ; COM server registration DllUnregisterServer PRIVATE ; COM server deregistration DllCanUnloadNow PRIVATE DllGetClassObject PRIVATE
;DSimpleObject.def : 聲明動態庫 DLL 的模組參數 .
LIBRARY DSimpleObjectDESCRIPTION ' 我的第一個純 C++ COM 對象 '
EXPORTS DllRegisterServer PRIVATE ; COM server registration DllUnregisterServer PRIVATE ; COM server deregistration DllCanUnloadNow PRIVATE DllGetClassObject PRIVATE
![Page 51: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/51.jpg)
OLEObject Linking & Embedding
InProcess Severs
by MFC
![Page 52: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/52.jpg)
Example: CalculatorMemory
![Page 53: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/53.jpg)
IMemoey
DECLARE_INTERFACE_(IMemory, IUnknown)
{
// IUnknown methods
STDMETHOD(QueryInterface)(THIS_ REFIID, void **) PURE;
STDMETHOD_(ULONG, AddRef)(THIS) PURE;
STDMETHOD_(ULONG, Release)(THIS) PURE;
// IMemory methods
STDMETHOD(MemoryClear)(THIS) PURE;
STDMETHOD(MemoryRecall)(THIS_ double *) PURE;
STDMETHOD(MemoryPlus)(THIS_ double) PURE;
STDMETHOD(MemoryMinus)(THIS_ double) PURE;
};
DECLARE_INTERFACE_(IMemory, IUnknown)
{
// IUnknown methods
STDMETHOD(QueryInterface)(THIS_ REFIID, void **) PURE;
STDMETHOD_(ULONG, AddRef)(THIS) PURE;
STDMETHOD_(ULONG, Release)(THIS) PURE;
// IMemory methods
STDMETHOD(MemoryClear)(THIS) PURE;
STDMETHOD(MemoryRecall)(THIS_ double *) PURE;
STDMETHOD(MemoryPlus)(THIS_ double) PURE;
STDMETHOD(MemoryMinus)(THIS_ double) PURE;
};
![Page 54: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/54.jpg)
Create MFC Project
![Page 55: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/55.jpg)
Create MFC Project
![Page 56: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/56.jpg)
Create MFC Project
![Page 57: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/57.jpg)
Create COM Objects
![Page 58: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/58.jpg)
CalculatorMemory.h
class CCalculatorMemory : public CCmdTarget{.........................................// Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CCalculatorMemory) public: virtual void OnFinalRelease(); //}}AFX_VIRTUAL
// Implementationprotected:......................................... DECLARE_OLECREATE(CCalculatorMemory)
// Generated OLE dispatch map functions //{{AFX_DISPATCH(CCalculatorMemory) // NOTE - the ClassWizard will add and remove member functions here. //}}AFX_DISPATCH DECLARE_DISPATCH_MAP() DECLARE_INTERFACE_MAP()};
class CCalculatorMemory : public CCmdTarget{.........................................// Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CCalculatorMemory) public: virtual void OnFinalRelease(); //}}AFX_VIRTUAL
// Implementationprotected:......................................... DECLARE_OLECREATE(CCalculatorMemory)
// Generated OLE dispatch map functions //{{AFX_DISPATCH(CCalculatorMemory) // NOTE - the ClassWizard will add and remove member functions here. //}}AFX_DISPATCH DECLARE_DISPATCH_MAP() DECLARE_INTERFACE_MAP()};
![Page 59: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/59.jpg)
CalculatorMemory.h
class CCalculatorMemory : public CCmdTarget{.........................................// Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CCalculatorMemory) public: virtual void OnFinalRelease(); //}}AFX_VIRTUAL
// Implementationprotected:......................................... DECLARE_OLECREATE(CCalculatorMemory)
// Generated OLE dispatch map functions //{{AFX_DISPATCH(CCalculatorMemory) // NOTE - the ClassWizard will add and remove member functions here. //}}AFX_DISPATCH DECLARE_DISPATCH_MAP() DECLARE_INTERFACE_MAP()};
class CCalculatorMemory : public CCmdTarget{.........................................// Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CCalculatorMemory) public: virtual void OnFinalRelease(); //}}AFX_VIRTUAL
// Implementationprotected:......................................... DECLARE_OLECREATE(CCalculatorMemory)
// Generated OLE dispatch map functions //{{AFX_DISPATCH(CCalculatorMemory) // NOTE - the ClassWizard will add and remove member functions here. //}}AFX_DISPATCH DECLARE_DISPATCH_MAP() DECLARE_INTERFACE_MAP()};
![Page 60: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/60.jpg)
CalculatorMemory.Cpp
...........................................................................BEGIN_DISPATCH_MAP(CCalculatorMemory, CCmdTarget) //{{AFX_DISPATCH_MAP(CCalculatorMemory) // NOTE - the ClassWizard will add and remove mapping macros here. //}}AFX_DISPATCH_MAPEND_DISPATCH_MAP()
// Note: we add support for IID_ICalculatorMemory to support typesafe binding// from VBA. This IID must match the GUID that is attached to the // dispinterface in the .ODL file.
// {07B9A7FE-DAD0-4865-9E96-43794803D4E7}static const IID IID_ICalculatorMemory ={ 0x7b9a7fe, 0xdad0, 0x4865, { 0x9e, 0x96, 0x43, 0x79, 0x48, 0x3, 0xd4, 0xe7 } };
BEGIN_INTERFACE_MAP(CCalculatorMemory, CCmdTarget) INTERFACE_PART(CCalculatorMemory, IID_ICalculatorMemory, Dispatch)END_INTERFACE_MAP()
// {E928B5CD-8700-48B3-9D74-21E7C76F4B35}IMPLEMENT_OLECREATE(CCalculatorMemory, "CalculatorMemory", ..........)...........................................................................
...........................................................................BEGIN_DISPATCH_MAP(CCalculatorMemory, CCmdTarget) //{{AFX_DISPATCH_MAP(CCalculatorMemory) // NOTE - the ClassWizard will add and remove mapping macros here. //}}AFX_DISPATCH_MAPEND_DISPATCH_MAP()
// Note: we add support for IID_ICalculatorMemory to support typesafe binding// from VBA. This IID must match the GUID that is attached to the // dispinterface in the .ODL file.
// {07B9A7FE-DAD0-4865-9E96-43794803D4E7}static const IID IID_ICalculatorMemory ={ 0x7b9a7fe, 0xdad0, 0x4865, { 0x9e, 0x96, 0x43, 0x79, 0x48, 0x3, 0xd4, 0xe7 } };
BEGIN_INTERFACE_MAP(CCalculatorMemory, CCmdTarget) INTERFACE_PART(CCalculatorMemory, IID_ICalculatorMemory, Dispatch)END_INTERFACE_MAP()
// {E928B5CD-8700-48B3-9D74-21E7C76F4B35}IMPLEMENT_OLECREATE(CCalculatorMemory, "CalculatorMemory", ..........)...........................................................................
![Page 61: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/61.jpg)
CalculatorMemory.Cpp
...........................................................................BEGIN_DISPATCH_MAP(CCalculatorMemory, CCmdTarget) //{{AFX_DISPATCH_MAP(CCalculatorMemory) // NOTE - the ClassWizard will add and remove mapping macros here. //}}AFX_DISPATCH_MAPEND_DISPATCH_MAP()
// Note: we add support for IID_ICalculatorMemory to support typesafe binding// from VBA. This IID must match the GUID that is attached to the // dispinterface in the .ODL file.
// {07B9A7FE-DAD0-4865-9E96-43794803D4E7}static const IID IID_ICalculatorMemory ={ 0x7b9a7fe, 0xdad0, 0x4865, { 0x9e, 0x96, 0x43, 0x79, 0x48, 0x3, 0xd4, 0xe7 } };
BEGIN_INTERFACE_MAP(CCalculatorMemory, CCmdTarget) INTERFACE_PART(CCalculatorMemory, IID_ICalculatorMemory, Dispatch)END_INTERFACE_MAP()
// {E928B5CD-8700-48B3-9D74-21E7C76F4B35}IMPLEMENT_OLECREATE(CCalculatorMemory, "CalculatorMemory", ..........)...........................................................................
...........................................................................BEGIN_DISPATCH_MAP(CCalculatorMemory, CCmdTarget) //{{AFX_DISPATCH_MAP(CCalculatorMemory) // NOTE - the ClassWizard will add and remove mapping macros here. //}}AFX_DISPATCH_MAPEND_DISPATCH_MAP()
// Note: we add support for IID_ICalculatorMemory to support typesafe binding// from VBA. This IID must match the GUID that is attached to the // dispinterface in the .ODL file.
// {07B9A7FE-DAD0-4865-9E96-43794803D4E7}static const IID IID_ICalculatorMemory ={ 0x7b9a7fe, 0xdad0, 0x4865, { 0x9e, 0x96, 0x43, 0x79, 0x48, 0x3, 0xd4, 0xe7 } };
BEGIN_INTERFACE_MAP(CCalculatorMemory, CCmdTarget) INTERFACE_PART(CCalculatorMemory, IID_ICalculatorMemory, Dispatch)END_INTERFACE_MAP()
// {E928B5CD-8700-48B3-9D74-21E7C76F4B35}IMPLEMENT_OLECREATE(CCalculatorMemory, "CalculatorMemory", ..........)...........................................................................
![Page 62: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/62.jpg)
Example: CalculatorMemory
View Source Code
![Page 63: Implementing COM Objects](https://reader036.vdocuments.mx/reader036/viewer/2022062301/568137f6550346895d9fb719/html5/thumbnails/63.jpg)
Exercises
10. Implement a simple calculator COM Sever by MFC.
11. Understanding what it is IDispatch.12. Understanding string data type BSTR.13. Understanding VARIANT data structure an
d its usages.