即bho IDispatchEx ::调用失败

时间:2014-12-14 18:44:29

标签: c++ internet-explorer com atl bho

美好的一天,我对Internet Explorer的浏览器帮助对象有问题。我需要从页面中注入js代码回调我的c ++代码,所以我必须将一些c ++方法导出到js代码。我通过IDispatchEx::Invoke找到了方法,但是这种方法在某些网站上一直都失败了。

void __stdcall CEventSink::DocumentComplete(IDispatch *pObject, VARIANT *pvarUrl)
{
    if(pObject)
    {
        IServiceProvider *pSp = NULL;
        if(SUCCEEDED(pObject->QueryInterface(IID_IServiceProvider, (void**)&pSp)))
        {
            IWebBrowser2 *browser = NULL;
            if(SUCCEEDED(pObject->QueryInterface(IID_IWebBrowser2, (void**)&browser)))
            {
            IDispatch *disp = NULL;
            if(SUCCEEDED(browser->get_Document(&disp)))
            {
                IHTMLDocument2 *doc = NULL;
                if(SUCCEEDED(disp->QueryInterface(IID_IHTMLDocument2, (void**)&doc)))
                {
                    IHTMLWindow2 *w = NULL;
                    if(SUCCEEDED(doc->get_parentWindow(&w)))
                    {
                        CComPtr<IDispatchEx> dispxWnd;
                        if(local_data.tabs[(ptr_type)browser].bho)
                        {
                            if(SUCCEEDED(w->QueryInterface( &dispxWnd )))
                            {
                                CComBSTR propName( L"cbx" );
                                DISPID dispid;
                                if(SUCCEEDED ( dispxWnd->GetDispID( propName, fdexNameEnsure, &dispid )))
                                {
                                    CComVariant varMyBho( (IDispatch*)local_data.tabs[(ptr_type)browser].bho );
                                    DISPID dummy[] = {DISPID_PROPERTYPUT};
                                    DISPPARAMS params;
                                    params.cArgs = 1;
                                    params.cNamedArgs = 0;
                                    params.rgvarg = &varMyBho;
                                    params.rgdispidNamedArgs = NULL;
                                    if(FAILED( dispxWnd->Invoke( dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUTREF, &params, NULL, NULL, NULL )))
                                    {
                                        MessageBoxA(NULL, "failed to dispxWnd->Invoke", "", MB_OK);
                                        //TODO: handle error
                                    }
                                }

它未能通过电话if(FAILED( dispxWnd->Invoke( dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUTREF, &params, NULL, NULL, NULL ))),但仅限于某些网站,例如tee-links.com。 local_data.tabs[(ptr_type)browser].bho存储指向具有已实现接口的类实例的指针。正如第一条评论所建议的,我已经添加了一些代码来检索有关错误,快速和脏的一些信息

HRESULT hr = dispxWnd->Invoke( dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUTREF, &params, NULL, NULL, NULL );
                                                if(FAILED(hr))
                                                {
                                                    _com_error err(hr);
                                                    LPCTSTR msg = err.ErrorMessage();
                                                    char errnum[32];
                                                    _snprintf(errnum, 31, "%x", hr);
                                                    MessageBox(NULL, msg, to_utf16(errnum).c_str(), MB_OK);

所以我们有错误信息,例如&#34;未找到组成员&#34;,我安装了俄语操作系统,因此无法准确说出,错误代码80020003

1 个答案:

答案 0 :(得分:0)

您正在获得IDispatchEx::GetDispID的动态DISPID,它应该与IDispatchEx::InvokeEx一起使用,但是您将它提供给IDispatch::Invoke,它应该与静态一起使用由IDIspatch::GetIDsOfNames返回的DISPID。


PS:我也发现以下一行有趣:

CComVariant varMyBho( (IDispatch*)local_data.tabs[(ptr_type)browser].bho );

这些真的都是IDispatch指针吗?或者他们是IUnknown指针?如果是后者,则必须QueryInterface