Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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" | |
| 14 #include "base/win/scoped_hdc.h" | |
| 15 #include "base/win/scoped_select_object.h" | |
| 13 #include "remoting/host/chromoting_host.h" | 16 #include "remoting/host/chromoting_host.h" |
| 14 // TODO(wez): The DisconnectWindow isn't plugin-specific, so shouldn't have | 17 // TODO(wez): The DisconnectWindow isn't plugin-specific, so shouldn't have |
| 15 // a dependency on the plugin's resource header. | 18 // a dependency on the plugin's resource header. |
| 16 #include "remoting/host/plugin/host_plugin_resource.h" | 19 #include "remoting/host/plugin/host_plugin_resource.h" |
| 17 #include "remoting/host/ui_strings.h" | 20 #include "remoting/host/ui_strings.h" |
| 18 | 21 |
| 19 // TODO(garykac): Lots of duplicated code in this file and | 22 // TODO(garykac): Lots of duplicated code in this file and |
| 20 // continue_window_win.cc. These global floating windows are temporary so | 23 // continue_window_win.cc. These global floating windows are temporary so |
| 21 // they should be deleted soon. If we need to expand this then we should | 24 // they should be deleted soon. If we need to expand this then we should |
| 22 // create a class with the shared code. | 25 // create a class with the shared code. |
| 23 | 26 |
| 24 // HMODULE from DllMain/WinMain. This is needed to find our dialog resource. | 27 // HMODULE from DllMain/WinMain. This is needed to find our dialog resource. |
| 25 // This is defined in: | 28 // This is defined in: |
| 26 // Plugin: host_plugin.cc | 29 // Plugin: host_plugin.cc |
| 27 // SimpleHost: simple_host_process.cc | 30 // SimpleHost: simple_host_process.cc |
| 28 extern HMODULE g_hModule; | 31 extern HMODULE g_hModule; |
| 29 | 32 |
| 30 const int DISCONNECT_HOTKEY_ID = 1000; | 33 const int DISCONNECT_HOTKEY_ID = 1000; |
| 34 const int kWindowBorderRadius = 14; | |
| 31 | 35 |
| 32 namespace remoting { | 36 namespace remoting { |
| 33 | 37 |
| 34 class DisconnectWindowWin : public DisconnectWindow { | 38 class DisconnectWindowWin : public DisconnectWindow { |
| 35 public: | 39 public: |
| 36 DisconnectWindowWin(); | 40 DisconnectWindowWin(); |
| 37 virtual ~DisconnectWindowWin(); | 41 virtual ~DisconnectWindowWin(); |
| 38 | 42 |
| 39 virtual void Show(remoting::ChromotingHost* host, | 43 virtual void Show(remoting::ChromotingHost* host, |
| 40 const std::string& username) OVERRIDE; | 44 const std::string& username) OVERRIDE; |
| 41 virtual void Hide() OVERRIDE; | 45 virtual void Hide() OVERRIDE; |
| 42 | 46 |
| 43 private: | 47 private: |
| 44 static BOOL CALLBACK DialogProc(HWND hwmd, UINT msg, WPARAM wParam, | 48 static BOOL CALLBACK DialogProc(HWND hwmd, UINT msg, WPARAM wParam, |
| 45 LPARAM lParam); | 49 LPARAM lParam); |
| 46 | 50 |
| 47 BOOL OnDialogMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); | 51 BOOL OnDialogMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); |
| 48 | 52 |
| 49 void ShutdownHost(); | 53 void ShutdownHost(); |
| 50 void EndDialog(int result); | 54 void EndDialog(int result); |
| 51 void SetStrings(const UiStrings& strings, const std::string& username); | 55 void SetStrings(const UiStrings& strings, const std::string& username); |
| 52 | 56 |
| 53 remoting::ChromotingHost* host_; | 57 remoting::ChromotingHost* host_; |
| 54 HWND hwnd_; | 58 HWND hwnd_; |
| 55 bool has_hotkey_; | 59 bool has_hotkey_; |
| 60 base::win::ScopedGDIObject<HPEN> border_pen_; | |
| 56 | 61 |
| 57 DISALLOW_COPY_AND_ASSIGN(DisconnectWindowWin); | 62 DISALLOW_COPY_AND_ASSIGN(DisconnectWindowWin); |
| 58 }; | 63 }; |
| 59 | 64 |
| 60 DisconnectWindowWin::DisconnectWindowWin() | 65 DisconnectWindowWin::DisconnectWindowWin() |
| 61 : host_(NULL), | 66 : host_(NULL), |
| 62 hwnd_(NULL), | 67 hwnd_(NULL), |
| 63 has_hotkey_(false) { | 68 has_hotkey_(false), |
| 69 border_pen_(CreatePen(PS_SOLID, 5, | |
| 70 RGB(0.13 * 255, 0.69 * 255, 0.11 * 255))) { | |
|
Wez
2011/10/20 20:28:58
nit: Is this the preferred way to express RGB valu
Jamie
2011/10/20 23:56:54
The fractions are copied from Dave's Mac implement
| |
| 64 } | 71 } |
| 65 | 72 |
| 66 DisconnectWindowWin::~DisconnectWindowWin() { | 73 DisconnectWindowWin::~DisconnectWindowWin() { |
| 67 EndDialog(0); | 74 EndDialog(0); |
| 68 } | 75 } |
| 69 | 76 |
| 70 BOOL CALLBACK DisconnectWindowWin::DialogProc(HWND hwnd, UINT msg, | 77 BOOL CALLBACK DisconnectWindowWin::DialogProc(HWND hwnd, UINT msg, |
| 71 WPARAM wParam, LPARAM lParam) { | 78 WPARAM wParam, LPARAM lParam) { |
| 72 DisconnectWindowWin* win = NULL; | 79 DisconnectWindowWin* win = NULL; |
| 73 if (msg == WM_INITDIALOG) { | 80 if (msg == WM_INITDIALOG) { |
| 74 win = reinterpret_cast<DisconnectWindowWin*>(lParam); | 81 win = reinterpret_cast<DisconnectWindowWin*>(lParam); |
| 75 CHECK(win); | 82 CHECK(win); |
| 76 SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR)win); | 83 SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR)win); |
| 77 } else { | 84 } else { |
| 78 LONG_PTR lp = GetWindowLongPtr(hwnd, DWLP_USER); | 85 LONG_PTR lp = GetWindowLongPtr(hwnd, DWLP_USER); |
| 79 win = reinterpret_cast<DisconnectWindowWin*>(lp); | 86 win = reinterpret_cast<DisconnectWindowWin*>(lp); |
| 80 } | 87 } |
| 81 if (win == NULL) | 88 if (win == NULL) |
| 82 return FALSE; | 89 return FALSE; |
| 83 return win->OnDialogMessage(hwnd, msg, wParam, lParam); | 90 return win->OnDialogMessage(hwnd, msg, wParam, lParam); |
| 84 } | 91 } |
| 85 | 92 |
| 86 BOOL DisconnectWindowWin::OnDialogMessage(HWND hwnd, UINT msg, | 93 BOOL DisconnectWindowWin::OnDialogMessage(HWND hwnd, UINT msg, |
| 87 WPARAM wParam, LPARAM lParam) { | 94 WPARAM wParam, LPARAM lParam) { |
| 88 switch (msg) { | 95 switch (msg) { |
| 89 case WM_HOTKEY: | 96 // Ignore close messages. |
| 90 ShutdownHost(); | 97 case WM_CLOSE: |
| 91 EndDialog(0); | |
| 92 return TRUE; | 98 return TRUE; |
| 93 case WM_CLOSE: | 99 |
| 94 // Ignore close messages. | 100 // Handle the Disconnect button. |
| 95 return TRUE; | |
| 96 case WM_DESTROY: | |
| 97 // Ensure we don't try to use the HWND anymore. | |
| 98 hwnd_ = NULL; | |
| 99 return TRUE; | |
| 100 case WM_COMMAND: | 101 case WM_COMMAND: |
| 101 switch (LOWORD(wParam)) { | 102 switch (LOWORD(wParam)) { |
| 102 case IDC_DISCONNECT: | 103 case IDC_DISCONNECT: |
| 103 ShutdownHost(); | 104 ShutdownHost(); |
| 104 EndDialog(LOWORD(wParam)); | 105 EndDialog(LOWORD(wParam)); |
| 105 return TRUE; | 106 return TRUE; |
| 106 } | 107 } |
| 108 return FALSE; | |
| 109 | |
| 110 // Ensure we don't try to use the HWND anymore. | |
| 111 case WM_DESTROY: | |
| 112 hwnd_ = NULL; | |
| 113 return TRUE; | |
| 114 | |
| 115 // Handle the disconnect hot-key. | |
| 116 case WM_HOTKEY: | |
| 117 ShutdownHost(); | |
| 118 EndDialog(0); | |
| 119 return TRUE; | |
| 120 | |
| 121 // Let the window be draggable by its client area by responding | |
| 122 // that the entire window is the title bar. | |
|
Wez
2011/10/20 20:28:58
Does this affect focus or clickability of widgets
Jamie
2011/10/20 23:56:54
No.
| |
| 123 case WM_NCHITTEST: | |
| 124 SetWindowLong(hwnd, DWL_MSGRESULT, HTCAPTION); | |
| 125 return TRUE; | |
| 126 | |
| 127 case WM_PAINT: | |
| 128 { | |
| 129 PAINTSTRUCT ps; | |
| 130 HDC hdc = BeginPaint(hwnd_, &ps); | |
| 131 RECT rect; | |
| 132 GetClientRect(hwnd_, &rect); | |
| 133 { | |
| 134 base::win::ScopedSelectObject border(hdc, border_pen_); | |
| 135 base::win::ScopedSelectObject brush(hdc, GetStockObject(NULL_BRUSH)); | |
| 136 RoundRect(hdc, rect.left, rect.top, rect.right - 1, rect.bottom - 1, | |
| 137 kWindowBorderRadius, kWindowBorderRadius); | |
| 138 } | |
| 139 EndPaint(hwnd_, &ps); | |
| 140 return TRUE; | |
| 141 } | |
| 107 } | 142 } |
| 108 return FALSE; | 143 return FALSE; |
| 109 } | 144 } |
| 110 | 145 |
| 111 void DisconnectWindowWin::Show(ChromotingHost* host, | 146 void DisconnectWindowWin::Show(ChromotingHost* host, |
| 112 const std::string& username) { | 147 const std::string& username) { |
| 113 host_ = host; | 148 host_ = host; |
| 114 | 149 |
| 115 CHECK(!hwnd_); | 150 CHECK(!hwnd_); |
| 116 hwnd_ = CreateDialogParam(g_hModule, MAKEINTRESOURCE(IDD_DISCONNECT), NULL, | 151 hwnd_ = CreateDialogParam(g_hModule, MAKEINTRESOURCE(IDD_DISCONNECT), NULL, |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 128 | 163 |
| 129 SetStrings(host->ui_strings(), username); | 164 SetStrings(host->ui_strings(), username); |
| 130 ShowWindow(hwnd_, SW_SHOW); | 165 ShowWindow(hwnd_, SW_SHOW); |
| 131 } | 166 } |
| 132 | 167 |
| 133 void DisconnectWindowWin::ShutdownHost() { | 168 void DisconnectWindowWin::ShutdownHost() { |
| 134 CHECK(host_); | 169 CHECK(host_); |
| 135 host_->Shutdown(NULL); | 170 host_->Shutdown(NULL); |
| 136 } | 171 } |
| 137 | 172 |
| 173 static int GetControlTextWidth(HWND control) { | |
| 174 WCHAR text[256]; | |
| 175 GetWindowText(control, text, arraysize(text)); | |
|
Wez
2011/10/20 20:28:58
Check the return value of GetWindowText(), otherwi
Jamie
2011/10/20 23:56:54
Done.
| |
| 176 base::win::ScopedGetDC dc(control); | |
| 177 base::win::ScopedSelectObject font( | |
| 178 dc, (HFONT)SendMessage(control, WM_GETFONT, 0, 0)); | |
| 179 RECT rect = {0, 0, 0, 0}; | |
| 180 DrawText(dc, text, -1, &rect, DT_CALCRECT|DT_SINGLELINE); | |
| 181 return rect.right; | |
| 182 } | |
| 183 | |
| 138 void DisconnectWindowWin::SetStrings(const UiStrings& strings, | 184 void DisconnectWindowWin::SetStrings(const UiStrings& strings, |
| 139 const std::string& username) { | 185 const std::string& username) { |
| 140 SetWindowText(hwnd_, strings.product_name.c_str()); | 186 SetWindowText(hwnd_, strings.product_name.c_str()); |
| 141 | 187 |
| 142 HWND hwndButton = GetDlgItem(hwnd_, IDC_DISCONNECT); | 188 HWND hwndButton = GetDlgItem(hwnd_, IDC_DISCONNECT); |
| 143 CHECK(hwndButton); | 189 CHECK(hwndButton); |
| 144 const WCHAR* label = | 190 const WCHAR* label = |
| 145 has_hotkey_ ? strings.disconnect_button_text_plus_shortcut.c_str() | 191 has_hotkey_ ? strings.disconnect_button_text_plus_shortcut.c_str() |
| 146 : strings.disconnect_button_text.c_str(); | 192 : strings.disconnect_button_text.c_str(); |
| 193 int button_old_required_width = GetControlTextWidth(hwndButton); | |
| 147 SetWindowText(hwndButton, label); | 194 SetWindowText(hwndButton, label); |
| 195 int button_new_required_width = GetControlTextWidth(hwndButton); | |
| 148 | 196 |
| 149 HWND hwndSharingWith = GetDlgItem(hwnd_, IDC_DISCONNECT_SHARINGWITH); | 197 HWND hwndSharingWith = GetDlgItem(hwnd_, IDC_DISCONNECT_SHARINGWITH); |
| 150 CHECK(hwndSharingWith); | 198 CHECK(hwndSharingWith); |
| 151 string16 text = ReplaceStringPlaceholders( | 199 string16 text = ReplaceStringPlaceholders( |
| 152 strings.disconnect_message, UTF8ToUTF16(username), NULL); | 200 strings.disconnect_message, UTF8ToUTF16(username), NULL); |
| 201 int label_old_required_width = GetControlTextWidth(hwndSharingWith); | |
| 153 SetWindowText(hwndSharingWith, text.c_str()); | 202 SetWindowText(hwndSharingWith, text.c_str()); |
| 203 int label_new_required_width = GetControlTextWidth(hwndSharingWith); | |
| 204 | |
| 205 int label_width_delta = label_new_required_width - label_old_required_width; | |
| 206 int button_width_delta = | |
| 207 button_new_required_width - button_old_required_width; | |
| 208 | |
| 209 RECT label_rect; | |
| 210 GetClientRect(hwndSharingWith, &label_rect); | |
| 211 SetWindowPos(hwndSharingWith, NULL, 0, 0, | |
| 212 label_rect.right + label_width_delta, label_rect.bottom, | |
| 213 SWP_NOMOVE|SWP_NOZORDER); | |
| 214 | |
| 215 RECT button_rect; | |
| 216 GetWindowRect(hwndButton, &button_rect); | |
| 217 POINT button_point = { button_rect.left, button_rect.top }; | |
| 218 ScreenToClient(hwnd_, &button_point); | |
| 219 SetWindowPos(hwndButton, NULL, | |
| 220 button_point.x + label_width_delta, button_point.y, | |
| 221 (button_rect.right - button_rect.left) + button_width_delta, | |
| 222 button_rect.bottom - button_rect.top, SWP_NOZORDER); | |
| 223 | |
| 224 RECT window_rect; | |
| 225 GetWindowRect(hwnd_, &window_rect); | |
| 226 int width = (window_rect.right - window_rect.left) + | |
| 227 button_width_delta + label_width_delta; | |
| 228 int height = window_rect.bottom - window_rect.top; | |
| 229 SetWindowPos(hwnd_, NULL, 0, 0, width, height, SWP_NOMOVE|SWP_NOZORDER); | |
| 230 HRGN rgn = CreateRoundRectRgn(0, 0, width, height, kWindowBorderRadius, | |
| 231 kWindowBorderRadius); | |
| 232 SetWindowRgn(hwnd_, rgn, TRUE); | |
| 154 } | 233 } |
| 155 | 234 |
| 156 void DisconnectWindowWin::Hide() { | 235 void DisconnectWindowWin::Hide() { |
| 157 EndDialog(0); | 236 EndDialog(0); |
| 158 } | 237 } |
| 159 | 238 |
| 160 void DisconnectWindowWin::EndDialog(int result) { | 239 void DisconnectWindowWin::EndDialog(int result) { |
| 161 if (has_hotkey_) { | 240 if (has_hotkey_) { |
| 162 UnregisterHotKey(hwnd_, DISCONNECT_HOTKEY_ID); | 241 UnregisterHotKey(hwnd_, DISCONNECT_HOTKEY_ID); |
| 163 has_hotkey_ = false; | 242 has_hotkey_ = false; |
| 164 } | 243 } |
| 165 | 244 |
| 166 if (hwnd_) { | 245 if (hwnd_) { |
| 167 ::EndDialog(hwnd_, result); | 246 ::EndDialog(hwnd_, result); |
| 168 hwnd_ = NULL; | 247 hwnd_ = NULL; |
| 169 } | 248 } |
| 170 } | 249 } |
| 171 | 250 |
| 172 DisconnectWindow* DisconnectWindow::Create() { | 251 DisconnectWindow* DisconnectWindow::Create() { |
| 173 return new DisconnectWindowWin; | 252 return new DisconnectWindowWin; |
| 174 } | 253 } |
| 175 | 254 |
| 176 } // namespace remoting | 255 } // namespace remoting |
| OLD | NEW |