KOALA.CPP
资源名称:MSDN_VC98.zip [点击查看]
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:11k
源码类别:
Windows编程
开发平台:
Visual C++
- /*
- * KOALA.CPP
- * Koala Object with Custom Marshaling, Chapter 6
- *
- * Implementation of the CKoala object with a custom interface
- * to demonstrate local/remote transparency.
- *
- * Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
- *
- * Kraig Brockschmidt, Microsoft
- * Internet : kraigb@microsoft.com
- * Compuserve: >INTERNET:kraigb@microsoft.com
- */
- #include "koala.h"
- /*
- * CKoala::CKoala
- * CKoala::~CKoala
- *
- * Parameters (Constructor):
- * pUnkOuter LPUNKNOWN of a controlling unknown.
- * pfnDestroy PFNDESTROYED to call when an object
- * is destroyed.
- */
- CKoala::CKoala(LPUNKNOWN pUnkOuter, PFNDESTROYED pfnDestroy)
- {
- m_cRef=0;
- m_pUnkOuter=pUnkOuter;
- m_pfnDestroy=pfnDestroy;
- m_pImpIAnimal=NULL;
- m_pImpIKoala=NULL;
- m_pImpIMarshal=NULL;
- m_fJustAte=FALSE;
- m_cSleepAfterEat=0;
- return;
- }
- CKoala::~CKoala(void)
- {
- DeleteInterfaceImp(m_pImpIMarshal);
- DeleteInterfaceImp(m_pImpIKoala);
- DeleteInterfaceImp(m_pImpIAnimal);
- return;
- }
- /*
- * CKoala::Init
- *
- * Purpose:
- * Performs any intiailization of a CKoala that's prone to failure
- * that we also use internally before exposing the object outside.
- *
- * Parameters:
- * None
- *
- * Return Value:
- * BOOL TRUE if the function is successful,
- * FALSE otherwise.
- */
- BOOL CKoala::Init(void)
- {
- IUnknown *pUnkOuter=m_pUnkOuter;
- if (NULL==pUnkOuter)
- pUnkOuter=this;
- m_pImpIAnimal=new CImpIAnimal(this, pUnkOuter);
- if (NULL==m_pImpIAnimal)
- return FALSE;
- m_pImpIKoala=new CImpIKoala(this, pUnkOuter);
- if (NULL==m_pImpIKoala)
- return FALSE;
- m_pImpIMarshal=new CImpIMarshal(this, pUnkOuter);
- if (NULL==m_pImpIMarshal)
- return FALSE;
- return TRUE;
- }
- /*
- * CKoala::CallLocal
- *
- * Purpose:
- * Sends or posts a message to the local object.
- *
- * Parameters:
- * iMsg UINT identifying the function to call
- * lParam LPARAM containing extra information
- * fAsync BOOL indicating if this is a Post (TRUE) or
- * a send (FALSE).
- *
- * Return Value:
- * DWORD Return value from the function or an HRESULT
- * on failure.
- */
- DWORD CKoala::CallLocal(UINT iMsg, LPARAM lParam, BOOL fAsync)
- {
- DWORD dwRet=0;
- if (fAsync)
- PostMessage(m_hWndLocal, WM_COMMAND, (WPARAM)iMsg, lParam);
- else
- {
- dwRet=SendMessage(m_hWndLocal, WM_COMMAND, (WPARAM)iMsg
- , lParam);
- }
- return dwRet;
- }
- /*
- * CKoala::QueryInterface
- * CKoala::AddRef
- * CKoala::Release
- *
- * Purpose:
- * IUnknown members for CKoala object.
- */
- STDMETHODIMP CKoala::QueryInterface(REFIID riid, PPVOID ppv)
- {
- *ppv=NULL;
- /*
- * The only calls for IUnknown are either in a nonaggregated
- * case or when created in an aggregation, so in either case
- * always return our IUnknown for IID_IUnknown.
- */
- if (IID_IUnknown==riid)
- *ppv=this;
- if (IID_IAnimal==riid)
- *ppv=m_pImpIAnimal;
- if (IID_IKoala==riid)
- *ppv=m_pImpIKoala;
- if (IID_IMarshal==riid)
- *ppv=m_pImpIMarshal;
- if (NULL!=*ppv)
- {
- ((LPUNKNOWN)*ppv)->AddRef();
- return NOERROR;
- }
- return ResultFromScode(E_NOINTERFACE);
- }
- STDMETHODIMP_(ULONG) CKoala::AddRef(void)
- {
- return ++m_cRef;
- }
- STDMETHODIMP_(ULONG) CKoala::Release(void)
- {
- if (0L!=--m_cRef)
- return m_cRef;
- /*
- * If this is the last Release, then we have to tell
- * the server to free its object too. This is an async
- * call as we don't need to hang around for it to quit.
- */
- CallLocal(MSG_RELEASE, 0, TRUE);
- if (NULL!=m_pfnDestroy)
- (*m_pfnDestroy)();
- delete this;
- return 0;
- }
- //Proxy-side IAnimal implementation
- /*
- * CImpIAnimal::CImpIAnimal
- * CImpIAnimal::~CImpIAnimal
- *
- * Constructor Parameters:
- * pObj PCKoala of the object containing us.
- * pUnkOuter LPUNKNOWN to which we blindly delegate
- * all IUnknown calls.
- */
- CImpIAnimal::CImpIAnimal(PCKoala pObj, LPUNKNOWN pUnkOuter)
- {
- m_cRef=0;
- m_pObj=pObj;
- m_pUnkOuter=pUnkOuter;
- return;
- }
- CImpIAnimal::~CImpIAnimal(void)
- {
- return;
- }
- /*
- * CImpIAnimal::QueryInterface
- * CImpIAnimal::AddRef
- * CImpIAnimal::Release
- *
- * Purpose:
- * Delegating IUnknown members for interface implementation.
- */
- STDMETHODIMP CImpIAnimal::QueryInterface(REFIID riid
- , LPVOID *ppv)
- {
- return m_pUnkOuter->QueryInterface(riid, ppv);
- }
- STDMETHODIMP_(ULONG) CImpIAnimal::AddRef(void)
- {
- ++m_cRef;
- return m_pUnkOuter->AddRef();
- }
- STDMETHODIMP_(ULONG) CImpIAnimal::Release(void)
- {
- --m_cRef;
- return m_pUnkOuter->Release();
- }
- /*
- * CImpIAnimal::Eat
- *
- * Purpose:
- * Instructs the animal to eat something, returning what the animal
- * actually ate which usually goes against recommendation (which is
- * true for the human animal, too).
- *
- * Parameters:
- * pszFoodRecommended LPTSTR describing the food that the animal
- * should eat.
- * pszFoodEaten LPTSTR describing the food the animal actually
- * ate, which may not, of course, be the same as
- * what it should eat.
- * cchEaten short containing the lenght of pszFoodEaten.
- *
- * Return Value:
- * HRESULT NOERROR if food is eaten, S_FALSE if not.
- */
- STDMETHODIMP CImpIAnimal::Eat(LPTSTR pszFoodRecommended
- , LPTSTR pszFoodEaten, short cchEaten)
- {
- /*
- * Koalas aren't don't care what you tell them, they eat one
- * thing. We can handle the return string for the local
- * object, but we still need to tell it that this was
- * called.
- */
- _tcsncpy(pszFoodEaten, TEXT("Eucalyptus Leaves"), cchEaten);
- m_pObj->CallLocal(MSG_EAT, 0L, FALSE);
- return NOERROR;
- }
- /*
- * CImpIAnimal::Sleep
- *
- * Purpose:
- * Instructs the animal to sleep for a while.
- *
- * Parameters:
- * pcMinutes short * (in-out) containing the number of
- * minutes to sleep on entry, then number of
- * minutes actually slept on exit
- *
- * Return Value:
- * HRESULT NOERROR if sleep taken, S_FALSE if not, where
- * *pcMinutes should be zero.
- */
- STDMETHODIMP CImpIAnimal::Sleep(short *pcMinutes)
- {
- DWORD dwRet;
- //Pass the client's value
- dwRet=m_pObj->CallLocal(MSG_SLEEP, (LPARAM)*pcMinutes, FALSE);
- if (FAILED((HRESULT)dwRet))
- return (HRESULT)dwRet;
- //Store the return value in the client's variable.
- *pcMinutes=LOWORD(dwRet);
- return NOERROR;
- }
- /*
- * CImpIAnimal::Procreate
- *
- * Purpose:
- * Instructs the animal to procreate. On entry, the number of
- * offstring is unknown, so that's an out parameter.
- *
- * Parameters:
- * pcOffspring short * (out) in which to store the number
- * of new offspring.
- *
- * Return Value:
- * HRESULT NOERROR if offspring created, S_FALSE if not
- * where *pcOffspring should be zero.
- */
- STDMETHODIMP CImpIAnimal::Procreate(short *pcOffspring)
- {
- DWORD dwRet;
- dwRet=m_pObj->CallLocal(MSG_PROCREATE, 0, FALSE);
- if (FAILED((HRESULT)dwRet))
- return (HRESULT)dwRet;
- *pcOffspring=(short)LOWORD(dwRet);
- return ResultFromScode(0==dwRet ? S_FALSE : S_OK);
- }
- /*
- * CImpIAnimal::WhatKindOfAnimal
- *
- * Purpose:
- * Returns the IID of the specific animal interface that describes
- * the type of animal this really is (a much more complex
- * classification scheme might have IAnimal::WhatGenus and
- * IGenus::WhatSpecies, etc., but we're just being simple here).
- *
- * Parameters:
- * pIID IID * in which to store the specific
- * animal IID.
- *
- * Return Value:
- * HRESULT NOERROR if the animal type is known,
- * S_FALSE if not with *pIID set to IID_NULL.
- */
- STDMETHODIMP CImpIAnimal::WhatKindOfAnimal(IID *pIID)
- {
- //No need to ask the local object for something we know
- *pIID=IID_IKoala;
- return NOERROR;
- }
- //IKoala implementation
- /*
- * CImpIKoala::CImpIKoala
- * CImpIKoala::~CImpIKoala
- *
- * Constructor Parameters:
- * pObj PCKoala of the object containing us.
- * pUnkOuter LPUNKNOWN to which we blindly delegate
- * all IUnknown calls.
- */
- CImpIKoala::CImpIKoala(PCKoala pObj, LPUNKNOWN pUnkOuter)
- {
- m_cRef=0;
- m_pObj=pObj;
- m_pUnkOuter=pUnkOuter;
- return;
- }
- CImpIKoala::~CImpIKoala(void)
- {
- return;
- }
- /*
- * CImpIKoala::QueryInterface
- * CImpIKoala::AddRef
- * CImpIKoala::Release
- *
- * Purpose:
- * Delegating IUnknown members for interface implementation.
- */
- STDMETHODIMP CImpIKoala::QueryInterface(REFIID riid
- , LPVOID *ppv)
- {
- return m_pUnkOuter->QueryInterface(riid, ppv);
- }
- STDMETHODIMP_(ULONG) CImpIKoala::AddRef(void)
- {
- ++m_cRef;
- return m_pUnkOuter->AddRef();
- }
- STDMETHODIMP_(ULONG) CImpIKoala::Release(void)
- {
- --m_cRef;
- return m_pUnkOuter->Release();
- }
- /*
- * CImpIKoala::ClimbEucalyptusTree
- *
- * Purpose:
- * Tells the Koala to go climb a tree, which means eating, which
- * a koala is probably more than happy to do.
- *
- * Parameters:
- * iTree short identifying the tree to climb.
- *
- * Return Value:
- * HRESULT NOERROR if tree climbed, S_FALSE if not.
- */
- STDMETHODIMP CImpIKoala::ClimbEucalyptusTree(short iTree)
- {
- //We know the server doesn't need this
- return NOERROR;
- }
- /*
- * CImpIKoala::PouchOpensDown
- *
- * Purpose:
- * Do-nothing function to demonstrate a void argument list.
- *
- * Parameters:
- * None
- *
- * Return Value:
- * HRESULT NOERROR
- */
- STDMETHODIMP CImpIKoala::PouchOpensDown(void)
- {
- //We know the server doesn't need this
- return NOERROR;
- }
- /*
- * CImpIKoala::SleepAfterEating
- *
- * Purpose:
- * Tells the Koala to sleep an additional number of minutes after
- * eating.
- *
- * Parameters:
- * cMinutes short * (in) containing the number of
- * extra minutes to sleep after eating.
- *
- * Return Value:
- * HRESULT NOERROR
- */
- STDMETHODIMP CImpIKoala::SleepAfterEating(short cMinutes)
- {
- DWORD dwRet;
- dwRet=m_pObj->CallLocal(MSG_SLEEPAFTEREATING
- , (LPARAM)cMinutes, TRUE);
- if (FAILED((HRESULT)dwRet))
- return (HRESULT)dwRet;
- return NOERROR;
- }