/*
*********************************************************************
*
*	The Essence of OLE
*
*	Source code sample
*
*	Copyright (c) 1996, Rolling Thunder Computing, Ipswich MA
*
*	e-mail: essence@rollthunder.com
*	CompuServe: 73540,3430
*	Web: http://www.rollthunder.com
*
*	File Name: HELLO.CPP
*
*	Purpose: OLE Automation object that implements IDispatch
*
*********************************************************************
*/

#include "resource.h"
#include "hellodisp.h"       
					

extern HWND hMainWnd ;

/*
Class Constructor/destructor
*/

CHelloDispatch::CHelloDispatch()
{
    m_RefCount = 1;
    m_bstrHelloMsg = SysAllocString(L"Hello, world");		
}

CHelloDispatch::~CHelloDispatch()
{
    SysFreeString(m_bstrHelloMsg);		
}





STDMETHODIMP CHelloDispatch::QueryInterface(REFIID riid, void **ppv)
{

/*
Someone is asking us for our IDispatch or dispinterface. They get a 
pointer to this object.
*/
 	
    if (riid == IID_IUnknown || riid == IID_IDispatch)
    {  
		*ppv = this ;
	    AddRef();
    	return NOERROR;
    }

/*
Caller asked for an interface that we don't support.
*/    
    else 
    {
	  	*ppv = NULL;
		return E_NOINTERFACE ;
    }
}


STDMETHODIMP_(ULONG) CHelloDispatch::AddRef()
{
    return ++m_RefCount;
}

STDMETHODIMP_(ULONG) CHelloDispatch::Release()
{
    if(--m_RefCount == 0)
    {
     
      PostQuitMessage(0);
      delete this;
      return 0;
    }
    return m_RefCount;
}

        
/*
STEP 2
GetIDsOfNames( ) method.  Caller is asking for the dispatch IDs that correspond
to the names of the specified items.  Compare the requested name with the ones
that we support.  If found, place the integer ID in the output parameter and
return success, otherwise return an error code.
*/

STDMETHODIMP CHelloDispatch::GetIDsOfNames(REFIID riid, LPOLESTR *pNames,
	UINT cNames, LCID lcid, DISPID *pDispID)
{

	return DISP_E_UNKNOWNNAME ;
}

/*
IDispatch::Invoke( ) method.  Caller is telling us to do something,
either call a method or set or get the value of a property. Decode 
parameters and take requested action.
*/

STDMETHODIMP CHelloDispatch::Invoke(DISPID dispidMember, REFIID riid,
	LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
	VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
{
	
/*
Caller wants to get or set the HelloMessage property.
*/
	if (dispidMember == 1)
	{
/*
STEP 3
Check the wFlags element for DISPATCH_PROPERTYGET.  If found, the caller
is trying to get the HelloMessage property. Set the vt element of the
pVarResult parameter to the proper value to indicate a string. Use the
function SysAllocString( ) to allocate a new BSTR containing the string in
the member variable m_bstrHelloMsg. Place this BSTR in the return variant
and return the success code.
*/

/*
STEP 4
Check the wFlags element for DISPATCH_PROPERTYPUT.  If found, the caller
is trying to set the HelloMessage property. Check the vt element of the 
supplied variant to make sure it contains a BSTR.  If so, use the 
function SysReAllocString( ) to reset the value of the member variable
m_bstrHelloMsg to the new value supplied in the VARIANT. Return success
or failure code.
*/



/*
STEP 5
Perform type checking on the passed VARIANT.  If not ablt to be coerced 
into a  BSTR, then fill EXCEPINFO structure and return the failure code 
that says the EXCEPINFO contains valid information.
*/

	}

/*
Caller wants to output the current message in the box
*/

	else if (dispidMember == 2)
	{
		if (pDispParams->cArgs != 0)
		{
			return DISP_E_BADPARAMCOUNT ;
		}

		MessageBeep (0) ;
		char out [128] ;
		WideCharToMultiByte (CP_ACP, 0, m_bstrHelloMsg, SysStringByteLen(m_bstrHelloMsg), out, sizeof(out), NULL, NULL) ; 
		SetDlgItemText(hMainWnd, IDC_HELLOAREA, out);
		return NOERROR ;
	}

	return DISP_E_MEMBERNOTFOUND ;
}


/*
Unimplemented methods of IDispatch.
*/


STDMETHODIMP CHelloDispatch::GetTypeInfoCount(UINT *pNtypeInfo)
{
	*pNtypeInfo = 0;
	return E_NOTIMPL ;
}
        
STDMETHODIMP CHelloDispatch::GetTypeInfo(UINT itinfo, LCID lcid, ITypeInfo **pptinfo)
{
	*pptinfo = NULL ;	
	return E_NOTIMPL ;
}
