在IDispatchEx :: GetDispID()中获取RPC_E_SYS_CALL_FAILED以获取一个进程外IDispatch指针

时间:2012-10-17 23:50:52

标签: atl

我遇到了一个问题,我很确定这个论坛能够为我提供帮助。

我正在尝试向脚本添加一些自动化对象(通过单独的进程(ATL EXE服务器)托管)。 此外,我正在尝试从ATL EXE脚本引擎中的这些自动化对象中提取事件。

要实现这一点,我正在使用http://www.codeproject.com/Articles/3326/Extending-the-Internet-Explorer-Scripting-Engine中所述的CDispExSinkConnector 如上所述,我正在使用IDispatchEx :: GetDispID()在脚本引擎中创建新成员。一旦创建了成员DISPID,我就使用InvokeEx()来设置属性值。 但是这些方法调用返回RPC_E_SYS_CALL_FAILED。

注意 - 这里我从OUT-OF-PROC IDispatch指针获取IDispEx指针。

更详细的说明: 我在ATL EXE服务器上有一个由CAxWindow托管的BrowserCtrl,我用它为我的MFC客户端应用程序创建HTML插件。 ATL EXE服务器为IWebBrowser2方法提供包装器方法,以便我可以调用类似IWebBrowser2Ptr-> Navigate2()的方法。

此外,我可以在此ATL EXE服务器中订阅像OnDocumentComplete(...。)这样的IWebBrowser2事件,并最终将这些事件转发到我的MFC客户端应用程序来处理那些事件。 以下是我的ATL EXE服务器(BrowserCtrl)的几个代码片段:

第一个是CreateControl(),它创建CAxWindow,创建WebBrowser控件并在内部默认CAxHostWindow上托管控件。

STDMETHODIMP BrowserCtrl::CreateControl(ULONG hwndParent, LONG left,LONG top, LONG right, LONG bottom)
{
  CRect rc(left, top, right, bottom);

  // Create the AX host window. m_wndBrowserCtrl is CAxWindow object
HWND hwndAxHost = m_wndBrowserCtrl.Create(reinterpret_cast<HWND>(hwndParent), &rc, L"Shell.Explorer", WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,  0, ID_BROWSERCTRL );

  //Obtain a pointer to the container object
  CComQIPtr<IAxWinHostWindow> ptrWinHost;
  HRESULT hr = m_wndBrowserCtrl.QueryHost(&ptrWinHost);


  LPOLESTR lpszCLSID = NULL;
  hr = StringFromCLSID(CLSID_WebBrowser, &lpszCLSID);


  // Create the WebBrowser Ctrl
  CComPtr<IUnknown> cpIUnknown = NULL;
hr = ptrWinHost->CreateControlEx(lpszCLSID, m_wndBrowserCtrl, NULL, &cpIUnknown, __uuidof(SHDocVw::DWebBrowserEvents2), reinterpret_cast<IUnknown*>(reinterpret_cast<DWebBrowserEvents2Impl*>(this)));

// Get the IWebBrowser2 interface pointer for the control
// CComQIPtr<IWebBrowser2> m_cpIBrowser;
  m_cpIBrowser = cpIUnknown;
  return S_OK;
}

//现在是IWebBrowser2方法的包装器方法

STDMETHODIMP BrowserCtrl::Navigate2(VARIANT *pwszUrl, VARIANT *Flags, VARIANT *TargetFrameName, VARIANT *PostData, VARIANT *Headers)
{
  HRESULT hr = m_cpIBrowser->Navigate2(pwszUrl, Flags,TargetFrameName,PostData,Headers);
}

//现在是IWebBrowser2事件的事件处理程序:

void __stdcall BrowserCtrl::OnDocumentComplete(IDispatch* pDisp, VARIANT* pvaURL)
{
Fire_OnDocumentComplete(pDisp , pvaURL);// forwarding to the MGC client APP

}

现在问题:

1.在MFC客户端APP和事件处理函数OnDocumentComplete()中,我执行以下操作:

 void MFCClientApp::HandleDocumentComplete(LPDISPATCH pIDisp, VARIANT* pvaURL)
    {
      CComPtr<IDispatch> pDispDoc;
      CComQIPtr<IDispatch> pScriptDisp;
      CComQIPtr<IDispatchEx> pDispEx;
      CComQIPtr<IHTMLDocument> pHTMLDoc;
      CComQIPtr<IWebBrowser2> pWebBrowser;

    if (pIDisp != NULL)
          {
            pWebBrowser = pIDisp;
            //CComPtr<IDispatch> ptrIDisp;
            //BOOL bResult = GetOPBrowser()->GetDisp(&ptrIDisp);
            //pWebBrowser = ptrIDisp;
            pWebBrowser->get_Document(&pDispDoc);

            if (pDispDoc != NULL)
            {
              // Get the IDispatchEx interface
              pHTMLDoc = pDispDoc;
              if (pHTMLDoc != NULL)
              {
                pHTMLDoc->get_Script(&pScriptDisp);
                pDispEx = pScriptDisp;

                if (pDispEx != NULL)
                {
                         CDispExSinkConnector pDispExSinkConnector = new CDispExSinkConnector();
    Hr = pDispExSinkConnector->SetDispEx(pDispEx); // here the Hr returned is 0x80010100  “System Call Failed” i.e. RPC_E_SYS_CALL_FAILED
    ……
    ……..
    ………
    }

这是SetDispEx()和内部相关函数:

void CDispExSinkConnector::SetDispEx(IDispatchEx *pDispEx)
{
       CComBSTR bstrThisGuid("AC0B188C-6B55-408f-9E8C-821B9B5467CB"); // @!I8NIGNORE

       HRESULT hr = m_pDispExGIT.Attach(pDispEx);//add it to the GIT Table
       ASSERT(pDispEx);
       // We need to add ourselves to the script engine
       AddNamedObject(bstrThisGuid, this);
}
HRESULT CDispExSinkConnector::AddNamedObject(BSTR bsName, IDispatch *pDisp)
{
       HRESULT hr = 0;

       CComPtr<IDispatchEx> pDispEx;
       GetDispEx(&pDispEx); 

       if(pDispEx == NULL)
              return E_FAIL;

       if(!bsName || SysStringLen(bsName) == 0 || !pDisp)
              return E_INVALIDARG;

       // Also, add our root objects into the script namespace
       DISPID dispIdThis = 0;     
hr = pDispEx->GetDispID(bsName, fdexNameEnsure | fdexNameCaseSensitive,&dispIdThis);     // here the Hr returned is 0x80010100  “System Call Failed” i.e. RPC_E_SYS_CALL_FAILED

       if (hr == DISP_E_UNKNOWNNAME)
…
..
}

请帮我找出解决此问题的根本原因和解决方案。 非常感谢您的快速帮助。 谢谢, SP

0 个答案:

没有答案