summaryrefslogtreecommitdiffstats
path: root/remoting/host/disconnect_window_win.cc
diff options
context:
space:
mode:
authorjamiewalch@chromium.org <jamiewalch@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-10-24 23:23:44 +0000
committerjamiewalch@chromium.org <jamiewalch@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-10-24 23:23:44 +0000
commitb4001d5d19c25899403a3c5b28949d94d2aca683 (patch)
treec8807077ed0853d2cc837d7b80036055178e174d /remoting/host/disconnect_window_win.cc
parent464750f4c63d803b27a80cbcd58fa5fdebee7247 (diff)
downloadchromium_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.cc142
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() {