⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 beeper.cpp

📁 英文版的 想要的话可以下载了 为大家服务
💻 CPP
字号:
/*
 * BEEPER.CPP
 * Simple Automation Object #5 Chapter 14
 *
 * Implementation of the CBeeper class demonstrating the use of
 * CreateStdDispatch instead of DispInvoke, DispGetIDOfNames, and
 * a custom IDispatch implementation.  In this case we don't have
 * our own IDispatch at all, which CreateStdDispatch provides for
 * us, but at the loss of multiple language support and the ability
 * to define exception.
 *
 * Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
 *
 * Kraig Brockschmidt, Microsoft
 * Internet  :  kraigb@microsoft.com
 * Compuserve:  >INTERNET:kraigb@microsoft.com
 */


#include "beeper.h"


/*
 * CBeeper::CBeeper
 * CBeeper::~CBeeper
 *
 * Parameters (Constructor):
 *  pUnkOuter       LPUNKNOWN of a controlling unknown.
 *  pfnDestroy      PFNDESTROYED to call when an object
 *                  is destroyed.
 */

CBeeper::CBeeper(LPUNKNOWN pUnkOuter, PFNDESTROYED pfnDestroy)
    {
    m_cRef=0;
    m_pUnkOuter=pUnkOuter;
    m_pfnDestroy=pfnDestroy;

    m_lSound=0;
    m_pITINeutral=NULL;
    m_pIUnkStdDisp=NULL;
    return;
    }


CBeeper::~CBeeper(void)
    {
    ReleaseInterface(m_pIUnkStdDisp);
    ReleaseInterface(m_pITINeutral);
    return;
    }



/*
 * CBeeper::Init
 *
 * Purpose:
 *  Performs any intiailization of a CBeeper 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 CBeeper::Init(void)
    {
    LPUNKNOWN       pIUnknown=this;
    ITypeLib       *pITypeLib;
    HRESULT         hr;

    if (NULL!=m_pUnkOuter)
        pIUnknown=m_pUnkOuter;

    /*
     * Load our type library.  Since this sample uses
     * CreateStdDispatch we can only support one locale,
     * which is neutral (English) in this case.
     */

    if (FAILED(LoadRegTypeLib(LIBID_BeeperTypeLibrary, 1, 0
        , LANG_NEUTRAL, &pITypeLib)))
        {
        /*
         * If LoadRegTypeLib fails, try loading directly with
         * LoadTypeLib, which will register the library for us.
         *
         * NOTE:  You should prepend your DIR registry key to the
         * .TLB name so you don't depend on it being it the PATH.
         * This sample will be updated later to reflect this.
         */
        if (FAILED(LoadTypeLib(OLETEXT("BEEP0000.TLB"), &pITypeLib)))
            return FALSE;
        }

    //Get the type information out of the type library.
    hr=pITypeLib->GetTypeInfoOfGuid(DIID_DIBeeper, &m_pITINeutral);

    if (FAILED(hr))
        {
        pITypeLib->Release();
        return FALSE;
        }

    m_pImpIProvideCI=new CImpIProvideClassInfo(this, pITypeLib);
    pITypeLib->Release();

    if (FAILED(hr))
        return FALSE;

    /*
     * CreateStdDispatch always returns an IUnknown pointer
     * because such is required in aggregation, which is
     * involved here.  In other words, the Beeper is aggregating
     * on the OLE-provided "StdDispatch" object in order to
     * directly expose IDispatch from that object.  See the
     * implementation of QueryInterface.
     */
    hr=CreateStdDispatch(pIUnknown, (IBeeper *)this, m_pITINeutral
        , &m_pIUnkStdDisp);

    if (FAILED(hr))
        return FALSE;

    return TRUE;
    }



/*
 * CBeeper::QueryInterface
 * CBeeper::AddRef
 * CBeeper::Release
 *
 * Purpose:
 *  IUnknown members for CBeeper object.
 */

STDMETHODIMP CBeeper::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 || IID_IBeeper==riid)
        *ppv=this;

    /*
     * We specifically have to ask the object returned from
     * CreateStdDispatch for our dispinterface.  Note that
     * it only understands IID_IDispatch and not DIID_DIBeeper,
     * so we convert requests for DIID_DIBeeper into IID_IDispatch
     * which amounts to exactly the same thing.
     */
    if (IID_IDispatch==riid || DIID_DIBeeper==riid)
        return m_pIUnkStdDisp->QueryInterface(IID_IDispatch, ppv);

    //AddRef any interface we'll return.
    if (NULL!=*ppv)
        {
        ((LPUNKNOWN)*ppv)->AddRef();
        return NOERROR;
        }

    return ResultFromScode(E_NOINTERFACE);
    }


STDMETHODIMP_(ULONG) CBeeper::AddRef(void)
    {
    return ++m_cRef;
    }


STDMETHODIMP_(ULONG) CBeeper::Release(void)
    {
    if (0L!=--m_cRef)
        return m_cRef;

    //Inform the server about destruction so it can handle shutdown
    if (NULL!=m_pfnDestroy)
        (*m_pfnDestroy)();

    delete this;
    return 0L;
    }



//IBeeper interface functions

/*
 * CBeeper::get_Sound
 * CBeeper::put_Sound
 *
 * Purpose:
 *  Functions called from DispInvoke to handle the Sound property.
 *
 * Parameters (Set only):
 *  lSound          long, new sound to save after validation.
 *
 * Return Value: (Get only):
 *  ULONG           Current sound.
 */

STDMETHODIMP_(long) CBeeper::get_Sound(void)
    {
    return m_lSound;
    }


STDMETHODIMP_(void) CBeeper::put_Sound(long lSound)
    {
    if (MB_OK!=lSound && MB_ICONEXCLAMATION!=lSound
        && MB_ICONQUESTION!=lSound && MB_ICONHAND!=lSound
        && MB_ICONASTERISK!=lSound)
        {
        /*
         * We cannot return error information to the StdDispatch
         * given the way we've defined the return value of this
         * methods, so we can't raise an exception.
         */
        return;
        }

    m_lSound=lSound;
    return;
    }



/*
 * CBeeper::Beep
 *
 * Purpose:
 *  Function called from DispInvoke to invoke the Beep method.
 *
 * Return Value:
 *  long            The sound played.
 */

STDMETHODIMP_(long) CBeeper::Beep(void)
    {
    MessageBeep((UINT)m_lSound);
    return m_lSound;
    }




/*
 * Since CreateStdDispatch provides an IDispatch implementation
 * for us, there's no specific code for that interface needed here.
 *
 * So to not get rid of too much code, we'll add an
 * IProvideClassInfo
 */



/*
 * CImpIProvideClassInfo::CImpIProvideClassInfo
 * CImpIProvideClassInfo::~CImpIProvideClassInfo
 *
 * Parameters (Constructor):
 *  pUnkOuter       LPUNKNOWN of a controlling unknown.
 *  pITypeLib       ITypeLib * to return from this interface.
 */

CImpIProvideClassInfo::CImpIProvideClassInfo(LPUNKNOWN pUnkOuter
    , ITypeLib *pITypeLib)
    {
    m_cRef=0;
    m_pUnkOuter=pUnkOuter;

    /*
     * Get the coclass type info.  If this fails then we'll
     * just fail GetClassInfo below.
     */
    m_pITI=NULL;
    pITypeLib->GetTypeInfoOfGuid(CLSID_Beeper, &m_pITI);
    return;
    }


CImpIProvideClassInfo::~CImpIProvideClassInfo(void)
    {
    ReleaseInterface(m_pITI);
    return;
    }


/*
 * CImpIProvideClassInfo::QueryInterface
 * CImpIProvideClassInfo::AddRef
 * CImpIProvideClassInfo::Release
 *
 * Purpose:
 *  IUnknown members for CImpIProvideClassInfo object.
 */

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


STDMETHODIMP_(ULONG) CImpIProvideClassInfo::AddRef(void)
    {
    return m_pUnkOuter->AddRef();
    }


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




/*
 * CImpIProvideClassInfo::GetClassInfo
 *
 * Purpose:
 *  Returns the type information for this coclass.
 *
 * Parameters:
 *  ppITI           ITypeInfo ** in which to store the ITypeInfo
 *                  for this coclass.
 *
 * Return Value:
 *  HRESULT         NOERROR on success, error otherwise.
 */

STDMETHODIMP CImpIProvideClassInfo::GetClassInfo(ITypeInfo **ppITI)
    {
    if (NULL==ppITI)
        return ResultFromScode(E_POINTER);

    *ppITI=m_pITI;

    if (NULL!=m_pITI)
        {
        m_pITI->AddRef();
        return NOERROR;
        }

    return ResultFromScode(E_FAIL);
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -