/** \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); } }
//---------------------------------------------------------------------------- // STDMETHODIMP CAnchoAddonService::browserActionNotification() { for (BrowserActionCallbackMap::iterator it = m_BrowserActionCallbacks.begin(); it != m_BrowserActionCallbacks.end(); ++it) { it->second.Invoke0(DISPID(0)); } return S_OK; }
/** \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; }