BEEPER.CPP
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:8k
源码类别:

Windows编程

开发平台:

Visual C++

  1. /*
  2.  * BEEPER.CPP
  3.  * Simple Automation Object #5 Chapter 14
  4.  *
  5.  * Implementation of the CBeeper class demonstrating the use of
  6.  * CreateStdDispatch instead of DispInvoke, DispGetIDOfNames, and
  7.  * a custom IDispatch implementation.  In this case we don't have
  8.  * our own IDispatch at all, which CreateStdDispatch provides for
  9.  * us, but at the loss of multiple language support and the ability
  10.  * to define exception.
  11.  *
  12.  * Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
  13.  *
  14.  * Kraig Brockschmidt, Microsoft
  15.  * Internet  :  kraigb@microsoft.com
  16.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  17.  */
  18. #include "beeper.h"
  19. /*
  20.  * CBeeper::CBeeper
  21.  * CBeeper::~CBeeper
  22.  *
  23.  * Parameters (Constructor):
  24.  *  pUnkOuter       LPUNKNOWN of a controlling unknown.
  25.  *  pfnDestroy      PFNDESTROYED to call when an object
  26.  *                  is destroyed.
  27.  */
  28. CBeeper::CBeeper(LPUNKNOWN pUnkOuter, PFNDESTROYED pfnDestroy)
  29.     {
  30.     m_cRef=0;
  31.     m_pUnkOuter=pUnkOuter;
  32.     m_pfnDestroy=pfnDestroy;
  33.     m_lSound=0;
  34.     m_pITINeutral=NULL;
  35.     m_pIUnkStdDisp=NULL;
  36.     return;
  37.     }
  38. CBeeper::~CBeeper(void)
  39.     {
  40.     ReleaseInterface(m_pIUnkStdDisp);
  41.     ReleaseInterface(m_pITINeutral);
  42.     return;
  43.     }
  44. /*
  45.  * CBeeper::Init
  46.  *
  47.  * Purpose:
  48.  *  Performs any intiailization of a CBeeper that's prone to failure
  49.  *  that we also use internally before exposing the object outside.
  50.  *
  51.  * Parameters:
  52.  *  None
  53.  *
  54.  * Return Value:
  55.  *  BOOL            TRUE if the function is successful,
  56.  *                  FALSE otherwise.
  57.  */
  58. BOOL CBeeper::Init(void)
  59.     {
  60.     LPUNKNOWN       pIUnknown=this;
  61.     ITypeLib       *pITypeLib;
  62.     HRESULT         hr;
  63.     if (NULL!=m_pUnkOuter)
  64.         pIUnknown=m_pUnkOuter;
  65.     /*
  66.      * Load our type library.  Since this sample uses
  67.      * CreateStdDispatch we can only support one locale,
  68.      * which is neutral (English) in this case.
  69.      */
  70.     if (FAILED(LoadRegTypeLib(LIBID_BeeperTypeLibrary, 1, 0
  71.         , LANG_NEUTRAL, &pITypeLib)))
  72.         {
  73.         /*
  74.          * If LoadRegTypeLib fails, try loading directly with
  75.          * LoadTypeLib, which will register the library for us.
  76.          *
  77.          * NOTE:  You should prepend your DIR registry key to the
  78.          * .TLB name so you don't depend on it being it the PATH.
  79.          * This sample will be updated later to reflect this.
  80.          */
  81.         if (FAILED(LoadTypeLib(OLETEXT("BEEP0000.TLB"), &pITypeLib)))
  82.             return FALSE;
  83.         }
  84.     //Get the type information out of the type library.
  85.     hr=pITypeLib->GetTypeInfoOfGuid(DIID_DIBeeper, &m_pITINeutral);
  86.     if (FAILED(hr))
  87.         {
  88.         pITypeLib->Release();
  89.         return FALSE;
  90.         }
  91.     m_pImpIProvideCI=new CImpIProvideClassInfo(this, pITypeLib);
  92.     pITypeLib->Release();
  93.     if (FAILED(hr))
  94.         return FALSE;
  95.     /*
  96.      * CreateStdDispatch always returns an IUnknown pointer
  97.      * because such is required in aggregation, which is
  98.      * involved here.  In other words, the Beeper is aggregating
  99.      * on the OLE-provided "StdDispatch" object in order to
  100.      * directly expose IDispatch from that object.  See the
  101.      * implementation of QueryInterface.
  102.      */
  103.     hr=CreateStdDispatch(pIUnknown, (IBeeper *)this, m_pITINeutral
  104.         , &m_pIUnkStdDisp);
  105.     if (FAILED(hr))
  106.         return FALSE;
  107.     return TRUE;
  108.     }
  109. /*
  110.  * CBeeper::QueryInterface
  111.  * CBeeper::AddRef
  112.  * CBeeper::Release
  113.  *
  114.  * Purpose:
  115.  *  IUnknown members for CBeeper object.
  116.  */
  117. STDMETHODIMP CBeeper::QueryInterface(REFIID riid, PPVOID ppv)
  118.     {
  119.     *ppv=NULL;
  120.     /*
  121.      * The only calls for IUnknown are either in a nonaggregated
  122.      * case or when created in an aggregation, so in either case
  123.      * always return our IUnknown for IID_IUnknown.
  124.      */
  125.     if (IID_IUnknown==riid || IID_IBeeper==riid)
  126.         *ppv=this;
  127.     /*
  128.      * We specifically have to ask the object returned from
  129.      * CreateStdDispatch for our dispinterface.  Note that
  130.      * it only understands IID_IDispatch and not DIID_DIBeeper,
  131.      * so we convert requests for DIID_DIBeeper into IID_IDispatch
  132.      * which amounts to exactly the same thing.
  133.      */
  134.     if (IID_IDispatch==riid || DIID_DIBeeper==riid)
  135.         return m_pIUnkStdDisp->QueryInterface(IID_IDispatch, ppv);
  136.     //AddRef any interface we'll return.
  137.     if (NULL!=*ppv)
  138.         {
  139.         ((LPUNKNOWN)*ppv)->AddRef();
  140.         return NOERROR;
  141.         }
  142.     return ResultFromScode(E_NOINTERFACE);
  143.     }
  144. STDMETHODIMP_(ULONG) CBeeper::AddRef(void)
  145.     {
  146.     return ++m_cRef;
  147.     }
  148. STDMETHODIMP_(ULONG) CBeeper::Release(void)
  149.     {
  150.     if (0L!=--m_cRef)
  151.         return m_cRef;
  152.     //Inform the server about destruction so it can handle shutdown
  153.     if (NULL!=m_pfnDestroy)
  154.         (*m_pfnDestroy)();
  155.     delete this;
  156.     return 0L;
  157.     }
  158. //IBeeper interface functions
  159. /*
  160.  * CBeeper::get_Sound
  161.  * CBeeper::put_Sound
  162.  *
  163.  * Purpose:
  164.  *  Functions called from DispInvoke to handle the Sound property.
  165.  *
  166.  * Parameters (Set only):
  167.  *  lSound          long, new sound to save after validation.
  168.  *
  169.  * Return Value: (Get only):
  170.  *  ULONG           Current sound.
  171.  */
  172. STDMETHODIMP_(long) CBeeper::get_Sound(void)
  173.     {
  174.     return m_lSound;
  175.     }
  176. STDMETHODIMP_(void) CBeeper::put_Sound(long lSound)
  177.     {
  178.     if (MB_OK!=lSound && MB_ICONEXCLAMATION!=lSound
  179.         && MB_ICONQUESTION!=lSound && MB_ICONHAND!=lSound
  180.         && MB_ICONASTERISK!=lSound)
  181.         {
  182.         /*
  183.          * We cannot return error information to the StdDispatch
  184.          * given the way we've defined the return value of this
  185.          * methods, so we can't raise an exception.
  186.          */
  187.         return;
  188.         }
  189.     m_lSound=lSound;
  190.     return;
  191.     }
  192. /*
  193.  * CBeeper::Beep
  194.  *
  195.  * Purpose:
  196.  *  Function called from DispInvoke to invoke the Beep method.
  197.  *
  198.  * Return Value:
  199.  *  long            The sound played.
  200.  */
  201. STDMETHODIMP_(long) CBeeper::Beep(void)
  202.     {
  203.     MessageBeep((UINT)m_lSound);
  204.     return m_lSound;
  205.     }
  206. /*
  207.  * Since CreateStdDispatch provides an IDispatch implementation
  208.  * for us, there's no specific code for that interface needed here.
  209.  *
  210.  * So to not get rid of too much code, we'll add an
  211.  * IProvideClassInfo
  212.  */
  213. /*
  214.  * CImpIProvideClassInfo::CImpIProvideClassInfo
  215.  * CImpIProvideClassInfo::~CImpIProvideClassInfo
  216.  *
  217.  * Parameters (Constructor):
  218.  *  pUnkOuter       LPUNKNOWN of a controlling unknown.
  219.  *  pITypeLib       ITypeLib * to return from this interface.
  220.  */
  221. CImpIProvideClassInfo::CImpIProvideClassInfo(LPUNKNOWN pUnkOuter
  222.     , ITypeLib *pITypeLib)
  223.     {
  224.     m_cRef=0;
  225.     m_pUnkOuter=pUnkOuter;
  226.     /*
  227.      * Get the coclass type info.  If this fails then we'll
  228.      * just fail GetClassInfo below.
  229.      */
  230.     m_pITI=NULL;
  231.     pITypeLib->GetTypeInfoOfGuid(CLSID_Beeper, &m_pITI);
  232.     return;
  233.     }
  234. CImpIProvideClassInfo::~CImpIProvideClassInfo(void)
  235.     {
  236.     ReleaseInterface(m_pITI);
  237.     return;
  238.     }
  239. /*
  240.  * CImpIProvideClassInfo::QueryInterface
  241.  * CImpIProvideClassInfo::AddRef
  242.  * CImpIProvideClassInfo::Release
  243.  *
  244.  * Purpose:
  245.  *  IUnknown members for CImpIProvideClassInfo object.
  246.  */
  247. STDMETHODIMP CImpIProvideClassInfo::QueryInterface(REFIID riid, PPVOID ppv)
  248.     {
  249.     return m_pUnkOuter->QueryInterface(riid, ppv);
  250.     }
  251. STDMETHODIMP_(ULONG) CImpIProvideClassInfo::AddRef(void)
  252.     {
  253.     return m_pUnkOuter->AddRef();
  254.     }
  255. STDMETHODIMP_(ULONG) CImpIProvideClassInfo::Release(void)
  256.     {
  257.     return m_pUnkOuter->Release();
  258.     }
  259. /*
  260.  * CImpIProvideClassInfo::GetClassInfo
  261.  *
  262.  * Purpose:
  263.  *  Returns the type information for this coclass.
  264.  *
  265.  * Parameters:
  266.  *  ppITI           ITypeInfo ** in which to store the ITypeInfo
  267.  *                  for this coclass.
  268.  *
  269.  * Return Value:
  270.  *  HRESULT         NOERROR on success, error otherwise.
  271.  */
  272. STDMETHODIMP CImpIProvideClassInfo::GetClassInfo(ITypeInfo **ppITI)
  273.     {
  274.     if (NULL==ppITI)
  275.         return ResultFromScode(E_POINTER);
  276.     *ppITI=m_pITI;
  277.     if (NULL!=m_pITI)
  278.         {
  279.         m_pITI->AddRef();
  280.         return NOERROR;
  281.         }
  282.     return ResultFromScode(E_FAIL);
  283.     }