本帖最后由 OneOnce 于 2011-03-29 11:31:40 编辑

解决方案 »

  1.   

    实现IDispath接口的Invoke方法,实现这个DISPID_FILEDOWNLOAD
      

  2.   


    没用过这个东西,而且还是第一次做MFC程序,能否指点一下啊~O(∩_∩)O~
      

  3.   

    我现在知道做一个简单的COM组件加法方法,但是Invoke方法的调用和加法的调用是一样的吗?
      

  4.   

    添加Invoke方法是不是右键-->Add Method但是那些参数是输入,那些是输出,那些是输入输出?大家多多指点~
      

  5.   

    Implementing   a   Custom   Download   Manager   
    http://msdn.microsoft.com/workshop/browser/ext/overview/downloadmgr.asp http://support.microsoft.com/kb/181678
      

  6.   

    首先写一个派生于IDispatch的类class AboutWebEvent : public IDispatch
    {
    public:
    AboutWebEvent():m_dwRef(1)
    {};
    public:
    ~AboutWebEvent(){};    DWORD m_dwRef;
    // IUnknown
        STDMETHOD(QueryInterface)(const struct _GUID &riid,void ** ppv){
            *ppv = NULL;        if (IID_IUnknown == riid)
            {
                *ppv = (LPUNKNOWN)this;
                AddRef();
                return NOERROR;
            }
            else if (IID_IDispatch == riid)
            {
                *ppv = (IDispatch*)this;
                AddRef();
                return NOERROR;
            }
            else
            {
                return E_NOTIMPL;
            }
        }
        ULONG __stdcall AddRef(void){
            return ++m_dwRef;
        }
        ULONG __stdcall Release(void){
            if (--m_dwRef == 0) 
            { 
                delete this; 
                return 0; 
            }
            return m_dwRef;
        }
    // IDispatch
        STDMETHOD(GetTypeInfoCount)(unsigned int *){
            TRACE("GetTypeInfoCount\n"); return E_NOTIMPL;
        }
        STDMETHOD(GetTypeInfo)(unsigned int,unsigned long,struct ITypeInfo ** ){
            TRACE("GetTypeInfo\n"); return E_NOTIMPL;
        }
        STDMETHOD(GetIDsOfNames)(const IID &,LPOLESTR *,UINT,LCID,DISPID *){
            TRACE("GetIDsOfNames\n"); return E_NOTIMPL;
        }

        STDMETHOD(Invoke)(DISPID dispID,const struct _GUID &,unsigned long,unsigned short,struct tagDISPPARAMS * pParams,struct tagVARIANT *,struct tagEXCEPINFO *,unsigned int *)
        {

    TRACE("进入Invoke--1\n"); 
    if(dispID == 0)
    {
    ::AfxMessageBox("dispID等于0");
    }
    if(dispID ==DISPID_FILEDOWNLOAD)
                    {
                     ..................
                    }
          }
      

  7.   

    没有这个DISPID_FILEDOWNLOAD东西啊,找不到在哪里定义的。
      

  8.   

        ICtrlDownload : public IDispatch
        {
        public:
            virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Invoke( 
                /* [in] */ DISPID dispidMember,
                /* [in] */ REFIID riid,
                /* [in] */ LCID lcid,
                /* [in] */ WORD wFlags,
                /* [out][in] */ DISPPARAMS *pDispParams,
                /* [out][in] */ VARIANT *pvarResult,
                /* [out][in] */ EXCEPINFO *pExcepInfo,
                /* [out][in] */ UINT *puArgErr) = 0;
            
        };我也有个类ICtrlDownload派生于IDispatch啊,但是只有一个Invoke,还是我通过右键-->Add Method自动生成的。没有你那么东西啊!
      

  9.   

    好像是IDownloadManager接口吧
      

  10.   


    你最好实现完全了,只有Invoke肯定是不完整的,建议你去看一下COM技术里面的事件连接点这些东东
      

  11.   

    直接MFC应用程序就行
    #include <mshtml.h>
    #include <atlbase.h>
    #include "atlcom.h"
    #include <mshtmdid.h>
    #include <oleacc.h>
    #include <atlconv.h>
      

  12.   

    DISPID_FILEDOWNLOAD定义是多少啊?还有个问题Invoke需要去调用吗?还是自动回去调用?
      

  13.   


    怎么去调用Invoke啊~不知道怎么下手...
      

  14.   

    我给你一个示例吧,功能是用事件连接点获取网页表单的submit(提交表单)消息
    首先写一个基于IDispatch的类:(这个类是一个事件接受器,根据实际接收到的事件做自己想要的处理,主要在Invlke函数里面实现)class AboutWebEvent : public IDispatch
    {
    public:
    AboutWebEvent():m_dwRef(1)
    {};
    public:
    ~AboutWebEvent(){};    DWORD m_dwRef;
    // IUnknown
        STDMETHOD(QueryInterface)(const struct _GUID &riid,void ** ppv){
            *ppv = NULL;        if (IID_IUnknown == riid)
            {
                *ppv = (LPUNKNOWN)this;
                AddRef();
                return NOERROR;
            }
            else if (IID_IDispatch == riid)
            {
                *ppv = (IDispatch*)this;
                AddRef();
                return NOERROR;
            }
            else
            {
                return E_NOTIMPL;
            }
        }
        ULONG __stdcall AddRef(void){
            return ++m_dwRef;
        }
        ULONG __stdcall Release(void){
            if (--m_dwRef == 0) 
            { 
                delete this; 
                return 0; 
            }
            return m_dwRef;
        }
    // IDispatch
        STDMETHOD(GetTypeInfoCount)(unsigned int *){
            TRACE("GetTypeInfoCount\n"); return E_NOTIMPL;
        }
        STDMETHOD(GetTypeInfo)(unsigned int,unsigned long,struct ITypeInfo ** ){
            TRACE("GetTypeInfo\n"); return E_NOTIMPL;
        }
        STDMETHOD(GetIDsOfNames)(const IID &,LPOLESTR *,UINT,LCID,DISPID *){
            TRACE("GetIDsOfNames\n"); return E_NOTIMPL;
        }

        STDMETHOD(Invoke)(DISPID dispID,const struct _GUID &,unsigned long,unsigned short,struct tagDISPPARAMS * pParams,struct tagVARIANT *,struct tagEXCEPINFO *,unsigned int *)
        {

    TRACE("进入Invoke--1\n"); 
    if(dispID == 0)
    {
    ::AfxMessageBox("dispID等于0");
    }
    if(dispID ==DISPID_HTMLFORMELEMENTEVENTS2_ONSUBMIT )
    {
                      ...................
                      ...................
                    }
    }
    其次,要把网页中的表单接口转化为事件连接点的接口,比如说提交表单消息事件(DISPID_HTMLFORMELEMENTEVENTS2_ONSUBMIT)属于DIID_HTMLFormElementEvents2事件集中的一个,要用到FindConnectionPoint函数(根据函数名你就知道啥意思了)AboutWebEvent pAboutWebEvent;//声明接收器对象
    CComQIPtr<IUnknown, &IID_IUnknown> spUnk = &pAboutWebEvent; IConnectionPointContainer* pCPC = NULL;
    IConnectionPoint* pCP = NULL;
    DWORD pdwCookie = NULL;
    hr=spFormElement->QueryInterface( IID_IConnectionPointContainer,(void**)&pCPC ); //spFormElement是已经获取的网页中的表单指针
    if ( hr == S_OK )
    {
            hr = pCPC->FindConnectionPoint(DIID_HTMLFormElementEvents2,&pCP);
    if ( hr == S_OK )
    {
    HRESULT hr1; hr1 = pCP->Advise(spUnk,&pdwCookie);
    if ( FAILED( hr1 ) )    ::AfxMessageBox("Advise调用失败");
                    TRACE("Advise调用成功");
    Invoke();   }
    pCPC->Release();
           }这样就可以进入Invoke中了,根据你的IDownloadManager接口,用FindConnectionPoint转一下,再看看有DISPID_FILEDOWNLOAD这个事件消息不
      

  15.   

    那个事件接收器类不必重新写一个单独的类,直接写在主程序的.cpp文件中就行,当然,你重新写一个单独的类也行
    另外,看看这篇文章吧http://zhenry86.blog.163.com/blog/static/7567665820088283838757/
      

  16.   

    你用的是webbrowser这个COM组建做的吗?那你实现它dispatch接口里的invoke应该就可以了,DISPID_FILEDOWNLOAD这个事件可能在vs2003下没有直接给出,vs2008就有了,不过你可以直接把这宏定义的值拿过来用就好了