IDispatch接口要自己实现吗?请问如何实现,我看见MSDN代码是这样的:
STDMETHODIMP CDualCtlCtrl::X_DIDualCtlObj::Invoke(DISPID dispidMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS FAR* pdispparams,VARIANT FAR* pvarResult,EXCEPINFO FAR* pexcepinfo,UINT FAR* puArgErr) {METHOD_PROLOGUE(CDualCtlCtrl, _DIDualCtlObj)LPDISPATCH pDisp = pThis->GetIDispatch(FALSE);ASSERT(pDisp != NULL);return pDisp->Invoke(dispidMember,riid,lcid,wFlags,pdispparams,pvarResult,pexcepinfo,puArgErr);}那是基类里面已经实现好的,我想自己实现,请问该如何做.
STDMETHODIMP CDualCtlCtrl::X_DIDualCtlObj::Invoke(DISPID dispidMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS FAR* pdispparams,VARIANT FAR* pvarResult,EXCEPINFO FAR* pexcepinfo,UINT FAR* puArgErr) {METHOD_PROLOGUE(CDualCtlCtrl, _DIDualCtlObj)LPDISPATCH pDisp = pThis->GetIDispatch(FALSE);ASSERT(pDisp != NULL);return pDisp->Invoke(dispidMember,riid,lcid,wFlags,pdispparams,pvarResult,pexcepinfo,puArgErr);}那是基类里面已经实现好的,我想自己实现,请问该如何做.
2 LPDISPATCH pDisp = pThis->GetIDispatch(FALSE);pThis 可不是基类
但是我不知道Invoke实现的源代码啊,有没有哪位大哥给出IDispatch所有函数实现的源代码啊.
象ATL中Invoke是这样的。
IDispatchImpl::STDMETHOD(Invoke)(DISPID dispidMember, REFIID riid,
LCID lcid, WORD wFlags, DISPPARAMS* pdispparams, VARIANT* pvarResult,
EXCEPINFO* pexcepinfo, UINT* puArgErr)
{
return _tih.Invoke((IDispatch*)this, dispidMember, riid, lcid,
wFlags, pdispparams, pvarResult, pexcepinfo, puArgErr);
}
实际上Invoke由类型信息接口ITypeInfo的Invoke成员函数实现。
唯一可能需要自己实现的就是Invoke方法下面是我在实现WebBrowser包含器的时候实现用到的Invoke方法
//
// IDispatch Methods
//
STDMETHODIMP CWebHost::Invoke(DISPID dispidMember, REFIID riid,
LCID lcid, WORD wFlags,
DISPPARAMS* pDispParams,
VARIANT* pvarResult, EXCEPINFO* pExcepInfo,
UINT* puArgErr)
{
USES_CONVERSION; switch (dispidMember)
{
case DISPID_DBPATH:
{
CComBSTR bstrDBPath((LPCSTR)_Module.m_szRootPath);
bstrDBPath.Append("DATABASE");
CComBSTR bstrFunctionMember("TestFunc1");
CComVariant vaResult;
CComPtr<IDispatch> pDispScript;
CComPtr<IDispatch> pDispHTMLDocument;
CComQIPtr<IHTMLDocument2, &IID_IHTMLDocument2> pHtmlDoc2;
DISPID dispid;
DISPPARAMS dispparams;
EXCEPINFO excepInfo;
HRESULT hr;
UINT nArgErr; _ASSERT(m_spWebBrowser);
pvarResult->vt=VT_BSTR;
bstrDBPath.CopyTo(&pvarResult->bstrVal);
hr=m_spWebBrowser->get_Document(&pDispHTMLDocument);
if (FAILED(hr))
return hr;
pHtmlDoc2=pDispHTMLDocument;
if(pHtmlDoc2)
{
//嵌套触发脚本函数,实现类似事件回调效果
pHtmlDoc2->get_Script(&pDispScript);
hr=pDispScript->GetIDsOfNames(IID_NULL,&bstrFunctionMember,1,LOCALE_SYSTEM_DEFAULT,&dispid);
memset(&dispparams, 0, sizeof(dispparams));
dispparams.cArgs = 1;
dispparams.rgvarg = new VARIANT[dispparams.cArgs];
CComBSTR bstrParam("参数传入测试");
dispparams.rgvarg[0].vt = VT_BSTR;
bstrParam.CopyTo(&dispparams.rgvarg[0].bstrVal);
dispparams.cNamedArgs = 0;
memset(&excepInfo, 0, sizeof excepInfo);
nArgErr = (UINT)-1; // initialize to invalid arg
//此处开始正式调用脚本函数
hr = pDispScript->Invoke(dispid,IID_NULL,0,DISPATCH_METHOD,&dispparams,&vaResult,&excepInfo,&nArgErr);
}
break;
}
case DISPID_BEFORENAVIGATE2:
ATLTRACE("DISPID_BEFORENAVIGATE2\n");
break; case DISPID_DOCUMENTCOMPLETE:
ATLTRACE("DISPID_DOCUMENTCOMPLETE\n");
break; case DISPID_DOWNLOADBEGIN:
// Enable the stop menu item and toolbar button
EnableMenuItem(m_hMenu, ID_VIEW_STOP, MF_BYCOMMAND|MF_ENABLED);
m_wndToolBar.SendMessage(TB_ENABLEBUTTON, ID_VIEW_STOP, MAKELONG(TRUE, 0)); break; case DISPID_NAVIGATECOMPLETE:
{
// Set the text of the combobox to the current URL
CComBSTR bstrURL; m_spWebBrowser->get_LocationURL(&bstrURL);
m_wndUrlCombo.SetWindowText(OLE2T(bstrURL));
} break; case DISPID_DOWNLOADCOMPLETE:
// Disable the stop menu item and toolbar button
EnableMenuItem(m_hMenu, ID_VIEW_STOP, MF_BYCOMMAND|MF_GRAYED);
m_wndToolBar.SendMessage(TB_ENABLEBUTTON, ID_VIEW_STOP, MAKELONG(FALSE, 0)); break; //
// The parameters for this DISPID:
// [0]: New status bar text - VT_BSTR
//
case DISPID_STATUSTEXTCHANGE:
m_wndStatusBar.SetWindowText(OLE2T(pDispParams->rgvarg[0].bstrVal));
break; //
// The parameters for this DISPID:
// [0]: Document title - VT_BSTR
//
case DISPID_TITLECHANGE:
{
strstream strTitle; if (pDispParams->cArgs > 0 && pDispParams->rgvarg[0].vt == VT_BSTR)
{
strTitle << OLE2T(pDispParams->rgvarg[0].bstrVal);
strTitle << " - PowerFax";
}
else
{
strTitle << "PowerFax";
} strTitle << ends;
SetWindowText(strTitle.str());
} break; //
// DISPID for Download Control
//
case DISPID_AMBIENT_DLCONTROL:
{
CComVariant vtResult(static_cast<long>(m_dwDLControl));
*pvarResult = vtResult;
} break; default:
return DISP_E_MEMBERNOTFOUND;
} return S_OK;
}