До сих пор я успешно использовал следующую функцию для получения указателя IWebBrowser2 на работающий экземпляр Internet Explorer, учитывая его 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 на него (чтобы я мог возиться с браузером).
К сожалению, похоже, это больше не работает с Internet Explorer 8, так как IE8, кажется, повторно использует процессы - по крайней мере, до некоторой степени. Для двух кодовых последовательностей, таких как:
PROCESS_INFORMATION pi;
// ...
if ( CreateProcess( ..., &pi ) ) {
// Wait a bit to give the browser a change to show its window
// ...
IWebBrowser2 *pWebBrowser = findBrowserByPID( pi.dwProcessId );
}
Первый запуск этого кода работает нормально, второму никогда не удается получить окно pWebBrowser.
После небольшой отладки выяснилось, что функция findBrowserByPID
находит множество окон браузера (и обнаруживает больше после запуска второго экземпляра браузера), но ни одно из них не относится к недавно запущенному процессу. Кажется, что все окна принадлежат первому процессу IE, который был запущен.
Кто-нибудь знает альтернативный способ получить указатель IWebBrowser2 на некоторый экземпляр IE8? Или, может быть, есть способ отключить это очевидное «повторное использование» процессов в IE8?