Chromium Code Reviews| 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 |