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
parent 464750f4
...@@ -10,6 +10,9 @@ ...@@ -10,6 +10,9 @@
#include "base/logging.h" #include "base/logging.h"
#include "base/string_util.h" #include "base/string_util.h"
#include "base/utf_string_conversions.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" #include "remoting/host/chromoting_host.h"
// TODO(wez): The DisconnectWindow isn't plugin-specific, so shouldn't have // TODO(wez): The DisconnectWindow isn't plugin-specific, so shouldn't have
// a dependency on the plugin's resource header. // a dependency on the plugin's resource header.
...@@ -28,6 +31,7 @@ ...@@ -28,6 +31,7 @@
extern HMODULE g_hModule; extern HMODULE g_hModule;
const int DISCONNECT_HOTKEY_ID = 1000; const int DISCONNECT_HOTKEY_ID = 1000;
const int kWindowBorderRadius = 14;
namespace remoting { namespace remoting {
...@@ -53,6 +57,7 @@ private: ...@@ -53,6 +57,7 @@ private:
remoting::ChromotingHost* host_; remoting::ChromotingHost* host_;
HWND hwnd_; HWND hwnd_;
bool has_hotkey_; bool has_hotkey_;
base::win::ScopedGDIObject<HPEN> border_pen_;
DISALLOW_COPY_AND_ASSIGN(DisconnectWindowWin); DISALLOW_COPY_AND_ASSIGN(DisconnectWindowWin);
}; };
...@@ -60,7 +65,9 @@ private: ...@@ -60,7 +65,9 @@ private:
DisconnectWindowWin::DisconnectWindowWin() DisconnectWindowWin::DisconnectWindowWin()
: host_(NULL), : host_(NULL),
hwnd_(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() { DisconnectWindowWin::~DisconnectWindowWin() {
...@@ -86,17 +93,11 @@ BOOL CALLBACK DisconnectWindowWin::DialogProc(HWND hwnd, UINT msg, ...@@ -86,17 +93,11 @@ BOOL CALLBACK DisconnectWindowWin::DialogProc(HWND hwnd, UINT msg,
BOOL DisconnectWindowWin::OnDialogMessage(HWND hwnd, UINT msg, BOOL DisconnectWindowWin::OnDialogMessage(HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam) { WPARAM wParam, LPARAM lParam) {
switch (msg) { switch (msg) {
case WM_HOTKEY: // Ignore close messages.
ShutdownHost();
EndDialog(0);
return TRUE;
case WM_CLOSE: 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; return TRUE;
// Handle the Disconnect button.
case WM_COMMAND: case WM_COMMAND:
switch (LOWORD(wParam)) { switch (LOWORD(wParam)) {
case IDC_DISCONNECT: case IDC_DISCONNECT:
...@@ -104,21 +105,77 @@ BOOL DisconnectWindowWin::OnDialogMessage(HWND hwnd, UINT msg, ...@@ -104,21 +105,77 @@ BOOL DisconnectWindowWin::OnDialogMessage(HWND hwnd, UINT msg,
EndDialog(LOWORD(wParam)); EndDialog(LOWORD(wParam));
return TRUE; 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; return FALSE;
} }
void DisconnectWindowWin::Show(ChromotingHost* host, void DisconnectWindowWin::Show(ChromotingHost* host,
const std::string& username) { const std::string& username) {
CHECK(!hwnd_);
host_ = host; host_ = host;
CHECK(!hwnd_); // Load the dialog resource so that we can modify the RTL flags if necessary.
hwnd_ = CreateDialogParam(g_hModule, MAKEINTRESOURCE(IDD_DISCONNECT), NULL, // This is taken from chrome/default_plugin/install_dialog.cc
(DLGPROC)DialogProc, (LPARAM)this); HRSRC dialog_resource =
if (!hwnd_) { FindResource(g_hModule, MAKEINTRESOURCE(IDD_DISCONNECT), RT_DIALOG);
LOG(ERROR) << "Unable to create Disconnect dialog for remoting."; CHECK(dialog_resource);
return; 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. // Set up handler for Ctrl-Alt-Esc shortcut.
if (!has_hotkey_ && RegisterHotKey(hwnd_, DISCONNECT_HOTKEY_ID, if (!has_hotkey_ && RegisterHotKey(hwnd_, DISCONNECT_HOTKEY_ID,
...@@ -135,8 +192,21 @@ void DisconnectWindowWin::ShutdownHost() { ...@@ -135,8 +192,21 @@ void DisconnectWindowWin::ShutdownHost() {
host_->Shutdown(NULL); 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, void DisconnectWindowWin::SetStrings(const UiStrings& strings,
const std::string& username) { const std::string& username) {
SetWindowText(hwnd_, strings.product_name.c_str()); SetWindowText(hwnd_, strings.product_name.c_str());
HWND hwndButton = GetDlgItem(hwnd_, IDC_DISCONNECT); HWND hwndButton = GetDlgItem(hwnd_, IDC_DISCONNECT);
...@@ -144,13 +214,49 @@ void DisconnectWindowWin::SetStrings(const UiStrings& strings, ...@@ -144,13 +214,49 @@ void DisconnectWindowWin::SetStrings(const UiStrings& strings,
const WCHAR* label = const WCHAR* label =
has_hotkey_ ? strings.disconnect_button_text_plus_shortcut.c_str() has_hotkey_ ? strings.disconnect_button_text_plus_shortcut.c_str()
: strings.disconnect_button_text.c_str(); : strings.disconnect_button_text.c_str();
int button_old_required_width = GetControlTextWidth(hwndButton);
SetWindowText(hwndButton, label); SetWindowText(hwndButton, label);
int button_new_required_width = GetControlTextWidth(hwndButton);
HWND hwndSharingWith = GetDlgItem(hwnd_, IDC_DISCONNECT_SHARINGWITH); HWND hwndSharingWith = GetDlgItem(hwnd_, IDC_DISCONNECT_SHARINGWITH);
CHECK(hwndSharingWith); CHECK(hwndSharingWith);
string16 text = ReplaceStringPlaceholders( string16 text = ReplaceStringPlaceholders(
strings.disconnect_message, UTF8ToUTF16(username), NULL); strings.disconnect_message, UTF8ToUTF16(username), NULL);
int label_old_required_width = GetControlTextWidth(hwndSharingWith);
SetWindowText(hwndSharingWith, text.c_str()); 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() { void DisconnectWindowWin::Hide() {
......
...@@ -91,14 +91,15 @@ END ...@@ -91,14 +91,15 @@ END
// Dialog // Dialog
// //
IDD_DISCONNECT DIALOGEX 0, 0, 166, 59 IDD_DISCONNECT DIALOGEX 0, 0, 145, 24
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION STYLE DS_SETFONT | WS_POPUP
EXSTYLE WS_EX_TOPMOST EXSTYLE WS_EX_TOPMOST
CAPTION "kTitle"
FONT 9, "Microsoft Sans Serif", 400, 0, 0x0 FONT 9, "Microsoft Sans Serif", 400, 0, 0x0
BEGIN BEGIN
DEFPUSHBUTTON "kDisconnectButton",IDC_DISCONNECT,20,38,126,14 DEFPUSHBUTTON "kDisconnectButton",IDC_DISCONNECT,68,5,70,14
LTEXT "kSharingWith",IDC_DISCONNECT_SHARINGWITH,7,7,152,28 LTEXT "kSharingWith",IDC_DISCONNECT_SHARINGWITH,18,7,43,8
CONTROL "",IDC_STATIC,"Static",SS_ETCHEDVERT,6,6,1,12
CONTROL "",IDC_STATIC,"Static",SS_ETCHEDVERT,8,6,1,12
END END
IDD_CONTINUE DIALOGEX 0, 0, 221, 58 IDD_CONTINUE DIALOGEX 0, 0, 221, 58
...@@ -123,12 +124,8 @@ GUIDELINES DESIGNINFO ...@@ -123,12 +124,8 @@ GUIDELINES DESIGNINFO
BEGIN BEGIN
IDD_DISCONNECT, DIALOG IDD_DISCONNECT, DIALOG
BEGIN BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 159
VERTGUIDE, 20 VERTGUIDE, 20
VERTGUIDE, 146 BOTTOMMARGIN, 23
TOPMARGIN, 7
BOTTOMMARGIN, 52
END END
IDD_CONTINUE, DIALOG IDD_CONTINUE, DIALOG
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment