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

📄 beeper.cpp

📁 英文版的 想要的话可以下载了 为大家服务
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*
 * BEEPER.CPP
 * Beeper Automation Object #1 Chapter 14
 *
 * Implementation of the CBeeper class which demonstrate a fully
 * custom IDispatch implementation that only supports mapping of
 * names to IDs through IDispatch::GetIDsOfNames.
 *
 * Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
 *
 * Kraig Brockschmidt, Microsoft
 * Internet  :  kraigb@microsoft.com
 * Compuserve:  >INTERNET:kraigb@microsoft.com
 */


#include "beeper.h"

extern HINSTANCE g_hInst;


/*
 * 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_pImpIDispatch=NULL;
    return;
    }


CBeeper::~CBeeper(void)
    {
    if (NULL==m_pszScratch)
        free(m_pszScratch);

    DeleteInterfaceImp(m_pImpIDispatch);
    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;

    if (NULL!=m_pUnkOuter)
        pIUnknown=m_pUnkOuter;

    m_pImpIDispatch=new CImpIDispatch(this, pIUnknown);

    if (NULL==m_pImpIDispatch)
        return FALSE;

    //Pre-allocate scratch space for IDispatch::GetIDsOfNames
    m_pszScratch=(LPTSTR)malloc(256*sizeof(TCHAR));

    if (NULL==m_pszScratch)
        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)
        *ppv=this;

    /*
     * QueryInterface must respond not only to IID_IDispatch for
     * the primary automation interface, but also to the DIID of the
     * dispinterface itself, which in our case is DIID_DIBeeper.
     */

    if (IID_IDispatch==riid || DIID_DIBeeper==riid)
        *ppv=m_pImpIDispatch;

    //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;
    }



//IDispatch interface implementation

/*
 * CImpIDispatch::CImpIDispatch
 * CImpIDispatch::~CImpIDispatch
 *
 * Parameters (Constructor):
 *  pObj            PCBeeper of the object we're in.
 *  pUnkOuter       LPUNKNOWN to which we delegate.
 */

CImpIDispatch::CImpIDispatch(PCBeeper pObj, LPUNKNOWN pUnkOuter)
    {
    m_cRef=0;
    m_pObj=pObj;
    m_pUnkOuter=pUnkOuter;
    return;
    }

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



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

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
 *
 * Purpose:
 *  Returns the number of type information (ITypeInfo) interfaces
 *  that the object provides (0 or 1).
 *
 * Parameters:
 *  pctInfo         UINT * to the location to receive
 *                  the count of interfaces.
 *
 * Return Value:
 *  HRESULT         NOERROR or a general error code.
 */

STDMETHODIMP CImpIDispatch::GetTypeInfoCount(UINT *pctInfo)
    {
    //We don't implement GetTypeInfo, so return 0
    *pctInfo=0;
    return NOERROR;
    }




/*
 * CImpIDispatch::GetTypeInfo
 *
 * Purpose:
 *  Retrieves type information for the automation interface.
 *
 * Parameters:
 *  itinfo          UINT reserved.  Must be zero.
 *  lcid            LCID providing the locale for the type
 *                  information.  If the object does not support
 *                  localization, this is ignored.
 *  pptinfo         ITypeInfo ** in which to store the ITypeInfo
 *                  interface for the object.
 *
 * Return Value:
 *  HRESULT         NOERROR or a general error code.
 */

STDMETHODIMP CImpIDispatch::GetTypeInfo(UINT itinfo, LCID lcid
    , ITypeInfo **pptInfo)
    {
    /*
     * Since we returned zero from GetTypeInfoCount, this function
     * should not be called.  If it is, be sure to NULL the pptInfo
     * pointer according to normal out-parameter rules.
     */
    *pptInfo=NULL;
    return ResultFromScode(E_NOTIMPL);
    }




/*
 * CImpIDispatch::GetIDsOfNames
 *
 * Purpose:
 *  Converts text names into DISPIDs to pass to Invoke
 *
 * Parameters:
 *  riid            REFIID reserved.  Must be IID_NULL.
 *  rgszNames       OLECHAR ** pointing to the array of names to be
 *                  mapped.
 *  cNames          UINT number of names to be mapped.
 *  lcid            LCID of the locale.
 *  rgDispID        DISPID * caller allocated array containing IDs
 *                  corresponging to those names in rgszNames.
 *
 * Return Value:
 *  HRESULT         NOERROR or a general error code.
 */

STDMETHODIMP CImpIDispatch::GetIDsOfNames(REFIID riid
    , OLECHAR **rgszNames, UINT cNames, LCID lcid, DISPID *rgDispID)
    {
    HRESULT     hr;
    int         i;
    int         idsMin;
    LPTSTR      psz;

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

    /*
     * This function will support English and German languages,
     * where in English we have a "Sound" property and "Beep"
     * method; in German these are "Ton" and "Peip" This particular
     * coding will handle either language identically, so a
     * controller using even both languages simultaneously can work
     * with this same automation object.
     *
     * To check the passed LCID, we use the PRIMARYLANGID macro
     * to check for LANG_ENGLISH and LANG_GERMAN, which means we
     * support any dialect of english (US, UK, AUS, CAN, NZ, EIRE)
     * and german (GER, SWISS, AUS).  The high byte of an LCID
     * specifies the sub-language, and the macro here strips that
     * differentiation.
     *
     * Note that LANG_NEUTRAL is considered here to be English.
     */

    //Set up idsMin to the right stringtable in our resources
    switch (PRIMARYLANGID(lcid))
        {
        case LANG_NEUTRAL:
        case LANG_ENGLISH:
            idsMin=IDS_0_NAMESMIN;
            break;

        case LANG_GERMAN:
            idsMin=IDS_7_NAMESMIN;
            break;

        default:
            return ResultFromScode(DISP_E_UNKNOWNLCID);
        }

    /*
     * The index in this loop happens to correspond to the DISPIDs
     * for each element which also matches the stringtable entry
     * ordering, where i+idsMin is the string to compare.  If we
     * find a match, i is the DISPID to return.
     */
    rgDispID[0]=DISPID_UNKNOWN;
    hr=ResultFromScode(DISP_E_UNKNOWNNAME);

    psz=m_pObj->m_pszScratch;

    for (i=0; i < CNAMES; i++)
        {
        /*
         * If we had more than one name per method or property,
         * we'd need to loop over the cNames parameter as well.
         */

        LoadString(g_hInst, idsMin+i, psz, 256);

       #ifdef WIN32ANSI
        char        szTemp[80];

⌨️ 快捷键说明

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