diff options
Diffstat (limited to 'chrome_frame/test/chrome_frame_test_utils.cc')
-rw-r--r-- | chrome_frame/test/chrome_frame_test_utils.cc | 397 |
1 files changed, 70 insertions, 327 deletions
diff --git a/chrome_frame/test/chrome_frame_test_utils.cc b/chrome_frame/test/chrome_frame_test_utils.cc index 0b8176d..79f388b 100644 --- a/chrome_frame/test/chrome_frame_test_utils.cc +++ b/chrome_frame/test/chrome_frame_test_utils.cc @@ -28,21 +28,6 @@ const wchar_t kOperaImageName[] = L"opera.exe"; const wchar_t kSafariImageName[] = L"safari.exe"; const wchar_t kChromeImageName[] = L"chrome.exe"; -bool IsTopLevelWindow(HWND window) { - long style = GetWindowLong(window, GWL_STYLE); // NOLINT - if (!(style & WS_CHILD)) - return true; - - HWND parent = GetParent(window); - if (!parent) - return true; - - if (parent == GetDesktopWindow()) - return true; - - return false; -} - // Callback function for EnumThreadWindows. BOOL CALLBACK CloseWindowsThreadCallback(HWND hwnd, LPARAM param) { int& count = *reinterpret_cast<int*>(param); @@ -105,195 +90,6 @@ int CloseVisibleWindowsOnAllThreads(HANDLE process) { return window_close_attempts; } -class ForegroundHelperWindow : public CWindowImpl<ForegroundHelperWindow> { - public: -BEGIN_MSG_MAP(ForegroundHelperWindow) - MESSAGE_HANDLER(WM_HOTKEY, OnHotKey) -END_MSG_MAP() - - HRESULT SetForeground(HWND window) { - DCHECK(::IsWindow(window)); - if (NULL == Create(NULL, NULL, NULL, WS_POPUP)) - return AtlHresultFromLastError(); - - static const int kHotKeyId = 0x0000baba; - static const int kHotKeyWaitTimeout = 2000; - - SetWindowLongPtr(GWLP_USERDATA, reinterpret_cast<ULONG_PTR>(window)); - RegisterHotKey(m_hWnd, kHotKeyId, 0, VK_F22); - - MSG msg = {0}; - PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE); - - SendVirtualKey(VK_F22, false); - // There are scenarios where the WM_HOTKEY is not dispatched by the - // the corresponding foreground thread. To prevent us from indefinitely - // waiting for the hotkey, we set a timer and exit the loop. - SetTimer(kHotKeyId, kHotKeyWaitTimeout, NULL); - - while (GetMessage(&msg, NULL, 0, 0)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - if (msg.message == WM_HOTKEY) - break; - else if (msg.message == WM_TIMER) { - SetForegroundWindow(window); - break; - } - } - - UnregisterHotKey(m_hWnd, kHotKeyId); - KillTimer(kHotKeyId); - DestroyWindow(); - return S_OK; - } - - LRESULT OnHotKey(UINT msg, WPARAM wp, LPARAM lp, BOOL& handled) { // NOLINT - HWND window = reinterpret_cast<HWND>(GetWindowLongPtr(GWLP_USERDATA)); - SetForegroundWindow(window); - return 1; - } -}; - -bool ForceSetForegroundWindow(HWND window) { - if (GetForegroundWindow() == window) - return true; - ForegroundHelperWindow foreground_helper_window; - HRESULT hr = foreground_helper_window.SetForeground(window); - return SUCCEEDED(hr); -} - -struct PidAndWindow { - base::ProcessId pid; - HWND hwnd; -}; - -BOOL CALLBACK FindWindowInProcessCallback(HWND hwnd, LPARAM param) { - PidAndWindow* paw = reinterpret_cast<PidAndWindow*>(param); - base::ProcessId pid; - GetWindowThreadProcessId(hwnd, &pid); - if (pid == paw->pid && IsWindowVisible(hwnd)) { - paw->hwnd = hwnd; - return FALSE; - } - - return TRUE; -} - -bool EnsureProcessInForeground(base::ProcessId process_id) { - HWND hwnd = GetForegroundWindow(); - base::ProcessId current_foreground_pid = 0; - DWORD active_thread_id = GetWindowThreadProcessId(hwnd, - ¤t_foreground_pid); - if (current_foreground_pid == process_id) - return true; - - PidAndWindow paw = { process_id }; - EnumWindows(FindWindowInProcessCallback, reinterpret_cast<LPARAM>(&paw)); - if (!IsWindow(paw.hwnd)) { - DLOG(ERROR) << "failed to find process window"; - return false; - } - - bool ret = ForceSetForegroundWindow(paw.hwnd); - LOG_IF(ERROR, !ret) << "ForceSetForegroundWindow: " << ret; - - return ret; -} - -// Iterates through all the characters in the string and simulates -// keyboard input. The input goes to the currently active application. -bool SendString(const wchar_t* string) { - DCHECK(string != NULL); - - INPUT input[2] = {0}; - input[0].type = INPUT_KEYBOARD; - input[0].ki.dwFlags = KEYEVENTF_UNICODE; // to avoid shift, etc. - input[1] = input[0]; - input[1].ki.dwFlags |= KEYEVENTF_KEYUP; - - for (const wchar_t* p = string; *p; p++) { - input[0].ki.wScan = input[1].ki.wScan = *p; - SendInput(2, input, sizeof(INPUT)); - } - - return true; -} - -void SendVirtualKey(int16 key, bool extended) { - INPUT input = { INPUT_KEYBOARD }; - input.ki.wVk = key; - input.ki.dwFlags = extended ? KEYEVENTF_EXTENDEDKEY : 0; - SendInput(1, &input, sizeof(input)); - input.ki.dwFlags = (extended ? KEYEVENTF_EXTENDEDKEY : 0) | KEYEVENTF_KEYUP; - SendInput(1, &input, sizeof(input)); -} - -void SendChar(char c) { - SendVirtualKey(VkKeyScanA(c), false); -} - -void SendString(const char* s) { - while (*s) { - SendChar(*s); - s++; - } -} - -// Sends a keystroke to the currently active application with optional -// modifiers set. -bool SendMnemonic(WORD mnemonic_char, bool shift_pressed, bool control_pressed, - bool alt_pressed) { - INPUT special_keys[3] = {0}; - for (int index = 0; index < arraysize(special_keys); ++index) { - special_keys[index].type = INPUT_KEYBOARD; - special_keys[index].ki.dwFlags = 0; - } - - int num_special_keys = 0; - if (shift_pressed) { - special_keys[num_special_keys].ki.wVk = VK_SHIFT; - num_special_keys++; - } - - if (control_pressed) { - special_keys[num_special_keys].ki.wVk = VK_CONTROL; - num_special_keys++; - } - - if (alt_pressed) { - special_keys[num_special_keys].ki.wVk = VK_MENU; - num_special_keys++; - } - - // Depress the modifiers. - SendInput(num_special_keys, special_keys, sizeof(INPUT)); - - Sleep(100); - - INPUT mnemonic = {0}; - mnemonic.type = INPUT_KEYBOARD; - mnemonic.ki.wVk = mnemonic_char; - - // Depress and release the mnemonic. - SendInput(1, &mnemonic, sizeof(INPUT)); - Sleep(100); - - mnemonic.ki.dwFlags |= KEYEVENTF_KEYUP; - SendInput(1, &mnemonic, sizeof(INPUT)); - Sleep(100); - - // Now release the modifiers. - for (int index = 0; index < num_special_keys; index++) { - special_keys[index].ki.dwFlags |= KEYEVENTF_KEYUP; - } - - SendInput(num_special_keys, special_keys, sizeof(INPUT)); - Sleep(100); - - return true; -} - std::wstring GetExecutableAppPath(const std::wstring& file) { std::wstring kAppPathsKey = L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\"; @@ -423,121 +219,6 @@ int CloseAllIEWindows() { return ret; } -void ShowChromeFrameContextMenu() { - static const int kChromeFrameContextMenuTimeout = 500; - HWND renderer_window = GetChromeRendererWindow(); - EXPECT_TRUE(IsWindow(renderer_window)); - - SetKeyboardFocusToWindow(renderer_window, 100, 100); - - // Bring up the context menu in the Chrome renderer window. - PostMessage(renderer_window, WM_RBUTTONDOWN, MK_RBUTTON, MAKELPARAM(50, 50)); - PostMessage(renderer_window, WM_RBUTTONUP, MK_RBUTTON, MAKELPARAM(50, 50)); - - MessageLoop::current()->PostDelayedTask( - FROM_HERE, - NewRunnableFunction(SelectAboutChromeFrame), - kChromeFrameContextMenuTimeout); -} - -void SetKeyboardFocusToWindow(HWND window, int x, int y) { - HWND top_level_window = window; - if (!IsTopLevelWindow(top_level_window)) { - top_level_window = GetAncestor(window, GA_ROOT); - } - ForceSetForegroundWindow(top_level_window); - - POINT cursor_position = {130, 130}; - ClientToScreen(window, &cursor_position); - - double screen_width = ::GetSystemMetrics( SM_CXSCREEN ) - 1; - double screen_height = ::GetSystemMetrics( SM_CYSCREEN ) - 1; - double location_x = cursor_position.x * (65535.0f / screen_width); - double location_y = cursor_position.y * (65535.0f / screen_height); - - INPUT input_info = {0}; - input_info.type = INPUT_MOUSE; - input_info.mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE; - input_info.mi.dx = static_cast<long>(location_x); - input_info.mi.dy = static_cast<long>(location_y); - ::SendInput(1, &input_info, sizeof(INPUT)); - - Sleep(10); - - input_info.mi.dwFlags = MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_ABSOLUTE; - ::SendInput(1, &input_info, sizeof(INPUT)); - - Sleep(10); - - input_info.mi.dwFlags = MOUSEEVENTF_LEFTUP | MOUSEEVENTF_ABSOLUTE; - ::SendInput(1, &input_info, sizeof(INPUT)); -} - -void SendInputToWindow(HWND window, const std::string& input_string) { - const unsigned long kIntervalBetweenInput = 100; - - for (size_t index = 0; index < input_string.length(); index++) { - bool is_upper_case = isupper(input_string[index]); - if (is_upper_case) { - INPUT input = { INPUT_KEYBOARD }; - input.ki.wVk = VK_SHIFT; - input.ki.dwFlags = 0; - SendInput(1, &input, sizeof(input)); - Sleep(kIntervalBetweenInput); - } - - // The WM_KEYDOWN and WM_KEYUP messages for characters always contain - // the uppercase character codes. - SendVirtualKey(toupper(input_string[index]), false); - Sleep(kIntervalBetweenInput); - - if (is_upper_case) { - INPUT input = { INPUT_KEYBOARD }; - input.ki.wVk = VK_SHIFT; - input.ki.dwFlags = KEYEVENTF_KEYUP; - SendInput(1, &input, sizeof(input)); - Sleep(kIntervalBetweenInput); - } - } -} - -void SelectAboutChromeFrame() { - // Send a key up message to enable the About chrome frame option to be - // selected followed by a return to select it. - SendVirtualKey(VK_UP, true); - SendVirtualKey(VK_RETURN, false); -} - -BOOL CALLBACK FindChromeRendererWindowProc( - HWND window, LPARAM lParam) { - HWND* target_window = reinterpret_cast<HWND*>(lParam); - wchar_t class_name[MAX_PATH] = {0}; - - GetClassName(window, class_name, arraysize(class_name)); - if (!_wcsicmp(class_name, L"Chrome_RenderWidgetHostHWND")) { - *target_window = window; - return FALSE; - } - - return TRUE; -} - -BOOL CALLBACK EnumHostBrowserWindowProc( - HWND window, LPARAM lParam) { - EnumChildWindows(window, FindChromeRendererWindowProc, lParam); - HWND* target_window = reinterpret_cast<HWND*>(lParam); - if (IsWindow(*target_window)) - return FALSE; - return TRUE; -} - -HWND GetChromeRendererWindow() { - HWND chrome_window = NULL; - EnumWindows(EnumHostBrowserWindowProc, - reinterpret_cast<LPARAM>(&chrome_window)); - return chrome_window; -} - LowIntegrityToken::LowIntegrityToken() : impersonated_(false) { } @@ -802,8 +483,30 @@ HRESULT WebBrowserEventSink::OnLoadErrorInternal(const VARIANT* param) { } HRESULT WebBrowserEventSink::OnMessageInternal(const VARIANT* param) { - DLOG(INFO) << __FUNCTION__ << " " << param->bstrVal; - OnMessage(param->bstrVal); + DLOG(INFO) << __FUNCTION__ << " " << param; + ScopedVariant data, origin, source; + if (param && (V_VT(param) == VT_DISPATCH)) { + wchar_t* properties[] = { L"data", L"origin", L"source" }; + const int prop_count = arraysize(properties); + DISPID ids[prop_count] = {0}; + + HRESULT hr = param->pdispVal->GetIDsOfNames(IID_NULL, properties, + prop_count, LOCALE_SYSTEM_DEFAULT, ids); + if (SUCCEEDED(hr)) { + DISPPARAMS params = { 0 }; + EXPECT_HRESULT_SUCCEEDED(param->pdispVal->Invoke(ids[0], IID_NULL, + LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET, ¶ms, + data.Receive(), NULL, NULL)); + EXPECT_HRESULT_SUCCEEDED(param->pdispVal->Invoke(ids[1], IID_NULL, + LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET, ¶ms, + origin.Receive(), NULL, NULL)); + EXPECT_HRESULT_SUCCEEDED(param->pdispVal->Invoke(ids[2], IID_NULL, + LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET, ¶ms, + source.Receive(), NULL, NULL)); + } + } + + OnMessage(V_BSTR(&data), V_BSTR(&origin), V_BSTR(&source)); return S_OK; } @@ -832,12 +535,17 @@ HRESULT WebBrowserEventSink::Navigate(const std::wstring& navigate_url) { } void WebBrowserEventSink::SetFocusToChrome() { - chrome_frame_test::SetKeyboardFocusToWindow(GetTabWindow(), 1, 1); + simulate_input::SetKeyboardFocusToWindow(GetRendererWindow()); } -void WebBrowserEventSink::SendInputToChrome( - const std::string& input_string) { - chrome_frame_test::SendInputToWindow(GetTabWindow(), input_string); +void WebBrowserEventSink::SendKeys(const wchar_t* input_string) { + SetFocusToChrome(); + simulate_input::SendString(input_string); +} + +void WebBrowserEventSink::SendMouseClick(int x, int y, + simulate_input::MouseButton button) { + simulate_input::SendMouseClick(GetRendererWindow(), x, y, button); } void WebBrowserEventSink::ConnectToChromeFrame() { @@ -875,7 +583,7 @@ void WebBrowserEventSink::DisconnectFromChromeFrame() { } } -HWND WebBrowserEventSink::GetTabWindow() { +HWND WebBrowserEventSink::GetRendererWindow() { DCHECK(chrome_frame_); HWND renderer_window = NULL; ScopedComPtr<IOleWindow> ole_window; @@ -893,7 +601,7 @@ HWND WebBrowserEventSink::GetTabWindow() { renderer_window = GetWindow(chrome_tab_window, GW_CHILD); } - DCHECK(IsWindow(renderer_window)); + EXPECT_TRUE(IsWindow(renderer_window)); return renderer_window; } @@ -905,4 +613,39 @@ HRESULT WebBrowserEventSink::SetWebBrowser(IWebBrowser2* web_browser2) { return hr; } +void WebBrowserEventSink::ExpectRendererWindowHasfocus() { + HWND renderer_window = GetRendererWindow(); + EXPECT_TRUE(IsWindow(renderer_window)); + + for (HWND first_child = renderer_window; + IsWindow(first_child); first_child = GetWindow(first_child, GW_CHILD)) { + renderer_window = first_child; + } + + wchar_t class_name[MAX_PATH] = {0}; + GetClassName(renderer_window, class_name, arraysize(class_name)); + EXPECT_EQ(0, _wcsicmp(class_name, L"Chrome_RenderWidgetHostHWND")); + + DWORD renderer_thread = 0; + DWORD renderer_process = 0; + renderer_thread = GetWindowThreadProcessId(renderer_window, + &renderer_process); + + ASSERT_TRUE(AttachThreadInput(GetCurrentThreadId(), renderer_thread, TRUE)); + HWND focus_window = GetFocus(); + EXPECT_TRUE(focus_window == renderer_window); + EXPECT_TRUE(AttachThreadInput(GetCurrentThreadId(), renderer_thread, FALSE)); +} + +void WebBrowserEventSink::Exec(const GUID* cmd_group_guid, DWORD command_id, + DWORD cmd_exec_opt, VARIANT* in_args, + VARIANT* out_args) { + ScopedComPtr<IOleCommandTarget> shell_browser_cmd_target; + DoQueryService(SID_STopLevelBrowser, web_browser2_, + shell_browser_cmd_target.Receive()); + ASSERT_TRUE(NULL != shell_browser_cmd_target); + EXPECT_HRESULT_SUCCEEDED(shell_browser_cmd_target->Exec(cmd_group_guid, + command_id, cmd_exec_opt, in_args, out_args)); +} + } // namespace chrome_frame_test |