OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "remoting/host/disconnect_window.h" | 5 #include "remoting/host/disconnect_window.h" |
6 | 6 |
7 #include <windows.h> | 7 #include <windows.h> |
8 | 8 |
9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/string_util.h" | 11 #include "base/string_util.h" |
12 #include "base/utf_string_conversions.h" | 12 #include "base/utf_string_conversions.h" |
13 #include "base/win/scoped_gdi_object.h" | 13 #include "base/win/scoped_gdi_object.h" |
14 #include "base/win/scoped_hdc.h" | 14 #include "base/win/scoped_hdc.h" |
15 #include "base/win/scoped_select_object.h" | 15 #include "base/win/scoped_select_object.h" |
16 #include "remoting/host/chromoting_host.h" | 16 #include "remoting/host/chromoting_host.h" |
17 #include "remoting/host/host_ui_resource.h" | 17 #include "remoting/host/host_ui_resource.h" |
18 #include "remoting/host/ui_strings.h" | 18 #include "remoting/host/ui_strings.h" |
19 | 19 |
20 // TODO(garykac): Lots of duplicated code in this file and | 20 // TODO(garykac): Lots of duplicated code in this file and |
21 // continue_window_win.cc. If we need to expand this then we should | 21 // continue_window_win.cc. If we need to expand this then we should |
22 // create a class with the shared code. | 22 // create a class with the shared code. |
23 | 23 |
24 // HMODULE from DllMain/WinMain. This is needed to find our dialog resource. | 24 // HMODULE from DllMain/WinMain. This is needed to find our dialog resource. |
25 // This is defined in: | 25 // This is defined in: |
26 // Plugin: host_plugin.cc | 26 // Plugin: host_plugin.cc |
27 // SimpleHost: simple_host_process.cc | 27 // SimpleHost: simple_host_process.cc |
28 extern HMODULE g_hModule; | 28 extern HMODULE g_hModule; |
29 | 29 |
30 namespace { | |
31 | |
30 const int DISCONNECT_HOTKEY_ID = 1000; | 32 const int DISCONNECT_HOTKEY_ID = 1000; |
31 const int kWindowBorderRadius = 14; | 33 const int kWindowBorderRadius = 14; |
34 const WCHAR kShellTrayWindowName[] = L"Shell_TrayWnd"; | |
alexeypa (please no reviews)
2012/08/10 17:28:02
nit: WCHAR -> wchar_t. L"" gives a wide string, wh
Wez
2012/08/10 20:06:17
Which are the same thing on Windows. ;)
Wez
2012/08/10 20:06:17
Done.
alexeypa (please no reviews)
2012/08/10 20:30:03
Yeah, I know. It is messy.
| |
35 | |
36 } // namespace anonymous | |
32 | 37 |
33 namespace remoting { | 38 namespace remoting { |
34 | 39 |
35 class DisconnectWindowWin : public DisconnectWindow { | 40 class DisconnectWindowWin : public DisconnectWindow { |
36 public: | 41 public: |
37 DisconnectWindowWin(); | 42 DisconnectWindowWin(); |
38 virtual ~DisconnectWindowWin(); | 43 virtual ~DisconnectWindowWin(); |
39 | 44 |
40 virtual void Show(ChromotingHost* host, | 45 virtual void Show(ChromotingHost* host, |
41 const DisconnectCallback& disconnect_callback, | 46 const DisconnectCallback& disconnect_callback, |
42 const std::string& username) OVERRIDE; | 47 const std::string& username) OVERRIDE; |
43 virtual void Hide() OVERRIDE; | 48 virtual void Hide() OVERRIDE; |
44 | 49 |
45 private: | 50 private: |
46 static BOOL CALLBACK DialogProc(HWND hwmd, UINT msg, WPARAM wParam, | 51 static BOOL CALLBACK DialogProc(HWND hwmd, UINT msg, WPARAM wParam, |
47 LPARAM lParam); | 52 LPARAM lParam); |
48 | 53 |
49 BOOL OnDialogMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); | 54 BOOL OnDialogMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); |
50 | 55 |
51 void ShutdownHost(); | 56 void ShutdownHost(); |
52 void EndDialog(); | 57 void EndDialog(); |
53 void SetStrings(const UiStrings& strings, const std::string& username); | 58 void SetStrings(const UiStrings& strings, const std::string& username); |
59 void SetDialogPosition(); | |
54 | 60 |
55 DisconnectCallback disconnect_callback_; | 61 DisconnectCallback disconnect_callback_; |
56 HWND hwnd_; | 62 HWND hwnd_; |
57 bool has_hotkey_; | 63 bool has_hotkey_; |
58 base::win::ScopedGDIObject<HPEN> border_pen_; | 64 base::win::ScopedGDIObject<HPEN> border_pen_; |
59 | 65 |
60 DISALLOW_COPY_AND_ASSIGN(DisconnectWindowWin); | 66 DISALLOW_COPY_AND_ASSIGN(DisconnectWindowWin); |
61 }; | 67 }; |
62 | 68 |
63 DisconnectWindowWin::DisconnectWindowWin() | 69 DisconnectWindowWin::DisconnectWindowWin() |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
102 ShutdownHost(); | 108 ShutdownHost(); |
103 return TRUE; | 109 return TRUE; |
104 } | 110 } |
105 return FALSE; | 111 return FALSE; |
106 | 112 |
107 // Ensure we don't try to use the HWND anymore. | 113 // Ensure we don't try to use the HWND anymore. |
108 case WM_DESTROY: | 114 case WM_DESTROY: |
109 hwnd_ = NULL; | 115 hwnd_ = NULL; |
110 return TRUE; | 116 return TRUE; |
111 | 117 |
118 // Ensure the dialog stays visible if the work area dimensions change. | |
119 case WM_SETTINGCHANGE: | |
120 if (wParam == SPI_SETWORKAREA) | |
121 SetDialogPosition(); | |
122 return TRUE; | |
123 | |
124 // Ensure the dialog stays visible if the display dimensions change. | |
125 case WM_DISPLAYCHANGE: | |
126 SetDialogPosition(); | |
127 return TRUE; | |
128 | |
112 // Handle the disconnect hot-key. | 129 // Handle the disconnect hot-key. |
113 case WM_HOTKEY: | 130 case WM_HOTKEY: |
114 EndDialog(); | 131 EndDialog(); |
115 ShutdownHost(); | 132 ShutdownHost(); |
116 return TRUE; | 133 return TRUE; |
117 | 134 |
118 // Let the window be draggable by its client area by responding | 135 // Let the window be draggable by its client area by responding |
119 // that the entire window is the title bar. | 136 // that the entire window is the title bar. |
120 case WM_NCHITTEST: | 137 case WM_NCHITTEST: |
121 SetWindowLong(hwnd, DWL_MSGRESULT, HTCAPTION); | 138 SetWindowLong(hwnd, DWL_MSGRESULT, HTCAPTION); |
122 return TRUE; | 139 return TRUE; |
123 | 140 |
124 case WM_PAINT: | 141 case WM_PAINT: { |
142 PAINTSTRUCT ps; | |
143 HDC hdc = BeginPaint(hwnd_, &ps); | |
144 RECT rect; | |
145 GetClientRect(hwnd_, &rect); | |
125 { | 146 { |
126 PAINTSTRUCT ps; | 147 base::win::ScopedSelectObject border(hdc, border_pen_); |
127 HDC hdc = BeginPaint(hwnd_, &ps); | 148 base::win::ScopedSelectObject brush(hdc, GetStockObject(NULL_BRUSH)); |
128 RECT rect; | 149 RoundRect(hdc, rect.left, rect.top, rect.right - 1, rect.bottom - 1, |
129 GetClientRect(hwnd_, &rect); | 150 kWindowBorderRadius, kWindowBorderRadius); |
130 { | |
131 base::win::ScopedSelectObject border(hdc, border_pen_); | |
132 base::win::ScopedSelectObject brush(hdc, GetStockObject(NULL_BRUSH)); | |
133 RoundRect(hdc, rect.left, rect.top, rect.right - 1, rect.bottom - 1, | |
134 kWindowBorderRadius, kWindowBorderRadius); | |
135 } | |
136 EndPaint(hwnd_, &ps); | |
137 return TRUE; | |
138 } | 151 } |
152 EndPaint(hwnd_, &ps); | |
153 return TRUE; | |
154 } | |
139 } | 155 } |
140 return FALSE; | 156 return FALSE; |
141 } | 157 } |
142 | 158 |
143 void DisconnectWindowWin::Show(ChromotingHost* host, | 159 void DisconnectWindowWin::Show(ChromotingHost* host, |
144 const DisconnectCallback& disconnect_callback, | 160 const DisconnectCallback& disconnect_callback, |
145 const std::string& username) { | 161 const std::string& username) { |
146 CHECK(!hwnd_); | 162 CHECK(!hwnd_); |
147 disconnect_callback_ = disconnect_callback; | 163 disconnect_callback_ = disconnect_callback; |
148 | 164 |
(...skipping 26 matching lines...) Expand all Loading... | |
175 (DLGPROC)DialogProc, (LPARAM)this); | 191 (DLGPROC)DialogProc, (LPARAM)this); |
176 CHECK(hwnd_); | 192 CHECK(hwnd_); |
177 | 193 |
178 // Set up handler for Ctrl-Alt-Esc shortcut. | 194 // Set up handler for Ctrl-Alt-Esc shortcut. |
179 if (!has_hotkey_ && RegisterHotKey(hwnd_, DISCONNECT_HOTKEY_ID, | 195 if (!has_hotkey_ && RegisterHotKey(hwnd_, DISCONNECT_HOTKEY_ID, |
180 MOD_ALT | MOD_CONTROL, VK_ESCAPE)) { | 196 MOD_ALT | MOD_CONTROL, VK_ESCAPE)) { |
181 has_hotkey_ = true; | 197 has_hotkey_ = true; |
182 } | 198 } |
183 | 199 |
184 SetStrings(host->ui_strings(), username); | 200 SetStrings(host->ui_strings(), username); |
185 | 201 SetDialogPosition(); |
186 // Try to center the window above the task-bar. If that fails, use the | |
187 // primary monitor. If that fails (very unlikely), use the default position. | |
188 HWND taskbar = FindWindow(L"Shell_TrayWnd", NULL); | |
189 HMONITOR monitor = MonitorFromWindow(taskbar, MONITOR_DEFAULTTOPRIMARY); | |
190 MONITORINFO monitor_info = {sizeof(monitor_info)}; | |
191 RECT window_rect; | |
192 if (GetMonitorInfo(monitor, &monitor_info) && | |
193 GetWindowRect(hwnd_, &window_rect)) { | |
194 int window_width = window_rect.right - window_rect.left; | |
195 int window_height = window_rect.bottom - window_rect.top; | |
196 int top = monitor_info.rcWork.bottom - window_height; | |
197 int left = (monitor_info.rcWork.right + monitor_info.rcWork.left - | |
198 window_width) / 2; | |
199 SetWindowPos(hwnd_, NULL, left, top, 0, 0, SWP_NOSIZE | SWP_NOZORDER); | |
200 } | |
201 ShowWindow(hwnd_, SW_SHOW); | 202 ShowWindow(hwnd_, SW_SHOW); |
202 } | 203 } |
203 | 204 |
204 void DisconnectWindowWin::ShutdownHost() { | 205 void DisconnectWindowWin::ShutdownHost() { |
205 CHECK(!disconnect_callback_.is_null()); | 206 CHECK(!disconnect_callback_.is_null()); |
206 disconnect_callback_.Run(); | 207 disconnect_callback_.Run(); |
207 } | 208 } |
208 | 209 |
209 static int GetControlTextWidth(HWND control) { | 210 static int GetControlTextWidth(HWND control) { |
210 RECT rect = {0, 0, 0, 0}; | 211 RECT rect = {0, 0, 0, 0}; |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
266 GetWindowRect(hwnd_, &window_rect); | 267 GetWindowRect(hwnd_, &window_rect); |
267 int width = (window_rect.right - window_rect.left) + | 268 int width = (window_rect.right - window_rect.left) + |
268 button_width_delta + label_width_delta; | 269 button_width_delta + label_width_delta; |
269 int height = window_rect.bottom - window_rect.top; | 270 int height = window_rect.bottom - window_rect.top; |
270 SetWindowPos(hwnd_, NULL, 0, 0, width, height, SWP_NOMOVE|SWP_NOZORDER); | 271 SetWindowPos(hwnd_, NULL, 0, 0, width, height, SWP_NOMOVE|SWP_NOZORDER); |
271 HRGN rgn = CreateRoundRectRgn(0, 0, width, height, kWindowBorderRadius, | 272 HRGN rgn = CreateRoundRectRgn(0, 0, width, height, kWindowBorderRadius, |
272 kWindowBorderRadius); | 273 kWindowBorderRadius); |
273 SetWindowRgn(hwnd_, rgn, TRUE); | 274 SetWindowRgn(hwnd_, rgn, TRUE); |
274 } | 275 } |
275 | 276 |
277 void DisconnectWindowWin::SetDialogPosition() { | |
278 // Try to center the window above the task-bar. If that fails, use the | |
279 // primary monitor. If that fails (very unlikely), use the default position. | |
280 HWND taskbar = FindWindow(kShellTrayWindowName, NULL); | |
281 HMONITOR monitor = MonitorFromWindow(taskbar, MONITOR_DEFAULTTOPRIMARY); | |
282 MONITORINFO monitor_info = {sizeof(monitor_info)}; | |
283 RECT window_rect; | |
284 if (GetMonitorInfo(monitor, &monitor_info) && | |
285 GetWindowRect(hwnd_, &window_rect)) { | |
286 int window_width = window_rect.right - window_rect.left; | |
287 int window_height = window_rect.bottom - window_rect.top; | |
288 int top = monitor_info.rcWork.bottom - window_height; | |
289 int left = (monitor_info.rcWork.right + monitor_info.rcWork.left - | |
290 window_width) / 2; | |
291 SetWindowPos(hwnd_, NULL, left, top, 0, 0, SWP_NOSIZE | SWP_NOZORDER); | |
292 } | |
293 } | |
294 | |
276 void DisconnectWindowWin::Hide() { | 295 void DisconnectWindowWin::Hide() { |
277 EndDialog(); | 296 EndDialog(); |
278 } | 297 } |
279 | 298 |
280 void DisconnectWindowWin::EndDialog() { | 299 void DisconnectWindowWin::EndDialog() { |
281 if (has_hotkey_) { | 300 if (has_hotkey_) { |
282 UnregisterHotKey(hwnd_, DISCONNECT_HOTKEY_ID); | 301 UnregisterHotKey(hwnd_, DISCONNECT_HOTKEY_ID); |
283 has_hotkey_ = false; | 302 has_hotkey_ = false; |
284 } | 303 } |
285 | 304 |
286 if (hwnd_) { | 305 if (hwnd_) { |
287 ::DestroyWindow(hwnd_); | 306 ::DestroyWindow(hwnd_); |
288 hwnd_ = NULL; | 307 hwnd_ = NULL; |
289 } | 308 } |
290 } | 309 } |
291 | 310 |
292 scoped_ptr<DisconnectWindow> DisconnectWindow::Create() { | 311 scoped_ptr<DisconnectWindow> DisconnectWindow::Create() { |
293 return scoped_ptr<DisconnectWindow>(new DisconnectWindowWin()); | 312 return scoped_ptr<DisconnectWindow>(new DisconnectWindowWin()); |
294 } | 313 } |
295 | 314 |
296 } // namespace remoting | 315 } // namespace remoting |
OLD | NEW |