/*///////////////////////////////////// Start of CMike.c ///////////////////

//this file provides an implementation of the IMike interface
// by the class CMike, a COM server

Back to the "COM Inproc Server in C" tutorial.

*/

#define INIT /*only initialize GUIDs once per project. */
#include "CMike.h"

#define _UNICODE
#include <TChar.h>


/*/////////////////////////////////////////////////////////////////////////
//
// QueryInterface
//
// IMike *pIm the "this" pointer that C++ implicitly passes.
// note that since this is actually the interface
// pointer, we have to find the beginnging of the real
// structure. For now, we'll assume that the pointer
// is the beginnging of the relevant structure, though
// we can use macros to find this for us automatically
// (though at compile time)
//
//
// REFIID iid A reference to the IID that's being requested.
//
// void **ppv A pointer to a pointer that will either hold
// NULL (on failure) or the address of the interface
// if it succeeds
//
// NOTES: According to the COM spec, we have to:
// (1) Perform an implicit AddRef before handing this back
// (2) It might be good to develop code that will dynamically
// add interfaces that are available, so I don't have to
// recode this everytime
//
/////////////////////////////////////////////////////////////////////////*/

HRESULT _stdcall CMikeQueryInterface(IMike *pIm, REFIID iid, void **ppv)
{

CMike *pThis = (CMike *)pIm;
IID iidIMike = IID_IMike;

if( IsEqualIID( iid, &IID_IUnknown) || IsEqualIID( iid, &IID_IMike) )
{
*ppv = &(pThis->Im);
((struct IMikeVtbl *)pIm->lpVtbl)->pfnAddRef( pIm );
return S_OK;
/*I think this means that we're technically cheating in the case of
//IUnknown: we really give out an implementation of the interface
//to IMike(the first three of which are identical to IUnknown),and
// simply rely on the user to assume that only IUnknown methods are
// there*/

}
else
{
ppv = NULL;
return E_NOINTERFACE;
}
}


ULONG _stdcall CMikeAddRef( IMike *pIm)
{
CMike *pThis = (CMike *)pIm;

return ++pThis->cRef;
}

ULONG _stdcall CMikeRelease( IMike *pIm)
{
CMike *pThis = (CMike *)pIm;


if( --pThis->cRef <= 0 )
{
cCMike--;
free( pThis );
return 0;
}
else
{
return pThis->cRef;
}
}

void _stdcall MikeSet( IMike *pIm, ULONG ulNewVal)
{
CMike *pThis = (CMike *)pIm;

pThis->cMikeNum = ulNewVal;
}

ULONG _stdcall MikeGet(IMike *pIm)
{
CMike *pThis = (CMike *)pIm;

return pThis->cMikeNum;
}

void _stdcall MikeBeep(IMike *pIm)
{
Beep( 8000, 1500 ); //frequency (MHz), and time (ms)
}

struct IMikeVtbl IMVT = {
CMikeQueryInterface,
CMikeAddRef,
CMikeRelease,
MikeSet,
MikeGet,
MikeBeep
};

/*///////////////////////////////////// End of CMike.c /////////////////*/