『 Google Chrome Frame をチェックしていたら、BHO ( Browser Helper Object ) が気になってきた 』 ので、C++、ATL を使って実装してみた で強制的に私のブログに遷移してしまうというサンプルを作成しました。そのサンプルをベースに BHO で HTML の要素にアクセスしてみたいと思います。
今回コードは、https://www.hatena.ne.jp/login に遷移すると、ID, PASSWORD を入力するものです。まず、はてなログイン画面の HTML の要素を見てみましょう。F12 開発者ツールを使って調べてみましょう。 ログインページの要素が下図のように参照できます。
ID, PASSWORD 部分の要素は下記の通りです。id で要素にアクセスしようかと思いましたが、PASSWORD の要素には id が付与されていないですね。なので、name 属性でアクセスすることにしましょう。
<table class="config">
<tr>
<th class="row">Hatena ID <br><span style="font-weight:normal">or</span> Email address</th>
<td><input value="" name="name" autofocus="autofocus" pattern=".{3,}" required="required" type="text" class="text" id="login-name"></td>
</tr>
<tr>
<th class="row">Password</th>
<td><input required="required" value="" name="password" class="password" type="password"></td>
</tr>
</table>
下記のコードで ページロード後に、ID, PASSWORD をセットすることができます。ただし、下記のコードはエラー処理を一切入れていないので、みなさんはぜひ要素存在チェックなど、きちんとエラー処理を入れてくださいね。
void STDMETHODCALLTYPE CNativeBhoSample::OnDocumentComplete(IDispatch* pDisp, VARIANT *pvarURL)
{
if (_tcsstr(pvarURL->bstrVal, _T("https://www.hatena.ne.jp/login")))
{
CComPtr<IWebBrowser2> spWebBrowser;
CComPtr<IDispatch> spDisp;
CComPtr<IDispatch> spPassDisp;
CComPtr<IHTMLDocument3> spHtmlDoc3;
CComPtr<IHTMLElement> spHtmlElem;
CComPtr<IHTMLInputElement> spHtmlInput;
CComPtr<IHTMLElementCollection> spHtmlElements;
CComBSTR bstrTemp;
// WebBrowser のポインタ取得
pDisp->QueryInterface(IID_IWebBrowser2, reinterpret_cast<void**>(&spWebBrowser));
spWebBrowser->get_Document(&spDisp);
// HTMLDocuemt の取得
spDisp->QueryInterface(IID_IHTMLDocument3, reinterpret_cast<void**>(&spHtmlDoc3));
// id = login-name の要素を取得
spHtmlDoc3->getElementById(_T("login-name"), &spHtmlElem);
spHtmlElem->QueryInterface(IID_IHTMLInputElement, reinterpret_cast<void**>(&spHtmlInput));
// ID の設定
spHtmlInput->put_value(_T("xxxxxxxx"));
spHtmlInput.Release();
spHtmlElem.Release();
// パスワードには、id 属性が付与されていない
spHtmlDoc3->getElementsByName(_T("password"), &spHtmlElements);
// passbox は一つしかないので....
VARIANT index;
VariantInit(&index);
index.vt = VT_I4;
index.lVal = 0;
// パスワードの要素を取得
spHtmlElements->item(index, index, &spPassDisp);
spPassDisp->QueryInterface(IID_IHTMLInputElement, reinterpret_cast<void**>(&spHtmlInput));
// パスワードの設定
spHtmlInput->put_value(_T("xxxxxxxx"));
spHtmlInput.Release();
spPassDisp.Release();
spHtmlElem.Release();
spHtmlDoc3.Release();
spDisp.Release();
bstrTemp.Empty();
spWebBrowser.Release();
}
}
ページロード後、DocumentComplete イベントが実行され、ID および PASSWORD がセットされました。
HTML へのアクセスは非常に簡単ですね。BHO 関連はあと何をしましょうか?
※これほしいなぁ。10 or 11 版とかでないのかな?