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

📄 beeper.cpp

📁 英文版的 想要的话可以下载了 为大家服务
💻 CPP
📖 第 1 页 / 共 2 页
字号:

        WideCharToMultiByte(CP_ACP, 0, rgszNames[0], -1
            , szTemp, 80, NULL, NULL);
        if (0==lstrcmpi(psz, szTemp))
       #else
        if (0==lstrcmpi(psz, rgszNames[0]))
       #endif
            {
            //Found a match, return the DISPID
            rgDispID[0]=i;
            hr=NOERROR;
            break;
            }
        }

    return hr;
    }





/*
 * CImpIDispatch::Invoke
 *
 * Purpose:
 *  Calls a method in the dispatch interface or manipulates a
 *  property.
 *
 * Parameters:
 *  dispID          DISPID of the method or property of interest.
 *  riid            REFIID reserved, must be IID_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 dispID, REFIID riid
    , LCID lcid, unsigned short wFlags, DISPPARAMS *pDispParams
    , VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
    {
    HRESULT     hr;

    //riid is supposed to be IID_NULL always
    if (IID_NULL!=riid)
        return ResultFromScode(DISP_E_UNKNOWNINTERFACE);

    /*
     * There is nothing locale-sensitive in any of our properties
     * or methods.  Some automation objects may have currency,
     * date/time, or string values in properties or methods which
     * would be sensitive to lcid; be sure the handle them properly.
     */


    /*
     * Process the invoked member or property.  For members,
     * call whatever functions are necessary to carry out the
     * action.  For properties, either return the value you have
     * or change it according to wFlags.
     *
     * This object supports one property and one method:
     *  ID 0    "Sound" property, a long that must be one of
     *          MB_OK, MB_ICONHAND, MB_ICONQUESTION,
     *          MB_ICONEXCLAMATION, and MB_ICONASTERISK.
     *  ID 1    "Beep" method, no parameters, return value of type
     *          long which is the sound that was played.
     *
     * Note that the IDs are assigned in the implementation of
     * IDispatch::GetIDsOfNames.
     */

    switch (dispID)
        {
        case PROPERTY_SOUND:
            /*
             * Some controllers might not be able to differentiate
             * between a property get and a function call, so we
             * have to handle both as a property get here.
             */
            if (DISPATCH_PROPERTYGET & wFlags
                || DISPATCH_METHOD & wFlags)
                {
                //Make sure we have a place for the result
                if (NULL==pVarResult)
                    return ResultFromScode(E_INVALIDARG);

                VariantInit(pVarResult);
                V_VT(pVarResult)=VT_I4;
                V_I4(pVarResult)=m_pObj->m_lSound;
                return NOERROR;
                }
            else
                {
                //DISPATCH_PROPERTYPUT
                long        lSound;
                int         c;
                VARIANT     vt;

                //Validate parameter count
                if (1!=pDispParams->cArgs)
                    return ResultFromScode(DISP_E_BADPARAMCOUNT);

                //Check that we have a named DISPID_PROPERTYPUT
                c=pDispParams->cNamedArgs;
                if (1!=c || (1==c && DISPID_PROPERTYPUT
                    !=pDispParams->rgdispidNamedArgs[0]))
                    return ResultFromScode(DISP_E_PARAMNOTOPTIONAL);

                /*
                 * Try to coerce the new property value into a
                 * type VT_I4.  VariantChangeType will do this for
                 * us and return an appropriate error code if the
                 * type cannot be coerced.  On error we store 0
                 * (first parameter) into puArgErr.
                 *
                 * We could also use DispGetParam here to do the
                 * same thing:
                 *   DispGetParam(pDispParams, 0, VT_I4
                 *       , &vtNew, puArgErr);
                 */
                VariantInit(&vt);
                hr=VariantChangeType(&vt, &pDispParams->rgvarg[0]
                    , 0, VT_I4);

                if (FAILED(hr))
                    {
                    if (NULL!=puArgErr)
                        *puArgErr=0;

                    return hr;
                    }

                //With the right type, now check the right value
                lSound=vt.lVal;

                if (MB_OK!=lSound && MB_ICONEXCLAMATION!=lSound
                    && MB_ICONQUESTION!=lSound && MB_ICONHAND!=lSound
                    && MB_ICONASTERISK!=lSound)
                    {
                    if (NULL==pExcepInfo)
                        return ResultFromScode(E_INVALIDARG);

                    /*
                     * This is the right place for an exception--
                     * the best we can tell the caller with a
                     * return value is something like E_INVALIDARG.
                     * But that doesn't at all indiate the problem.
                     * So we use EXCEPTION_INVALIDSOUND and the
                     * FillException callback to fill the EXCEPINFO.
                     *
                     * Note:  DispTest and Visual Basic 3 don't
                     * support deferred filling of the EXCEPINFO
                     * structure; Visual Basic 4 does.  Even if you
                     * don't use deferred filling, a separate
                     * function is still useful as you can just call
                     * it here to fill the structure immediately.
                     *
                     * Deferred fill-in code would appear:
                     *
                     *   INITEXCEPINFO(*pExcepInfo);
                     *   pExcepInfo->scode
                     *       =(SCODE)MAKELONG(EXCEPTION_INVALIDSOUND
                     *       , PRIMARYLANGID(lcid));
                     *   pExcepInfo->pfnDeferredFillIn=FillException;
                     */

                    /*
                     * So we can make a localized exception, we'll
                     * store the language ID and our exception code
                     * into the scode field; in FillException we move
                     * the code into wCode and clear scode.  Otherwise
                     * there's no way to tell FillException about
                     * the locale.
                     */

                    pExcepInfo->scode
                        =(SCODE)MAKELONG(EXCEPTION_INVALIDSOUND
                        , PRIMARYLANGID(lcid));
                    FillException(pExcepInfo);
                    return ResultFromScode(DISP_E_EXCEPTION);
                    }

                //Everything checks out:  save the new value
                m_pObj->m_lSound=lSound;
                }

            break;


        case METHOD_BEEP:
            if (!(DISPATCH_METHOD & wFlags))
                return ResultFromScode(DISP_E_MEMBERNOTFOUND);

            if (0!=pDispParams->cArgs)
                return ResultFromScode(DISP_E_BADPARAMCOUNT);

            MessageBeep((UINT)m_pObj->m_lSound);

            //The result of this method is the sound we played
            if (NULL!=pVarResult)
                {
                VariantInit(pVarResult);
                V_VT(pVarResult)=VT_I4;
                V_I4(pVarResult)=m_pObj->m_lSound;
                }

            break;

        default:
            return ResultFromScode(DISP_E_MEMBERNOTFOUND);
        }

    return NOERROR;
    }




/*
 * FillException
 *
 * Purpose:
 *  Callback function pointed to in IDispatch::Invoke that fills
 *  an EXCEPINFO structure based on the code stored inside
 *  Invoke.  This is a nice mechanism to keep all the management
 *  of error code strings and help IDs centralized in one place,
 *  even across many different automation objects within the same
 *  application.  It also keeps Invoke cleaner.
 *
 * Parameters:
 *  pExcepInfo      EXCEPINFO * to fill.
 *
 * Return Value:
 *  HRESULT         NOERROR if successful, error code otherwise.
 */

HRESULT STDAPICALLTYPE FillException(EXCEPINFO *pExcepInfo)
    {
    SCODE       scode;
    LANGID      langID;
    USHORT      wCode;
    HRESULT     hr;
    LPTSTR      psz;
    LPOLESTR    pszHelp;
    UINT        idsSource;
    UINT        idsException;

    if (NULL==pExcepInfo)
        return ResultFromScode(E_INVALIDARG);

    /*
     * Parts of our implementation that raise exceptions put the
     * WORD exception code in the loword of scode and the LANGID
     * in the hiword.
     */
    scode=pExcepInfo->scode;
    langID=HIWORD(scode);
    wCode=LOWORD(scode);

    //Allocate BSTRs for source and description strings
    psz=(LPTSTR)malloc(1024*sizeof(TCHAR));

    if (NULL==psz)
        return ResultFromScode(E_OUTOFMEMORY);

    hr=NOERROR;

    switch (wCode)
        {
        case EXCEPTION_INVALIDSOUND:
            //Fill in unused information, macro in inole.h
            INITEXCEPINFO(*pExcepInfo);
            pExcepInfo->wCode=wCode;

            /*
             * DispTest and Visual Basic 3 ignore the help file and
             * context ID.  A complete controller such as Visual
             * Basic 4 checks if these fields are set, and if so,
             * displays a Help button in a message box.  If Help
             * is pressed, the controller calls WinHelp with this
             * filename and context ID for complete integration.
             *
             * The sources for beeper.hlp are in
             * \inole\chap14\beephelp along with the actual help
             * file.  For this sample I assume it's on C drive.
             * Normally you'll want to read your own HELPDIR
             * registry entry from under TypeLib and prepend that
             * to the name of the help file, but since this sample
             * doesn't have a type library, that entry doesn't
             * exist so I just hard-code it.
             */
            pExcepInfo->dwHelpContext=HID_SOUND_PROPERTY_LIMITATIONS;

            //Set defaults
            pszHelp=OLETEXT("c:\\inole\\chap14\\beephelp\\beep0000.hlp");
            idsSource=IDS_0_EXCEPTIONSOURCE;
            idsException=IDS_0_EXCEPTIONINVALIDSOUND;

            //Get the localized source and exception strings
            switch (langID)
                {
                case LANG_GERMAN:
                    idsSource=IDS_7_EXCEPTIONSOURCE;
                    idsException=IDS_7_EXCEPTIONINVALIDSOUND;
                    pszHelp=OLETEXT("c:\\inole\\chap14\\beephelp\\beep0007.hlp");
                    break;

                case LANG_ENGLISH:
                case LANG_NEUTRAL:
                default:
                    break;
                }

            break;

        default:
            hr=ResultFromScode(E_FAIL);
        }

    if (SUCCEEDED(hr))
        {
        pExcepInfo->bstrHelpFile=SysAllocString(pszHelp);

       #ifdef WIN32ANSI
        OLECHAR     szTemp[256];

        LoadString(g_hInst, idsSource, psz, 256);
        MultiByteToWideChar(CP_ACP, 0, psz, -1, szTemp, 256);
        pExcepInfo->bstrSource=SysAllocString(szTemp);

        LoadString(g_hInst, idsException, psz, 256);
        MultiByteToWideChar(CP_ACP, 0, psz, -1, szTemp, 256);
        pExcepInfo->bstrDescription=SysAllocString(szTemp);
       #else
        LoadString(g_hInst, idsSource, psz, 1024);
        pExcepInfo->bstrSource=SysAllocString(psz);
        LoadString(g_hInst, idsException, psz, 1024);
        pExcepInfo->bstrDescription=SysAllocString(psz);
       #endif
        }

    free(psz);
    return hr;
    }

⌨️ 快捷键说明

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