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);}那是基类里面已经实现好的,我想自己实现,请问该如何做.

解决方案 »

  1.   

    1 CDualCtlCtrl::X_DIDualCtlObj不是IDispatch的实现
    2 LPDISPATCH pDisp = pThis->GetIDispatch(FALSE);pThis 可不是基类
      

  2.   

    STDMETHODIMP CDualCtlCtrl::X_DIDualCtlObj::Invoke()这可是IDispatch的Invoke函数的实现啊,pThis我知道是其外部类的指针.
    但是我不知道Invoke实现的源代码啊,有没有哪位大哥给出IDispatch所有函数实现的源代码啊.
      

  3.   

    不需要,对于MFC中,CCmdTarget以经封装实现了IDispatch;ATL有IDispatchImpl。
    象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成员函数实现。
      

  4.   

    在atl中使用IDispatchImpl之后通常没必要自己实现IDispatch接口的所有方法.
    唯一可能需要自己实现的就是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;
    }
      

  5.   

    完全不需要,可以借助ITypeLib来完成.