|
// The VTable and functions for our ISub1 sub-object (of our IMultInterface).
#include <windows.h>
#include <objbase.h>
#include <stddef.h>
#include "IMultInterface2.h"
// Here are ISub1's functions.
//
// Every COM object's interface must have the 3 functions QueryInterface(),
// AddRef(), and Release().
//
// I also chose to add an extra function to ISub1, which an app
// will call with the name ShowMessage.
// ISub1's QueryInterface()
static HRESULT STDMETHODCALLTYPE QueryInterface(ISub1 *this, REFIID vTableGuid, void **ppv)
{
// Because ISub1 is a sub-object of one of our other COM objects (in the case, it's
// a sub-object of our IMultInterface) then an app is allowed to call our ISub1's
// QueryInterface to ask for a pointer not only to our ISub1 object, but also a
// pointer to its base object, or any other sub-objects for that particular
// IMultInterface.
//
// Because the base object's QueryInterface() already does all of this, the easiest
// thing to do is somehow get a pointer to this base object, substitute it for the
// "this" argument, and just call that base object's QueryInterface().
//
// Well, guess what? Because this ISub1 object is embedded right inside of its
// IMultInterface, it's very easy to get the base object just with a little
// pointer arithematic. Here it is:
return(IBase_QueryInterface((IBase *)((unsigned char *)this - offsetof(IMultInterface, sub1)), vTableGuid, ppv));
}
// ISub1's AddRef()
static ULONG STDMETHODCALLTYPE AddRef(ISub1 *this)
{
// Because ISub1 is a sub-object of our IMultInterface, then when an app
// calls our ISub1's AddRef, we must also call its base object's AddRef to
// increment the reference count. After all, we can't delete the base
// object without first deleting all other sub-objects too. So to prevent
// this from happening, we make sure that we increment the base reference
// count every time an app AddRef()'s an ISub1.
//
// The easiest thing to do is somehow get a pointer to this ISub1's base
// object, substitute it for the "this" argument, and just call that
// base object's AddRef().
//
// Well, guess what? Because this ISub1 object is embedded right inside of its
// IMultInterface, it's very easy to get the base object just with a little
// pointer arithematic. Here it is:
return(IBase_AddRef((IBase *)((unsigned char *)this - offsetof(IMultInterface, sub1))));
}
// ISub1's Release()
static ULONG STDMETHODCALLTYPE Release(ISub1 *this)
{
// See AddRef() remarks above
return(IBase_Release((IBase *)((unsigned char *)this - offsetof(IMultInterface, sub1))));
}
// ================== The following are my own extra functions added to ISub1
// ISub1's ShowMessage(). This displays the passed string in a message box
static HRESULT STDMETHODCALLTYPE ShowMessage(ISub1 *this, char *str)
{
MessageBox(0, str, "ISub1 ShowMessage", MB_OK);
return(NOERROR);
}
// Here is ISub1's VTable. It never changes so we can declare it
// static
static const ISub1Vtbl ISub1_Vtbl = {QueryInterface,
AddRef,
Release,
ShowMessage};
// This is just a helper function that initializes the ISub1 embedded
// inside of a IMultInterface
void initISub1(IMultInterface *myObj)
{
// Set the VTable for the embedded ISub1
myObj->sub1.lpVtbl = (ISub1Vtbl *)&ISub1_Vtbl;
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.