示例#1
0
    /** \brief Provides the required behaviour of
     *  <code>IDispatch::Invoke()</code>, by invoking this method on the
     *  requisite dispinterface.
     *
     * This method operates by detecting the striping bit on the dispid,
     * from which the appropriate dispiniterface is determined. The
     * stripe is then removed, and the method invoked.
     *
     * \remarks Names are matched en bloc: they are either all matched by one
     *  interface, or all by the other. It is <b>never</b> the case that
     *  some part are matched by one and the remainder by the other.
     *
     * \note If no striping is apparent, the invocation is conducted on
     *  each interface in turn.
     */
    STDMETHOD(Invoke)(  DISPID      dispidMember
                    ,   REFIID      riid
                    ,   LCID        lcid
                    ,   WORD        wFlags
                    ,   DISPPARAMS  *pdispparams
                    ,   VARIANT     *pvarResult
                    ,   EXCEPINFO   *pexcepinfo
                    ,   UINT        *puArgErr)
    {
        if(dispidMember >= 0)
        {
            DISPID  dispidFlag  =   DISPID(0x1) << (8 * sizeof(DISPID) - 2);

            dispidFlag >>= 0;
            if(dispidMember & dispidFlag)
            {
                return dispatch_parent_0_type::Invoke(dispidMember & ~dispidFlag, riid, lcid, wFlags, pdispparams, pvarResult, pexcepinfo, puArgErr);
            }

            dispidFlag >>= 1;
            if(dispidMember & dispidFlag)
            {
                return dispatch_parent_1_type::Invoke(dispidMember & ~dispidFlag, riid, lcid, wFlags, pdispparams, pvarResult, pexcepinfo, puArgErr);
            }
        }
示例#2
0
//----------------------------------------------------------------------------
//
STDMETHODIMP CAnchoAddonService::browserActionNotification()
{
  for (BrowserActionCallbackMap::iterator it = m_BrowserActionCallbacks.begin(); it != m_BrowserActionCallbacks.end(); ++it) {
    it->second.Invoke0(DISPID(0));
  }
  return S_OK;
}
示例#3
0
    /** \brief Provides the required behaviour of
     *  <code>IDispatch::GetIDsOfNames()</code>, by querying the two
     *  dispinterfaces, in order, to match the name(s).
     *
     * This method operates by first determining which, if any, of the
     * two parent dispinterfaces can resolve the names. If successful, the
     * resultant dispatch Ids are then striped with a bit in their
     * most-significant byte(s) to record the index of the dispinterface
     * which has thus undertaken to interpret them. This stripe is then
     * detected
     *
     * \remarks Names are matched en bloc: they are either all matched by one
     *  interface, or all by the other. It is <b>never</b> the case that
     *  some part are matched by one and the remainder by the other.
     *
     * \note If a dispid returned from a successful call to one of the
     *  underlying dispinterfaces' <code>GetIDsOfNames()</code> already
     *  uses the striping bit, it is left alone. Such methods will be
     *  successfully called in Invoke(), in its post-stripe processing.
     */
    STDMETHOD(GetIDsOfNames)(   REFIID      riid
                            ,   LPOLESTR    *rgszNames
                            ,   UINT        cNames
                            ,   LCID        lcid
                            ,   DISPID      *rgdispid)
    {
        unsigned    index   =   1;
        HRESULT     hr      =   dispatch_parent_0_type::GetIDsOfNames(riid, rgszNames, cNames, lcid, rgdispid);

        if( FAILED(hr) &&
            DISP_E_UNKNOWNNAME == hr)
        {
            ++index;

            hr = dispatch_parent_1_type::GetIDsOfNames(riid, rgszNames, cNames, lcid, rgdispid);
        }

        // Encode interface info into the dispid
        if(SUCCEEDED(hr))
        {
            DISPID  dispidFlag  =   DISPID(0x1) << (8 * sizeof(DISPID) - 2);

            dispidFlag >>= (index - 1);

            for(UINT i = 0; i < cNames; ++i)
            {
                if(rgdispid[i] < 0)
                {
                    // Leave these alone. They'll be processed on a first-come-first-serve
                    // basis, which assumes that the GetIDsOfNames() and Invoke() of I0 and
                    // I1 are faithfully inter-related.
                }
                else
                {
                    ATLSTL_MESSAGE_ASSERT("Dispatch Id is out of range!", 0 == (dispidFlag & rgdispid[i]));

                    rgdispid[i] |= dispidFlag;
                }
            }
        }

        return hr;
    }