bool BrowserFactory::AttachToBrowser(ProcessWindowInfo* process_window_info, bool ignore_zoom_setting, std::string* error_message) { LOG(TRACE) << "Entering BrowserFactory::AttachToBrowser"; while (process_window_info->hwndBrowser == NULL) { // TODO: create a timeout for this. We shouldn't need it, since // we got a valid process ID, but we should bulletproof it. ::EnumWindows(&BrowserFactory::FindBrowserWindow, reinterpret_cast<LPARAM>(process_window_info)); if (process_window_info->hwndBrowser == NULL) { ::Sleep(250); } } CComPtr<IHTMLDocument2> document; if (this->GetDocumentFromWindowHandle(process_window_info->hwndBrowser, &document)) { CComPtr<IHTMLWindow2> window; HRESULT hr = document->get_parentWindow(&window); // Test for zoom level = 100% int zoom_level = 100; LOG(DEBUG) << "Ignoring zoom setting: " << ignore_zoom_setting; if (!ignore_zoom_setting) { zoom_level = this->GetZoomLevel(document, window); } if (zoom_level != 100) { vector<char> zoom_level_buffer(10); _itoa_s(zoom_level, &zoom_level_buffer[0], 10, 10); std::string zoom(&zoom_level_buffer[0]); *error_message = "Browser zoom level was set to " + zoom + "%. It should be set to 100%"; return false; } if (SUCCEEDED(hr)) { // http://support.microsoft.com/kb/257717 CComQIPtr<IServiceProvider> provider(window); if (provider) { CComPtr<IServiceProvider> child_provider; hr = provider->QueryService(SID_STopLevelBrowser, IID_IServiceProvider, reinterpret_cast<void**>(&child_provider)); if (SUCCEEDED(hr)) { IWebBrowser2* browser; hr = child_provider->QueryService(SID_SWebBrowserApp, IID_IWebBrowser2, reinterpret_cast<void**>(&browser)); if (SUCCEEDED(hr)) { process_window_info->pBrowser = browser; return true; } else { LOGHR(WARN, hr) << "IServiceProvider::QueryService for SID_SWebBrowserApp failed"; } } else { LOGHR(WARN, hr) << "IServiceProvider::QueryService for SID_STopLevelBrowser failed"; } } else { LOG(WARN) << "QueryInterface for IServiceProvider failed"; } } else { LOGHR(WARN, hr) << "Call to IHTMLDocument2::get_parentWindow failed"; } } else { *error_message = "Could not get document from window handle"; } return false; }
bool BrowserFactory::AttachToBrowser(ProcessWindowInfo* process_window_info, const int timeout_in_milliseconds, const bool ignore_zoom_setting, std::string* error_message) { LOG(TRACE) << "Entering BrowserFactory::AttachToBrowser"; clock_t end = clock() + (timeout_in_milliseconds / 1000 * CLOCKS_PER_SEC); while (process_window_info->hwndBrowser == NULL) { if (timeout_in_milliseconds > 0 && (clock() > end)) { break; } ::EnumWindows(&BrowserFactory::FindBrowserWindow, reinterpret_cast<LPARAM>(process_window_info)); if (process_window_info->hwndBrowser == NULL) { ::Sleep(250); } } if (process_window_info->hwndBrowser == NULL) { int attach_fail_msg_count = _scprintf(ATTACH_TIMEOUT_ERROR_MESSAGE, process_window_info->dwProcessId, timeout_in_milliseconds); vector<char> attach_fail_msg_buffer(attach_fail_msg_count + 1); _snprintf_s(&attach_fail_msg_buffer[0], attach_fail_msg_buffer.size(), attach_fail_msg_count, ATTACH_TIMEOUT_ERROR_MESSAGE, process_window_info->dwProcessId, timeout_in_milliseconds); std::string attach_fail_msg = &attach_fail_msg_buffer[0]; *error_message = attach_fail_msg; return false; } CComPtr<IHTMLDocument2> document; if (this->GetDocumentFromWindowHandle(process_window_info->hwndBrowser, &document)) { CComPtr<IHTMLWindow2> window; HRESULT hr = document->get_parentWindow(&window); // Test for zoom level = 100% int zoom_level = 100; LOG(DEBUG) << "Ignoring zoom setting: " << ignore_zoom_setting; if (!ignore_zoom_setting) { zoom_level = this->GetZoomLevel(document, window); } if (zoom_level != 100) { vector<char> zoom_level_buffer(10); _itoa_s(zoom_level, &zoom_level_buffer[0], 10, 10); std::string zoom(&zoom_level_buffer[0]); *error_message = "Browser zoom level was set to " + zoom + "%. It should be set to 100%"; return false; } if (SUCCEEDED(hr)) { // http://support.microsoft.com/kb/257717 CComPtr<IServiceProvider> provider; window->QueryInterface<IServiceProvider>(&provider); if (provider) { CComPtr<IServiceProvider> child_provider; hr = provider->QueryService(SID_STopLevelBrowser, IID_IServiceProvider, reinterpret_cast<void**>(&child_provider)); if (SUCCEEDED(hr)) { IWebBrowser2* browser; hr = child_provider->QueryService(SID_SWebBrowserApp, IID_IWebBrowser2, reinterpret_cast<void**>(&browser)); if (SUCCEEDED(hr)) { process_window_info->pBrowser = browser; return true; } else { LOGHR(WARN, hr) << "IServiceProvider::QueryService for SID_SWebBrowserApp failed"; } } else { LOGHR(WARN, hr) << "IServiceProvider::QueryService for SID_STopLevelBrowser failed"; } } else { LOG(WARN) << "QueryInterface for IServiceProvider failed"; } } else { LOGHR(WARN, hr) << "Call to IHTMLDocument2::get_parentWindow failed"; } } else { *error_message = "Could not get document from window handle"; } return false; }