社本@元ネオニート Blog

社本@元ネオニート (元々ワック) のいたずら書き (for Programmers)

AILight Banner
AILight Blog

プロフィール

社本@元ネオニート Blog
働いたら負けかなと思っていたのですが。。とうとう働き始めました。アメリカのシアトル・エリアにある企業向けのバックアップソフトを開発している会社です。日本人は私だけ。なんとか。。やっていけてるようです。

目次

Blog 利用状況

記事分類

過去の記事

タグ

HTML(Script)側へのオブジェクトの公開 その3- IE/WebBrowser

> なんと、グローバルな領域にオブジェクトを公開している
> ではないですか!!
> 彼らにできて、オレにできないなんて許せない!という訳で、
> 再度、調査をしてみることにしました。

IHTMLDocument::get_Scriptで取得できるオブジェクトが
IDispatchExを実装しており、これにプロパティとして
オブジェクトを追加すればよいだけでした。

分かってしまえば、IDocHostUIHandlerを使った実装
よりも簡単でした。

---
#include <exdispid.h>
#include <DispEx.h>

// Native Compiler COM Support
#include <comdef.h>        // _com_error
#include <comutil.h>       // _bstr_t, _variant_t
#include <comip.h>        // _com_ptr_t
#pragma comment(lib, "comsupp.lib")
#pragma comment(lib, "comsuppw.lib")

#if 0
#pragma warning(push)
#pragma warning(disable: 4192)
#pragma warning(disable: 4278)
#pragma warning(disable: 4279)
#import <shdocvw.dll>
#import <mshtml.tlb>
#pragma warning(pop)
#else
#include <ExDisp.h>        // IWebBrowser2
#include <MsHTML.h>        // IHTMLDocument2
#endif

#if _MSC_VER Document;
   if (spHTMLDocuemt2 == NULL)
   {
    return NULL;
   }

   spResult = spHTMLDocuemt2->Script;
   if (spResult == NULL)
   {
    return NULL;
   }
  }
  catch (...)
  {
   ATLASSERT(0);
   return NULL;
  }

  return spResult;
 }
#else
 // Scriptオブジェクトを取得
 static IDispatchExPtr GetScript(IWebBrowser2Ptr spWebBrowser2)
 {
  if (spWebBrowser2 == NULL)
  {
   ATLASSERT(0);
   return NULL;
  }

  HRESULT hr = S_OK;

  IDispatchPtr spDispHTMLDocuemt2;
  hr = spWebBrowser2->get_Document(&spDispHTMLDocuemt2);
  if (FAILED(hr))
  {
   return NULL;
  }

  IHTMLDocument2Ptr spHTMLDocuemt2 = spDispHTMLDocuemt2;
  if (spHTMLDocuemt2 == NULL)
  {
   return NULL;
  }

  IDispatchPtr spDispScript;
  hr = spHTMLDocuemt2->get_Script(&spDispScript);
  if (FAILED(hr))
  {
   return NULL;
  }

  IDispatchExPtr spScript = spDispScript;
  if (spScript == NULL)
  {
   return NULL;
  }

  return spScript;
 }
#endif

public:
 // プロパティを登録
 static HRESULT RegisterProperty(IDispatchExPtr spDispatchEx, LPCTSTR szName, _variant_t varValue)
 {
  if (spDispatchEx == NULL)
  {
   ATLASSERT(0);
   return E_FAIL;
  }

  HRESULT hr = S_OK;

  DISPID dispID = 0;
  hr = spDispatchEx->GetDispID(_bstr_t(szName), fdexNameEnsure | fdexNameCaseSensitive, &dispID);
  if (FAILED(hr))
  {
   return hr;
  }

  DISPID dispidNamedArgs = DISPID_PROPERTYPUT;

  DISPPARAMS dispParams = { &varValue, &dispidNamedArgs, 1, 1 };
  EXCEPINFO excepInfo = { 0 };
  hr = spDispatchEx->InvokeEx(dispID, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUT, &dispParams, NULL, &excepInfo, NULL);
  if (FAILED(hr))
  {
   return hr;
  }

  return S_OK;
 }
 // プロパティを登録解除
 static HRESULT UnregisterProperty(IDispatchExPtr spDispatchEx, LPCTSTR szName)
 {
  USES_CONVERSION;

  if (spDispatchEx == NULL)
  {
   ATLASSERT(0);
   return E_FAIL;
  }

  HRESULT hr = S_OK;

#if 1
  LPOLESTR szNames[] = { T2W(szName) };
  DISPID dispID = 0;
  hr = spDispatchEx->GetIDsOfNames(IID_NULL, szNames, _countof(szNames), LOCALE_USER_DEFAULT, &dispID);
  if (FAILED(hr))
  {
   return hr;
  }

  hr = spDispatchEx->DeleteMemberByDispID(dispID);
  if (FAILED(hr))
  {
   // NOTE: E_NOTIMPLになる。。
   return hr;
  }
#else
  hr = spDispatchEx->DeleteMemberByName(_bstr_t(szName), fdexNameCaseSensitive);
  if (FAILED(hr))
  {
   // NOTE: E_NOTIMPLになる。。
   return hr;
  }
#endif

  return S_OK;
 }
 // プロパティを取得
 static HRESULT GetProperty(IDispatchExPtr spDispatchEx, LPCTSTR szName, _variant_t& varValue)
 {
  USES_CONVERSION;

  if (spDispatchEx == NULL)
  {
   ATLASSERT(0);
   return E_FAIL;
  }

  HRESULT hr = S_OK;

  LPOLESTR szNames[] = { T2W(szName) };
  DISPID dispID = 0;
  hr = spDispatchEx->GetIDsOfNames(IID_NULL, szNames, _countof(szNames), LOCALE_USER_DEFAULT, &dispID);
  if (FAILED(hr))
  {
   return hr;
  }

  DISPPARAMS dispParams = { NULL, NULL, 0, 0 };
  _variant_t var;
  hr = spDispatchEx->Invoke(dispID, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispParams, &var, NULL, NULL);
  if (FAILED(hr))
  {
   return hr;
  }

  return S_OK;
 }
};
---

---
■ブラウザをホストするアプリ
 void __stdcall OnNavigateComplete2(IDispatch * pDisp, VARIANT * URL)
 {
  HRESULT hr = S_OK;

  try
  {
   IDispatchExPtr spScript = CIEScriptHelper::GetScript((IUnknown*)m_wndWebBrowser2);
   if (spScript == NULL)
   {
    return;
   }

   // ブラウザ(IWebBrowser2)自身を、Hogeとして登録
   hr = CIEScriptHelper::RegisterProperty(spScript, _T("Hoge"), _variant_t(pDisp));
   if (FAILED(hr))
   {
    return;
   }

   // 取得
   _variant_t varValue;
   hr = CIEScriptHelper::GetProperty(spScript, _T("Hoge"), varValue);
   if (FAILED(hr))
   {
    return;
   }

   // spHoge == pDisp である
   IDispatchPtr spHoge = (IDispatch*)varValue;

/*
   // 登録解除
   hr = CIEScriptHelper::UnregisterProperty(spScript, _T("Hoge"));
   if (FAILED(hr))
   {
    // 無視する。。
   }
*/
  }
  catch (...)
  {
   ATLASSERT(0);
  }
 }
---

---
■HTMLのサンプル
<html>
<head>
<title>Sample</title>

<script language="jscript">
function onClick()
{
 Hoge.Navigate2("http://www.wac-jp.com/");
}

</script>
</head>
<body>
 <br />
 <br />
 <input type="button" value="hoge" onClick="javascript:onClick();" />
 <br />
 <br />
</body>
</html>
---


■IHTMLDocument::Script Property - MSDN
http://msdn2.microsoft.com/en-us/library/aa752642.aspx

投稿日時 : 2007年6月11日 17:36


コメントを追加

タイトル
名前
URL
コメント