1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ui/base/win/foreground_helper.h"
7 #include "base/logging.h"
8 #include "ui/gfx/win/window_impl.h"
13 HRESULT
ForegroundHelper::SetForeground(HWND window
) {
14 DCHECK(::IsWindow(window
));
15 ForegroundHelper foreground_helper
;
16 return foreground_helper
.ForegroundHotKey(window
);
19 HRESULT
ForegroundHelper::ForegroundHotKey(HWND window
) {
20 // This implementation registers a hot key (F22) and then
21 // triggers the hot key. When receiving the hot key, we'll
22 // be in the foreground and allowed to move the target window
23 // into the foreground too.
25 set_window_style(WS_POPUP
);
26 Init(NULL
, gfx::Rect());
28 static const int kHotKeyId
= 0x0000baba;
29 static const int kHotKeyWaitTimeout
= 2000;
31 // Store the target window into our USERDATA for use in our
34 RegisterHotKey(hwnd(), kHotKeyId
, 0, VK_F22
);
36 // If the calling thread is not yet a UI thread, call PeekMessage
37 // to ensure creation of its message queue.
39 PeekMessage(&msg
, NULL
, 0, 0, PM_NOREMOVE
);
43 hotkey
.type
= INPUT_KEYBOARD
;
44 hotkey
.ki
.wVk
= VK_F22
;
45 if (1 != SendInput(1, &hotkey
, sizeof(hotkey
))) {
46 LOG(WARNING
) << "Failed to send input; GetLastError(): " << GetLastError();
50 // There are scenarios where the WM_HOTKEY is not dispatched by the
51 // the corresponding foreground thread. To prevent us from indefinitely
52 // waiting for the hotkey, we set a timer and exit the loop.
53 SetTimer(hwnd(), kHotKeyId
, kHotKeyWaitTimeout
, NULL
);
55 // Loop until we get the key or the timer fires.
56 while (GetMessage(&msg
, NULL
, 0, 0)) {
57 TranslateMessage(&msg
);
58 DispatchMessage(&msg
);
60 if (WM_HOTKEY
== msg
.message
)
62 if (WM_TIMER
== msg
.message
) {
63 SetForegroundWindow(window
);
68 UnregisterHotKey(hwnd(), kHotKeyId
);
69 KillTimer(hwnd(), kHotKeyId
);
70 DestroyWindow(hwnd());
75 // Handle the registered Hotkey being pressed.
76 void ForegroundHelper::OnHotKey(int id
, UINT vcode
, UINT modifiers
) {
77 SetForegroundWindow(window_
);