diff options
author | jamiewalch@chromium.org <jamiewalch@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-10-24 23:23:44 +0000 |
---|---|---|
committer | jamiewalch@chromium.org <jamiewalch@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-10-24 23:23:44 +0000 |
commit | b4001d5d19c25899403a3c5b28949d94d2aca683 (patch) | |
tree | c8807077ed0853d2cc837d7b80036055178e174d /remoting/host/disconnect_window_win.cc | |
parent | 464750f4c63d803b27a80cbcd58fa5fdebee7247 (diff) | |
download | chromium_src-b4001d5d19c25899403a3c5b28949d94d2aca683.zip chromium_src-b4001d5d19c25899403a3c5b28949d94d2aca683.tar.gz chromium_src-b4001d5d19c25899403a3c5b28949d94d2aca683.tar.bz2 |
Initial prototype minus drop-shadow.
BUG=None
TEST=Manual
Review URL: http://codereview.chromium.org/8356032
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@107011 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting/host/disconnect_window_win.cc')
-rw-r--r-- | remoting/host/disconnect_window_win.cc | 142 |
1 files changed, 124 insertions, 18 deletions
diff --git a/remoting/host/disconnect_window_win.cc b/remoting/host/disconnect_window_win.cc index abe739a..e81ed65 100644 --- a/remoting/host/disconnect_window_win.cc +++ b/remoting/host/disconnect_window_win.cc @@ -10,6 +10,9 @@ #include "base/logging.h" #include "base/string_util.h" #include "base/utf_string_conversions.h" +#include "base/win/scoped_gdi_object.h" +#include "base/win/scoped_hdc.h" +#include "base/win/scoped_select_object.h" #include "remoting/host/chromoting_host.h" // TODO(wez): The DisconnectWindow isn't plugin-specific, so shouldn't have // a dependency on the plugin's resource header. @@ -28,6 +31,7 @@ extern HMODULE g_hModule; const int DISCONNECT_HOTKEY_ID = 1000; +const int kWindowBorderRadius = 14; namespace remoting { @@ -53,6 +57,7 @@ private: remoting::ChromotingHost* host_; HWND hwnd_; bool has_hotkey_; + base::win::ScopedGDIObject<HPEN> border_pen_; DISALLOW_COPY_AND_ASSIGN(DisconnectWindowWin); }; @@ -60,7 +65,9 @@ private: DisconnectWindowWin::DisconnectWindowWin() : host_(NULL), hwnd_(NULL), - has_hotkey_(false) { + has_hotkey_(false), + border_pen_(CreatePen(PS_SOLID, 5, + RGB(0.13 * 255, 0.69 * 255, 0.11 * 255))) { } DisconnectWindowWin::~DisconnectWindowWin() { @@ -86,17 +93,11 @@ BOOL CALLBACK DisconnectWindowWin::DialogProc(HWND hwnd, UINT msg, BOOL DisconnectWindowWin::OnDialogMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { - case WM_HOTKEY: - ShutdownHost(); - EndDialog(0); - return TRUE; + // Ignore close messages. case WM_CLOSE: - // Ignore close messages. - return TRUE; - case WM_DESTROY: - // Ensure we don't try to use the HWND anymore. - hwnd_ = NULL; return TRUE; + + // Handle the Disconnect button. case WM_COMMAND: switch (LOWORD(wParam)) { case IDC_DISCONNECT: @@ -104,21 +105,77 @@ BOOL DisconnectWindowWin::OnDialogMessage(HWND hwnd, UINT msg, EndDialog(LOWORD(wParam)); return TRUE; } + return FALSE; + + // Ensure we don't try to use the HWND anymore. + case WM_DESTROY: + hwnd_ = NULL; + return TRUE; + + // Handle the disconnect hot-key. + case WM_HOTKEY: + ShutdownHost(); + EndDialog(0); + return TRUE; + + // Let the window be draggable by its client area by responding + // that the entire window is the title bar. + case WM_NCHITTEST: + SetWindowLong(hwnd, DWL_MSGRESULT, HTCAPTION); + return TRUE; + + case WM_PAINT: + { + PAINTSTRUCT ps; + HDC hdc = BeginPaint(hwnd_, &ps); + RECT rect; + GetClientRect(hwnd_, &rect); + { + base::win::ScopedSelectObject border(hdc, border_pen_); + base::win::ScopedSelectObject brush(hdc, GetStockObject(NULL_BRUSH)); + RoundRect(hdc, rect.left, rect.top, rect.right - 1, rect.bottom - 1, + kWindowBorderRadius, kWindowBorderRadius); + } + EndPaint(hwnd_, &ps); + return TRUE; + } } return FALSE; } void DisconnectWindowWin::Show(ChromotingHost* host, const std::string& username) { + CHECK(!hwnd_); host_ = host; - CHECK(!hwnd_); - hwnd_ = CreateDialogParam(g_hModule, MAKEINTRESOURCE(IDD_DISCONNECT), NULL, - (DLGPROC)DialogProc, (LPARAM)this); - if (!hwnd_) { - LOG(ERROR) << "Unable to create Disconnect dialog for remoting."; - return; - } + // Load the dialog resource so that we can modify the RTL flags if necessary. + // This is taken from chrome/default_plugin/install_dialog.cc + HRSRC dialog_resource =
+ FindResource(g_hModule, MAKEINTRESOURCE(IDD_DISCONNECT), RT_DIALOG);
+ CHECK(dialog_resource);
+ HGLOBAL dialog_template = LoadResource(g_hModule, dialog_resource);
+ CHECK(dialog_template);
+ DLGTEMPLATE* dialog_pointer =
+ reinterpret_cast<DLGTEMPLATE*>(LockResource(dialog_template));
+ CHECK(dialog_pointer);
+
+ // The actual resource type is DLGTEMPLATEEX, but this is not defined in any
+ // standard headers, so we treat it as a generic pointer and manipulate the
+ // correct offsets explicitly.
+ scoped_ptr<unsigned char> rtl_dialog_template;
+ if (host->ui_strings().direction == UiStrings::RTL) { + unsigned long dialog_template_size =
+ SizeofResource(g_hModule, dialog_resource);
+ rtl_dialog_template.reset(new unsigned char[dialog_template_size]);
+ memcpy(rtl_dialog_template.get(), dialog_pointer, dialog_template_size);
+ DWORD* rtl_dwords = reinterpret_cast<DWORD*>(rtl_dialog_template.get());
+ rtl_dwords[2] |= (WS_EX_LAYOUTRTL | WS_EX_RTLREADING);
+ dialog_pointer = reinterpret_cast<DLGTEMPLATE*>(rtl_dwords);
+ }
+
+ hwnd_ = CreateDialogIndirectParam(g_hModule, dialog_pointer, NULL, + (DLGPROC)DialogProc, (LPARAM)this); + CHECK(hwnd_); // Set up handler for Ctrl-Alt-Esc shortcut. if (!has_hotkey_ && RegisterHotKey(hwnd_, DISCONNECT_HOTKEY_ID, @@ -135,8 +192,21 @@ void DisconnectWindowWin::ShutdownHost() { host_->Shutdown(NULL); } +static int GetControlTextWidth(HWND control) { + RECT rect = {0, 0, 0, 0}; + WCHAR text[256]; + int result = GetWindowText(control, text, arraysize(text)); + if (result) { + base::win::ScopedGetDC dc(control); + base::win::ScopedSelectObject font( + dc, (HFONT)SendMessage(control, WM_GETFONT, 0, 0)); + DrawText(dc, text, -1, &rect, DT_CALCRECT|DT_SINGLELINE); + } + return rect.right; +} + void DisconnectWindowWin::SetStrings(const UiStrings& strings, - const std::string& username) { + const std::string& username) { SetWindowText(hwnd_, strings.product_name.c_str()); HWND hwndButton = GetDlgItem(hwnd_, IDC_DISCONNECT); @@ -144,13 +214,49 @@ void DisconnectWindowWin::SetStrings(const UiStrings& strings, const WCHAR* label = has_hotkey_ ? strings.disconnect_button_text_plus_shortcut.c_str() : strings.disconnect_button_text.c_str(); + int button_old_required_width = GetControlTextWidth(hwndButton); SetWindowText(hwndButton, label); + int button_new_required_width = GetControlTextWidth(hwndButton); HWND hwndSharingWith = GetDlgItem(hwnd_, IDC_DISCONNECT_SHARINGWITH); CHECK(hwndSharingWith); string16 text = ReplaceStringPlaceholders( strings.disconnect_message, UTF8ToUTF16(username), NULL); + int label_old_required_width = GetControlTextWidth(hwndSharingWith); SetWindowText(hwndSharingWith, text.c_str()); + int label_new_required_width = GetControlTextWidth(hwndSharingWith); + + int label_width_delta = label_new_required_width - label_old_required_width; + int button_width_delta = + button_new_required_width - button_old_required_width; + + // Reposition the controls such that the label lies to the left of the + // disconnect button (assuming LTR layout). The dialog template determines + // the controls' spacing; update their size to fit the localized content. + RECT label_rect; + GetClientRect(hwndSharingWith, &label_rect); + SetWindowPos(hwndSharingWith, NULL, 0, 0, + label_rect.right + label_width_delta, label_rect.bottom, + SWP_NOMOVE|SWP_NOZORDER); + + RECT button_rect; + GetWindowRect(hwndButton, &button_rect); + int button_width = button_rect.right - button_rect.left; + int button_height = button_rect.bottom - button_rect.top; + MapWindowPoints(NULL, hwnd_, reinterpret_cast<LPPOINT>(&button_rect), 2); + SetWindowPos(hwndButton, NULL, + button_rect.left + label_width_delta, button_rect.top, + button_width + button_width_delta, button_height, SWP_NOZORDER); + + RECT window_rect; + GetWindowRect(hwnd_, &window_rect); + int width = (window_rect.right - window_rect.left) + + button_width_delta + label_width_delta; + int height = window_rect.bottom - window_rect.top; + SetWindowPos(hwnd_, NULL, 0, 0, width, height, SWP_NOMOVE|SWP_NOZORDER); + HRGN rgn = CreateRoundRectRgn(0, 0, width, height, kWindowBorderRadius, + kWindowBorderRadius); + SetWindowRgn(hwnd_, rgn, TRUE); } void DisconnectWindowWin::Hide() { |