1

私は問題に悩まされており、このフォーラムがこれについて私を助けることができると確信しています。

スクリプトにいくつかの自動化オブジェクトを追加しようとしています(別のプロセス(ATL EXEサーバー)を介してホストされています)。また、ATLEXEスクリプトエンジン内のこれらの自動化オブジェクトからイベントをシンクしようとしています。

これを実現するために、 http://www.codeproject.com/Articles/3326/Extending-the-Internet-Explorer-Scripting-Engineで説明されているようにCDispExSinkConnectorを使用しています。説明されているように、 IDispatchEx :: GetDispID()を使用して作成しています。スクリプトエンジン内の新しいメンバー。メンバーDISPIDが作成されたら、InvokeEx()を使用してプロパティ値を設定します。ただし、これらのメソッド呼び出しはRPC_E_SYS_CALL_FAILEDを返します。

注-ここでは、OUT-OF-PROCIDispatchポインターからIDispExポインターを取得します。

より詳細な説明:MFCクライアントアプリケーション用のHTMLプラグインを作成するために使用しているATLEXEサーバーにCAxWindowによってホストされているBrowserCtrlがあります。ATL EXEサーバーは、IWebBrowser2メソッドにラッパーメソッドを提供するため、IWebBrowser2Ptr-> Navigate2()などのメソッドを呼び出すことができます。

また、このATL EXEサーバーでOnDocumentComplete(…。)などのIWebBrowser2イベントをサブスクライブし、最終的にそれらをMFCクライアントアプリケーションに転送して、そこで処理することもできます。以下は、私のATL EXEサーバー(BrowserCtrl)のいくつかのコードスニペットです。

1つ目は、CAxWindowを作成し、WebBrowserコントロールを作成し、内部のデフォルトCAxHostWindowでコントロールをホストするCreateControl()です。

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

4

0 に答える 0