C++からIEコントロールで動作しているJavaScriptの関数を呼び出すには、IHTMLDocument2のget_Script()関数で、IDispatchを取得します。 IDispatchのGetIDsOfNames()メソッドで呼び出したい関数名をIdに変換したら、IDispatchのInvoke()メソッドを呼び出すとJavaScriptの関数が実行されます。
#include <tchar.h> #include <iostream> #include <string> #include <shlobj.h> #include <comdef.h> #include <comutil.h> #pragma warning(push) #pragma warning(disable:4996) #include <atlbase.h> #pragma warning(pop) #include <ExDispid.h> #include <Mshtml.h> // Atl.dllの関数ポインタ定義 typedef BOOL(WINAPI *ATLAXWININIT)(); typedef HRESULT(WINAPI *ATLAXGETCONTROL)(HWND, IUnknown **); // I/F解放用マクロ #define SAFE_RELEASE( p1 ) if ( p1 ) { p1->Release(); p1 = NULL; } /* JavaScriptの呼び出し */ HRESULT CallJavaScript ( IWebBrowser2* pIWebBrowser2 , BSTR funcName // 呼び出したい関数名 , DISPPARAMS* params // パラメータ , VARIANT* retval // 戻り値 ) { IDispatch* pIDispatch = NULL; // IDispatchの取得 HRESULT hResult = pIWebBrowser2->get_Document( &pIDispatch ); if ( S_OK != hResult ) { goto err; } // IHTMLDocument2の取得 IHTMLDocument2* pIHTMLDocument2 = NULL; hResult = pIDispatch->QueryInterface( __uuidof(IHTMLDocument2), (void**)&pIHTMLDocument2 ); if ( S_OK != hResult ) { goto err; } // IDispatchの取得 IDispatch* pScriptDispatch = NULL; hResult = pIHTMLDocument2->get_Script( &pScriptDispatch ); if ( S_OK != hResult ) { goto err; } // スクリプト名称をIdに変換 USES_CONVERSION; OLECHAR FAR* pFuncName = funcName; DISPID dispId; hResult = pScriptDispatch->GetIDsOfNames( IID_NULL, &pFuncName, 1, LOCALE_SYSTEM_DEFAULT, &dispId ); if ( S_OK != hResult ) { goto err; } // スクリプトの呼び出し hResult = pScriptDispatch->Invoke( dispId , IID_NULL , LOCALE_SYSTEM_DEFAULT , DISPATCH_METHOD , params , retval , NULL , NULL ); if ( S_OK != hResult ) { goto err; } err: SAFE_RELEASE( pIDispatch ); SAFE_RELEASE( pIHTMLDocument2 ); SAFE_RELEASE( pScriptDispatch ); // 処理結果を返す return( hResult ); } /* ブラウザコントロールの生成 */ int _tmain ( int argc , _TCHAR* argv[] ) { // ロケール変更(wcoutでユニコードを出力する為) std::wcout.imbue(std::locale("", std::locale::ctype)); // COMを初期化する CoInitialize(NULL); /* Atl.dllのロード */ HMODULE hAtl = NULL; std::wstring strWindowClassName; { struct { TCHAR* pszDllName; // DLLの名前 TCHAR* pszAtlAxWindowClassName; // ウインドウクラスの名前 } taDllInfo[] = { { L"atl110.dll", L"AtlAxWin110" } ,{ L"atl100.dll", L"AtlAxWin100" } ,{ L"atl90.dll" , L"AtlAxWin90" } ,{ L"atl80.dll" , L"AtlAxWin80" } ,{ L"atl71.dll" , L"AtlAxWin71" } ,{ L"atl.dll" , L"AtlAxWin" } }; for (int nI = 0; nI < _countof(taDllInfo); nI++) { // DLLをロードしてみる hAtl = LoadLibrary(taDllInfo[nI].pszDllName); if (NULL != hAtl) { // ロードできたので、ウインドウクラス名を取得 strWindowClassName = taDllInfo[nI].pszAtlAxWindowClassName; break; } } } if (NULL == hAtl) { std::wcout << L"atl.dllのロードに失敗しました。" << std::endl; } else { std::wcout << L"atl.dllのロードに成功しました。" << std::endl; // Atl.dllの関数ポインタ取得 ATLAXWININIT dll_AtlAxWinInit = (ATLAXWININIT)GetProcAddress(hAtl, "AtlAxWinInit"); ATLAXGETCONTROL dll_AtlAxGetControl = (ATLAXGETCONTROL)GetProcAddress(hAtl, "AtlAxGetControl"); // Atlの初期化 dll_AtlAxWinInit(); // ウインドウ矩形 RECT tRect = { 100, 100, 1000, 900 }; /* ブラウザコントロールの生成 */ HWND hWnd = CreateWindowEx( 0 , strWindowClassName.c_str() , L"Shell.Explorer.2" , WS_OVERLAPPEDWINDOW | WS_TABSTOP | WS_VISIBLE , tRect.left , tRect.top , tRect.right - tRect.left , tRect.bottom - tRect.top , NULL // 親ウインドウハンドル , 0 , (HINSTANCE)::GetModuleHandle(NULL) , 0 ); if (NULL == hWnd) { std::wcout << L"ブラウザコントロールの生成失敗" << std::endl; } else { std::wcout << L"ブラウザコントロールの生成成功" << std::endl; CComPtr<IUnknown> pUnknown; // ATLコントロールの取得 if (S_OK != dll_AtlAxGetControl(hWnd, (IUnknown**)&pUnknown)) { std::wcout << L"IUnknownの取得失敗" << std::endl; } else { std::wcout << L"IUnknownの取得成功" << std::endl; CComPtr<IWebBrowser2> pIWebBrowser2; // IWebBrowser2の取得 pUnknown->QueryInterface(IID_IWebBrowser2, (VOID**)&pIWebBrowser2); if (NULL == pIWebBrowser2) { std::wcout << L"IWebBrowser2の取得失敗" << std::endl; } else { std::wcout << L"IWebBrowser2の取得成功" << std::endl; /* ホームページを開く */ { TCHAR waFilePath[ MAX_PATH ]; // 実行ファイルのPATH名を得る ::GetModuleFileNameW( NULL, waFilePath, _countof( waFilePath ) ); // ファイル名をHtmlファイルへ変更 TCHAR* pFileNameTop = ::wcsrchr( waFilePath, L'¥¥' ) + 1; ::wcscpy( pFileNameTop, L"Test.html" ); // URL // CComVariant oNaviGateUrl(L"http://www.yahoo.co.jp"); CComVariant oNaviGateUrl( waFilePath ); CComVariant oNoUse; pIWebBrowser2->Navigate2(&oNaviGateUrl, &oNoUse, &oNoUse, &oNoUse, &oNoUse); } // 時間待ち(テスト用) ::MessageBox(NULL, L"HTMLが表示されたら、OKを押下するとJavaScriptを呼び出します。", L"C++からのJavaScript呼び出し", MB_OK); /* JavaScriptの呼び出し */ { DISPPARAMS empty = { NULL, NULL, 0, 0 }; VARIANT retval; HRESULT hResult = CallJavaScript( pIWebBrowser2, L"TestScript", &empty, &retval ); if ( S_OK == hResult ) { std::wcout << L"JavaScriptの呼び出しに成功しました。" << std::endl; } else { std::wcout << L"JavaScriptの呼び出しに失敗しました。" << std::endl; } } // 時間待ち(テスト用) ::MessageBox(NULL, L"OKを押下するとブラウザを閉じます。", L"ブラウザコントロールの生成", MB_OK); } } // ウインドウの破棄 ::DestroyWindow( hWnd ); } // Atl.dllの破棄 FreeLibrary(hAtl); } // COMの使用終了 CoUninitialize(); // 正常終了 return(0); }
<!doctype html> <html> <head> <meta charset="UTF-8"> <meta http-equiv="content-language" content="ja"> <title>C++からJavaScriptの関数を呼び出す。</title> <style> function TestScript() { alert( "C++から呼び出されました。" ); }; </style> <script> </script> </head> <body> C++からJavaScriptの関数を呼び出す。 <br/> </body> </html>
atl.dllのロードに成功しました。 ブラウザコントロールの生成成功 IUnknownの取得成功 IWebBrowser2の取得成功 JavaScriptの呼び出しに成功しました。