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" |
(...skipping 20 matching lines...) Expand all Loading... |
31 | 31 |
32 const wchar_t kShellTrayWindowName[] = L"Shell_TrayWnd"; | 32 const wchar_t kShellTrayWindowName[] = L"Shell_TrayWnd"; |
33 const int kWindowBorderRadius = 14; | 33 const int kWindowBorderRadius = 14; |
34 | 34 |
35 } // namespace anonymous | 35 } // namespace anonymous |
36 | 36 |
37 namespace remoting { | 37 namespace remoting { |
38 | 38 |
39 class DisconnectWindowWin : public DisconnectWindow { | 39 class DisconnectWindowWin : public DisconnectWindow { |
40 public: | 40 public: |
41 DisconnectWindowWin(); | 41 explicit DisconnectWindowWin(const UiStrings* ui_strings); |
42 virtual ~DisconnectWindowWin(); | 42 virtual ~DisconnectWindowWin(); |
43 | 43 |
44 // DisconnectWindow interface. | 44 // DisconnectWindow interface. |
45 virtual bool Show(const UiStrings& ui_strings, | 45 virtual bool Show(const base::Closure& disconnect_callback, |
46 const base::Closure& disconnect_callback, | |
47 const std::string& username) OVERRIDE; | 46 const std::string& username) OVERRIDE; |
48 virtual void Hide() OVERRIDE; | 47 virtual void Hide() OVERRIDE; |
49 | 48 |
50 private: | 49 private: |
51 static BOOL CALLBACK DialogProc(HWND hwnd, UINT message, WPARAM wparam, | 50 static BOOL CALLBACK DialogProc(HWND hwnd, UINT message, WPARAM wparam, |
52 LPARAM lparam); | 51 LPARAM lparam); |
53 | 52 |
54 BOOL OnDialogMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); | 53 BOOL OnDialogMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); |
55 | 54 |
56 // Creates the dialog window and registers the disconnect hot key. | 55 // Creates the dialog window and registers the disconnect hot key. |
57 bool BeginDialog(const UiStrings& ui_strings, | 56 bool BeginDialog(const std::string& username); |
58 const std::string& username); | |
59 | 57 |
60 // Closes the dialog, unregisters the hot key and invokes the disconnect | 58 // Closes the dialog, unregisters the hot key and invokes the disconnect |
61 // callback, if set. | 59 // callback, if set. |
62 void EndDialog(); | 60 void EndDialog(); |
63 | 61 |
64 // Trys to position the dialog window above the taskbar. | 62 // Trys to position the dialog window above the taskbar. |
65 void SetDialogPosition(); | 63 void SetDialogPosition(); |
66 | 64 |
67 // Applies localization string and resizes the dialog. | 65 // Applies localization string and resizes the dialog. |
68 bool SetStrings(const UiStrings& strings, const string16& username); | 66 bool SetStrings(const string16& username); |
69 | 67 |
70 base::Closure disconnect_callback_; | 68 base::Closure disconnect_callback_; |
71 HWND hwnd_; | 69 HWND hwnd_; |
72 bool has_hotkey_; | 70 bool has_hotkey_; |
73 base::win::ScopedGDIObject<HPEN> border_pen_; | 71 base::win::ScopedGDIObject<HPEN> border_pen_; |
74 | 72 |
| 73 // Points to the localized strings. |
| 74 const UiStrings* ui_strings_; |
| 75 |
75 DISALLOW_COPY_AND_ASSIGN(DisconnectWindowWin); | 76 DISALLOW_COPY_AND_ASSIGN(DisconnectWindowWin); |
76 }; | 77 }; |
77 | 78 |
78 static int GetControlTextWidth(HWND control) { | 79 static int GetControlTextWidth(HWND control) { |
79 RECT rect = {0, 0, 0, 0}; | 80 RECT rect = {0, 0, 0, 0}; |
80 WCHAR text[256]; | 81 WCHAR text[256]; |
81 int result = GetWindowText(control, text, arraysize(text)); | 82 int result = GetWindowText(control, text, arraysize(text)); |
82 if (result) { | 83 if (result) { |
83 base::win::ScopedGetDC dc(control); | 84 base::win::ScopedGetDC dc(control); |
84 base::win::ScopedSelectObject font( | 85 base::win::ScopedSelectObject font( |
85 dc, (HFONT)SendMessage(control, WM_GETFONT, 0, 0)); | 86 dc, (HFONT)SendMessage(control, WM_GETFONT, 0, 0)); |
86 DrawText(dc, text, -1, &rect, DT_CALCRECT | DT_SINGLELINE); | 87 DrawText(dc, text, -1, &rect, DT_CALCRECT | DT_SINGLELINE); |
87 } | 88 } |
88 return rect.right; | 89 return rect.right; |
89 } | 90 } |
90 | 91 |
91 DisconnectWindowWin::DisconnectWindowWin() | 92 DisconnectWindowWin::DisconnectWindowWin(const UiStrings* ui_strings) |
92 : hwnd_(NULL), | 93 : hwnd_(NULL), |
93 has_hotkey_(false), | 94 has_hotkey_(false), |
94 border_pen_(CreatePen(PS_SOLID, 5, | 95 border_pen_(CreatePen(PS_SOLID, 5, |
95 RGB(0.13 * 255, 0.69 * 255, 0.11 * 255))) { | 96 RGB(0.13 * 255, 0.69 * 255, 0.11 * 255))), |
| 97 ui_strings_(ui_strings) { |
96 } | 98 } |
97 | 99 |
98 DisconnectWindowWin::~DisconnectWindowWin() { | 100 DisconnectWindowWin::~DisconnectWindowWin() { |
99 Hide(); | 101 Hide(); |
100 } | 102 } |
101 | 103 |
102 bool DisconnectWindowWin::Show(const UiStrings& ui_strings, | 104 bool DisconnectWindowWin::Show(const base::Closure& disconnect_callback, |
103 const base::Closure& disconnect_callback, | |
104 const std::string& username) { | 105 const std::string& username) { |
105 DCHECK(disconnect_callback_.is_null()); | 106 DCHECK(disconnect_callback_.is_null()); |
106 DCHECK(!disconnect_callback.is_null()); | 107 DCHECK(!disconnect_callback.is_null()); |
107 | 108 |
108 disconnect_callback_ = disconnect_callback; | 109 disconnect_callback_ = disconnect_callback; |
109 | 110 |
110 if (BeginDialog(ui_strings, username)) { | 111 if (BeginDialog(username)) { |
111 return true; | 112 return true; |
112 } else { | 113 } else { |
113 Hide(); | 114 Hide(); |
114 return false; | 115 return false; |
115 } | 116 } |
116 } | 117 } |
117 | 118 |
118 void DisconnectWindowWin::Hide() { | 119 void DisconnectWindowWin::Hide() { |
119 // Clear the |disconnect_callback_| so it won't be invoked by EndDialog(). | 120 // Clear the |disconnect_callback_| so it won't be invoked by EndDialog(). |
120 disconnect_callback_.Reset(); | 121 disconnect_callback_.Reset(); |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
202 RoundRect(hdc, rect.left, rect.top, rect.right - 1, rect.bottom - 1, | 203 RoundRect(hdc, rect.left, rect.top, rect.right - 1, rect.bottom - 1, |
203 kWindowBorderRadius, kWindowBorderRadius); | 204 kWindowBorderRadius, kWindowBorderRadius); |
204 } | 205 } |
205 EndPaint(hwnd_, &ps); | 206 EndPaint(hwnd_, &ps); |
206 return TRUE; | 207 return TRUE; |
207 } | 208 } |
208 } | 209 } |
209 return FALSE; | 210 return FALSE; |
210 } | 211 } |
211 | 212 |
212 bool DisconnectWindowWin::BeginDialog(const UiStrings& ui_strings, | 213 bool DisconnectWindowWin::BeginDialog(const std::string& username) { |
213 const std::string& username) { | |
214 DCHECK(!hwnd_); | 214 DCHECK(!hwnd_); |
215 | 215 |
216 // Load the dialog resource so that we can modify the RTL flags if necessary. | 216 // Load the dialog resource so that we can modify the RTL flags if necessary. |
217 HMODULE module = base::GetModuleFromAddress(&DialogProc); | 217 HMODULE module = base::GetModuleFromAddress(&DialogProc); |
218 HRSRC dialog_resource = | 218 HRSRC dialog_resource = |
219 FindResource(module, MAKEINTRESOURCE(IDD_DISCONNECT), RT_DIALOG); | 219 FindResource(module, MAKEINTRESOURCE(IDD_DISCONNECT), RT_DIALOG); |
220 if (!dialog_resource) | 220 if (!dialog_resource) |
221 return false; | 221 return false; |
222 | 222 |
223 HGLOBAL dialog_template = LoadResource(module, dialog_resource); | 223 HGLOBAL dialog_template = LoadResource(module, dialog_resource); |
224 if (!dialog_template) | 224 if (!dialog_template) |
225 return false; | 225 return false; |
226 | 226 |
227 DLGTEMPLATE* dialog_pointer = | 227 DLGTEMPLATE* dialog_pointer = |
228 reinterpret_cast<DLGTEMPLATE*>(LockResource(dialog_template)); | 228 reinterpret_cast<DLGTEMPLATE*>(LockResource(dialog_template)); |
229 if (!dialog_pointer) | 229 if (!dialog_pointer) |
230 return false; | 230 return false; |
231 | 231 |
232 // The actual resource type is DLGTEMPLATEEX, but this is not defined in any | 232 // The actual resource type is DLGTEMPLATEEX, but this is not defined in any |
233 // standard headers, so we treat it as a generic pointer and manipulate the | 233 // standard headers, so we treat it as a generic pointer and manipulate the |
234 // correct offsets explicitly. | 234 // correct offsets explicitly. |
235 scoped_array<unsigned char> rtl_dialog_template; | 235 scoped_array<unsigned char> rtl_dialog_template; |
236 if (ui_strings.direction == UiStrings::RTL) { | 236 if (ui_strings_->direction == UiStrings::RTL) { |
237 unsigned long dialog_template_size = | 237 unsigned long dialog_template_size = |
238 SizeofResource(module, dialog_resource); | 238 SizeofResource(module, dialog_resource); |
239 rtl_dialog_template.reset(new unsigned char[dialog_template_size]); | 239 rtl_dialog_template.reset(new unsigned char[dialog_template_size]); |
240 memcpy(rtl_dialog_template.get(), dialog_pointer, dialog_template_size); | 240 memcpy(rtl_dialog_template.get(), dialog_pointer, dialog_template_size); |
241 DWORD* rtl_dwords = reinterpret_cast<DWORD*>(rtl_dialog_template.get()); | 241 DWORD* rtl_dwords = reinterpret_cast<DWORD*>(rtl_dialog_template.get()); |
242 rtl_dwords[2] |= (WS_EX_LAYOUTRTL | WS_EX_RTLREADING); | 242 rtl_dwords[2] |= (WS_EX_LAYOUTRTL | WS_EX_RTLREADING); |
243 dialog_pointer = reinterpret_cast<DLGTEMPLATE*>(rtl_dwords); | 243 dialog_pointer = reinterpret_cast<DLGTEMPLATE*>(rtl_dwords); |
244 } | 244 } |
245 | 245 |
246 hwnd_ = CreateDialogIndirectParam(module, dialog_pointer, NULL, | 246 hwnd_ = CreateDialogIndirectParam(module, dialog_pointer, NULL, |
247 DialogProc, reinterpret_cast<LPARAM>(this)); | 247 DialogProc, reinterpret_cast<LPARAM>(this)); |
248 if (!hwnd_) | 248 if (!hwnd_) |
249 return false; | 249 return false; |
250 | 250 |
251 // Set up handler for Ctrl-Alt-Esc shortcut. | 251 // Set up handler for Ctrl-Alt-Esc shortcut. |
252 if (!has_hotkey_ && RegisterHotKey(hwnd_, DISCONNECT_HOTKEY_ID, | 252 if (!has_hotkey_ && RegisterHotKey(hwnd_, DISCONNECT_HOTKEY_ID, |
253 MOD_ALT | MOD_CONTROL, VK_ESCAPE)) { | 253 MOD_ALT | MOD_CONTROL, VK_ESCAPE)) { |
254 has_hotkey_ = true; | 254 has_hotkey_ = true; |
255 } | 255 } |
256 | 256 |
257 if (!SetStrings(ui_strings, UTF8ToUTF16(username))) | 257 if (!SetStrings(UTF8ToUTF16(username))) |
258 return false; | 258 return false; |
259 | 259 |
260 SetDialogPosition(); | 260 SetDialogPosition(); |
261 ShowWindow(hwnd_, SW_SHOW); | 261 ShowWindow(hwnd_, SW_SHOW); |
262 return IsWindowVisible(hwnd_) != FALSE; | 262 return IsWindowVisible(hwnd_) != FALSE; |
263 } | 263 } |
264 | 264 |
265 void DisconnectWindowWin::EndDialog() { | 265 void DisconnectWindowWin::EndDialog() { |
266 if (has_hotkey_) { | 266 if (has_hotkey_) { |
267 UnregisterHotKey(hwnd_, DISCONNECT_HOTKEY_ID); | 267 UnregisterHotKey(hwnd_, DISCONNECT_HOTKEY_ID); |
(...skipping 22 matching lines...) Expand all Loading... |
290 GetWindowRect(hwnd_, &window_rect)) { | 290 GetWindowRect(hwnd_, &window_rect)) { |
291 int window_width = window_rect.right - window_rect.left; | 291 int window_width = window_rect.right - window_rect.left; |
292 int window_height = window_rect.bottom - window_rect.top; | 292 int window_height = window_rect.bottom - window_rect.top; |
293 int top = monitor_info.rcWork.bottom - window_height; | 293 int top = monitor_info.rcWork.bottom - window_height; |
294 int left = (monitor_info.rcWork.right + monitor_info.rcWork.left - | 294 int left = (monitor_info.rcWork.right + monitor_info.rcWork.left - |
295 window_width) / 2; | 295 window_width) / 2; |
296 SetWindowPos(hwnd_, NULL, left, top, 0, 0, SWP_NOSIZE | SWP_NOZORDER); | 296 SetWindowPos(hwnd_, NULL, left, top, 0, 0, SWP_NOSIZE | SWP_NOZORDER); |
297 } | 297 } |
298 } | 298 } |
299 | 299 |
300 bool DisconnectWindowWin::SetStrings(const UiStrings& ui_strings, | 300 bool DisconnectWindowWin::SetStrings(const string16& username) { |
301 const string16& username) { | 301 if (!SetWindowText(hwnd_, ui_strings_->product_name.c_str())) |
302 if (!SetWindowText(hwnd_, ui_strings.product_name.c_str())) | |
303 return false; | 302 return false; |
304 | 303 |
305 // Localize the disconnect button text and measure length of the old and new | 304 // Localize the disconnect button text and measure length of the old and new |
306 // labels. | 305 // labels. |
307 HWND disconnect_button = GetDlgItem(hwnd_, IDC_DISCONNECT); | 306 HWND disconnect_button = GetDlgItem(hwnd_, IDC_DISCONNECT); |
308 if (!disconnect_button) | 307 if (!disconnect_button) |
309 return false; | 308 return false; |
310 int button_old_required_width = GetControlTextWidth(disconnect_button); | 309 int button_old_required_width = GetControlTextWidth(disconnect_button); |
311 if (!SetWindowText(disconnect_button, | 310 if (!SetWindowText(disconnect_button, |
312 ui_strings.disconnect_button_text.c_str())) { | 311 ui_strings_->disconnect_button_text.c_str())) { |
313 return false; | 312 return false; |
314 } | 313 } |
315 int button_new_required_width = GetControlTextWidth(disconnect_button); | 314 int button_new_required_width = GetControlTextWidth(disconnect_button); |
316 int button_width_delta = | 315 int button_width_delta = |
317 button_new_required_width - button_old_required_width; | 316 button_new_required_width - button_old_required_width; |
318 | 317 |
319 // Format and truncate "Your desktop is shared with ..." message. | 318 // Format and truncate "Your desktop is shared with ..." message. |
320 string16 text = ReplaceStringPlaceholders(ui_strings.disconnect_message, | 319 string16 text = ReplaceStringPlaceholders(ui_strings_->disconnect_message, |
321 username, NULL); | 320 username, NULL); |
322 if (text.length() > kMaxSharingWithTextLength) | 321 if (text.length() > kMaxSharingWithTextLength) |
323 text.erase(kMaxSharingWithTextLength); | 322 text.erase(kMaxSharingWithTextLength); |
324 | 323 |
325 // Set localized and truncated "Your desktop is shared with ..." message and | 324 // Set localized and truncated "Your desktop is shared with ..." message and |
326 // measure length of the old and new text. | 325 // measure length of the old and new text. |
327 HWND sharing_with_label = GetDlgItem(hwnd_, IDC_DISCONNECT_SHARINGWITH); | 326 HWND sharing_with_label = GetDlgItem(hwnd_, IDC_DISCONNECT_SHARINGWITH); |
328 if (!sharing_with_label) | 327 if (!sharing_with_label) |
329 return false; | 328 return false; |
330 int label_old_required_width = GetControlTextWidth(sharing_with_label); | 329 int label_old_required_width = GetControlTextWidth(sharing_with_label); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
379 HRGN rgn = CreateRoundRectRgn(0, 0, width, height, kWindowBorderRadius, | 378 HRGN rgn = CreateRoundRectRgn(0, 0, width, height, kWindowBorderRadius, |
380 kWindowBorderRadius); | 379 kWindowBorderRadius); |
381 if (!rgn) | 380 if (!rgn) |
382 return false; | 381 return false; |
383 if (!SetWindowRgn(hwnd_, rgn, TRUE)) | 382 if (!SetWindowRgn(hwnd_, rgn, TRUE)) |
384 return false; | 383 return false; |
385 | 384 |
386 return true; | 385 return true; |
387 } | 386 } |
388 | 387 |
389 scoped_ptr<DisconnectWindow> DisconnectWindow::Create() { | 388 scoped_ptr<DisconnectWindow> DisconnectWindow::Create( |
390 return scoped_ptr<DisconnectWindow>(new DisconnectWindowWin()); | 389 const UiStrings* ui_strings) { |
| 390 return scoped_ptr<DisconnectWindow>(new DisconnectWindowWin(ui_strings)); |
391 } | 391 } |
392 | 392 |
393 } // namespace remoting | 393 } // namespace remoting |
OLD | NEW |