これまでのところ、次の関数を使用して、実行中の Internet Explorer インスタンスへの IWebBrowser2 ポインターを PID で取得することに成功しました。
static SHDocVw::IWebBrowser2Ptr findBrowserByPID( DWORD pid )
{
SHDocVw::IShellWindowsPtr ptr;
ptr.CreateInstance(__uuidof(SHDocVw::ShellWindows));
if ( ptr == NULL ) {
return 0;
}
// number of shell windows
const long nCount = ptr->GetCount();
// iterate over all shell windows
for (long i = 0; i < nCount; ++i) {
// get interface to item no i
_variant_t va(i, VT_I4);
IDispatchPtr spDisp = ptr->Item(va);
SHDocVw::IWebBrowser2Ptr spBrowser(spDisp);
if (spBrowser != NULL) {
// if there's a document we know this is an IE object
// rather than a Windows Explorer instance
HWND browserWindow;
try {
browserWindow = (HWND)spBrowser->GetHWND();
} catch ( const _com_error &e ) {
// in case ->GetHWND() fails
continue;
}
DWORD browserPID;
GetWindowThreadProcessId( browserWindow, &browserPID );
if ( browserPID == pid ) {
return spBrowser;
}
}
}
return 0;
}
私がしていることは、explorer.exe
経由でプロセスを起動しCreateProcess
、上記の関数を使用して IWebBrowser2Ptr を取得することです (ブラウザーをいじることができるように)。
残念ながら、IE8 はプロセスを再利用しているように見えるため、これは Internet Explorer 8 では動作しないようです (少なくともある程度は)。次のような 2 つのコード シーケンスの場合:
PROCESS_INFORMATION pi;
// ...
if ( CreateProcess( ..., &pi ) ) {
// Wait a bit to give the browser a change to show its window
// ...
IWebBrowser2 *pWebBrowser = findBrowserByPID( pi.dwProcessId );
}
このコードの最初の実行は正常に機能しますが、2 回目は pWebBrowser ウィンドウを取得できません。
少しデバッグした後、このfindBrowserByPID
関数は多くのブラウザー ウィンドウを検出する (そして、2 番目のブラウザー インスタンスを開始するとさらに多くのウィンドウを検出する) が、新しく開始されたプロセスに属していないことが明らかになりました。すべてのウィンドウは、最初に開始された IE プロセスに属しているようです。
IWebBrowser2 ポインターを IE8 インスタンスに取得する別の方法を知っている人はいますか? または、IE8 でこのプロセスの明らかな「再利用」を無効にする方法はありますか?