AMBIENTS.CPP

/* 
* AMBIENTS.CPP
* Patron Chapter 24
*
* Implementation of the ambient properties IDispatch on a
* tenant control site.
*
* Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
*
* Kraig Brockschmidt, Microsoft
* Internet : kraigb@microsoft.com
* Compuserve: >INTERNET:kraigb@microsoft.com
*/


#include "patron.h"


/*
* CImpIDispatch::CImpIDispatch
* CImpIDispatch::~CImpIDispatch
*
* Parameters (Constructor):
* pTen PCTenant of the tenant we're in.
* pUnkOuter LPUNKNOWN to which we delegate.
*/

CImpIDispatch::CImpIDispatch(PCTenant pTen, LPUNKNOWN pUnkOuter)
{
m_cRef=0;
m_pTen=pTen;
m_pUnkOuter=pUnkOuter;
return;
}

CImpIDispatch::~CImpIDispatch(void)
{
return;
}




/*
* CImpIDispatch::QueryInterface
* CImpIDispatch::AddRef
* CImpIDispatch::Release
*/

STDMETHODIMP CImpIDispatch::QueryInterface(REFIID riid, PPVOID ppv)
{
return m_pUnkOuter->QueryInterface(riid, ppv);
}

STDMETHODIMP_(ULONG) CImpIDispatch::AddRef(void)
{
++m_cRef;
return m_pUnkOuter->AddRef();
}

STDMETHODIMP_(ULONG) CImpIDispatch::Release(void)
{
m_cRef--;
return m_pUnkOuter->Release();
}




/*
* CImpIDispatch::GetTypeInfoCount
* CImpIDispatch::GetTypeInfo
* CImpIDispatch::GetIDsOfNames
*
* Unimplemented members, not needed for ambient properties.
*/

STDMETHODIMP CImpIDispatch::GetTypeInfoCount(UINT *pctInfo)
{
*pctInfo=0;
return NOERROR;
}

STDMETHODIMP CImpIDispatch::GetTypeInfo(UINT itinfo
, LCID lcid, ITypeInfo **pptInfo)
{
*pptInfo=NULL;
return ResultFromScode(E_NOTIMPL);
}

STDMETHODIMP CImpIDispatch::GetIDsOfNames(REFIID riid
, OLECHAR **rgszNames, UINT cNames, LCID lcid, DISPID *rgDispID)
{
*rgszNames=NULL;
*rgDispID=NULL;
return ResultFromScode(E_NOTIMPL);
}




/*
* CImpIDispatch::Invoke
*
* Purpose:
* Calls a method in the dispatch interface or manipulates a
* property.
*
* Parameters:
* dispIDMember DISPID of the method or property of interest.
* riid REFIID reserved, must be NULL.
* lcid LCID of the locale.
* wFlags USHORT describing the context of the invocation.
* pDispParams DISPPARAMS * to the array of arguments.
* pVarResult VARIANT * in which to store the result. Is
* NULL if the caller is not interested.
* pExcepInfo EXCEPINFO * to exception information.
* puArgErr UINT * in which to store the index of an
* invalid parameter if DISP_E_TYPEMISMATCH
* is returned.
*
* Return Value:
* HRESULT NOERROR or a general error code.
*/


STDMETHODIMP CImpIDispatch::Invoke(DISPID dispIDMember, REFIID riid
, LCID lcid, unsigned short wFlags, DISPPARAMS *pDispParams
, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
{
HRESULT hr;
VARIANT varResult;

if (IID_NULL!=riid)
return ResultFromScode(E_INVALIDARG);

/*
* We ignore lcid in this function. A multilingual application
* might use it to determine the meaning of certain parameters
* or perhaps as an indication of how to format data like
* time, date, and currency or any other language or locale-
* sensitive data.
*/

/*
* Variable handling: since ambient properties is just a
* collection of singular read-only values, we don't have to
* worry about input parameters.
*/

/*
* If the caller is not interested in the return value, then
* pVarResult is NULL. But since we're dealing with ambient
* properties, there should always be an interest. In any case,
* if we're given a NULL, we'll point it to a dummy structure so
* the rest of the code can assume that pVarResult is non-NULL.
*/
if(NULL==pVarResult)
pVarResult=&varResult;

VariantInit(pVarResult);

//The most common case is boolean, use as an initial type
V_VT(pVarResult)=VT_BOOL;

/*
* Process the requested ambient property. Anything but a
* request for a property is invalid, so we can check that
* before looking at the specific ID. We can only get away
* with this because all properties are read-only.
*/

if (!(DISPATCH_PROPERTYGET & wFlags))
return ResultFromScode(DISP_E_MEMBERNOTFOUND);

hr=NOERROR;

switch (dispIDMember)
{
case DISPID_AMBIENT_BACKCOLOR:
V_I4(pVarResult)=m_pTen->m_clrBack;
V_VT(pVarResult)=VT_I4;
break;

case DISPID_AMBIENT_FORECOLOR:
V_I4(pVarResult)=m_pTen->m_clrFore;
V_VT(pVarResult)=VT_I4;
break;

case DISPID_AMBIENT_FONT:
/*
* If we failed to create the font, act like we
* don't support it.
*/
if (NULL==m_pTen->m_pIFont)
return ResultFromScode(DISP_E_MEMBERNOTFOUND);

//The correct type is an IFontDisp pointer
V_DISPATCH(pVarResult)=m_pTen->m_pIFont;
m_pTen->m_pIFont->AddRef();
V_VT(pVarResult)=VT_FONT;
break;

case DISPID_AMBIENT_LOCALEID:
V_I4(pVarResult)=m_pTen->m_lcid;
V_VT(pVarResult)=VT_I4;
break;

case DISPID_AMBIENT_USERMODE:
V_BOOL(pVarResult)=!m_pTen->m_fDesignMode;
break;

case DISPID_AMBIENT_UIDEAD:
V_BOOL(pVarResult)=m_pTen->m_fUIDead;
break;

case DISPID_AMBIENT_SUPPORTSMNEMONICS:
V_BOOL(pVarResult)=TRUE;
break;

case DISPID_AMBIENT_SHOWGRABHANDLES:
V_BOOL(pVarResult)=m_pTen->m_fHatchHandles;
break;

case DISPID_AMBIENT_SHOWHATCHING:
V_BOOL(pVarResult)=m_pTen->m_fHatchHandles;
break;

default:
hr=ResultFromScode(DISP_E_MEMBERNOTFOUND);
break;
}

return hr;
}