Getting RPC_E_SYS_CALL_FAILED in IDispatchEx::GetDispID() for an out-of-proc IDispatch pointer

1

I’m stuck with an issue and I’m pretty sure that this forum will be able to help me for this.

I’m trying to add few automation objects to the scripts (hosted via a separate process (ATL EXE server)). Also I am trying to sink the events from these automation objects inside my ATL EXE script engine.

To achive this I’m using CDispExSinkConnector as described in http://www.codeproject.com/Articles/3326/Extending-the-Internet-Explorer-Scripting-Engine As described I’m using IDispatchEx::GetDispID()to create new members inside the scripting engine. Once the member DISPID has been created, I’m using InvokeEx()to set the property value. But these method calls return RPC_E_SYS_CALL_FAILED.

Note- Here I get the IDispEx pointer from an OUT-OF-PROC IDispatch pointer.

More detailed descriptions: I do have a BrowserCtrl hosted by CAxWindow in an ATL EXE server which I’m using to create HTML plug-ins for my MFC client application. The ATL EXE server provides wrapper methods to IWebBrowser2 methods so that I can call methods like IWebBrowser2Ptr->Navigate2().

Also I can subscribe to IWebBrowser2 events like OnDocumentComplete(….)in this ATL EXE server and ultimately forward those to my MFC Client application to handle those there. Below are few code snippets for my ATL EXE server (BrowserCtrl):

1st is CreateControl() which creates the CAxWindow, creates the WebBrowser Control and host the control on internal default 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;
}

//Now the wrapper method for IWebBrowser2 methods

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

//Now the event handlers for the IWebBrowser2 events:

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

}

Now the issue:

1.On the MFC Client APP and in the event handler function OnDocumentComplete() I do the following:

 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
    ……
    ……..
    ………
    }

Here is the SetDispEx() and internal related functions:

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)
…
..
}

Please help me to find out the root cause and a solution to resolve this issue. Your quick help will be much appreciated. Thanks, SP

atl
asked on Stack Overflow Oct 17, 2012 by user1754779

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0