Refactor management of overview window copy lifetime into a separate class.
[chromium-blink-merge.git] / content / shell / browser / shell_win.cc
blob2854e5c5c7dc3e9ca31fa0bb74c6f04dea7339b4
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/shell/browser/shell.h"
7 #include <windows.h>
8 #include <commctrl.h>
9 #include <fcntl.h>
10 #include <io.h>
12 #include "base/strings/utf_string_conversions.h"
13 #include "base/win/wrapped_window_proc.h"
14 #include "content/public/browser/web_contents.h"
15 #include "content/public/browser/web_contents_view.h"
16 #include "content/shell/app/resource.h"
17 #include "ui/gfx/win/hwnd_util.h"
19 namespace {
21 const wchar_t kWindowTitle[] = L"Content Shell";
22 const wchar_t kWindowClass[] = L"CONTENT_SHELL";
24 const int kButtonWidth = 72;
25 const int kURLBarHeight = 24;
27 const int kMaxURLLength = 1024;
29 } // namespace
31 namespace content {
33 HINSTANCE Shell::instance_handle_;
35 void Shell::PlatformInitialize(const gfx::Size& default_window_size) {
36 _setmode(_fileno(stdout), _O_BINARY);
37 _setmode(_fileno(stderr), _O_BINARY);
38 INITCOMMONCONTROLSEX InitCtrlEx;
39 InitCtrlEx.dwSize = sizeof(INITCOMMONCONTROLSEX);
40 InitCtrlEx.dwICC = ICC_STANDARD_CLASSES;
41 InitCommonControlsEx(&InitCtrlEx);
42 RegisterWindowClass();
45 void Shell::PlatformExit() {
46 std::vector<Shell*> windows = windows_;
47 for (std::vector<Shell*>::iterator it = windows.begin();
48 it != windows.end(); ++it)
49 DestroyWindow((*it)->window_);
52 void Shell::PlatformCleanUp() {
53 // When the window is destroyed, tell the Edit field to forget about us,
54 // otherwise we will crash.
55 gfx::SetWindowProc(url_edit_view_, default_edit_wnd_proc_);
56 gfx::SetWindowUserData(url_edit_view_, NULL);
59 void Shell::PlatformEnableUIControl(UIControl control, bool is_enabled) {
60 int id;
61 switch (control) {
62 case BACK_BUTTON:
63 id = IDC_NAV_BACK;
64 break;
65 case FORWARD_BUTTON:
66 id = IDC_NAV_FORWARD;
67 break;
68 case STOP_BUTTON:
69 id = IDC_NAV_STOP;
70 break;
71 default:
72 NOTREACHED() << "Unknown UI control";
73 return;
75 EnableWindow(GetDlgItem(window_, id), is_enabled);
78 void Shell::PlatformSetAddressBarURL(const GURL& url) {
79 std::wstring url_string = UTF8ToWide(url.spec());
80 SendMessage(url_edit_view_, WM_SETTEXT, 0,
81 reinterpret_cast<LPARAM>(url_string.c_str()));
84 void Shell::PlatformSetIsLoading(bool loading) {
87 void Shell::PlatformCreateWindow(int width, int height) {
88 window_ = CreateWindow(kWindowClass, kWindowTitle,
89 WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
90 CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
91 NULL, NULL, instance_handle_, NULL);
92 gfx::SetWindowUserData(window_, this);
94 HWND hwnd;
95 int x = 0;
97 hwnd = CreateWindow(L"BUTTON", L"Back",
98 WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON ,
99 x, 0, kButtonWidth, kURLBarHeight,
100 window_, (HMENU) IDC_NAV_BACK, instance_handle_, 0);
101 x += kButtonWidth;
103 hwnd = CreateWindow(L"BUTTON", L"Forward",
104 WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON ,
105 x, 0, kButtonWidth, kURLBarHeight,
106 window_, (HMENU) IDC_NAV_FORWARD, instance_handle_, 0);
107 x += kButtonWidth;
109 hwnd = CreateWindow(L"BUTTON", L"Reload",
110 WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON ,
111 x, 0, kButtonWidth, kURLBarHeight,
112 window_, (HMENU) IDC_NAV_RELOAD, instance_handle_, 0);
113 x += kButtonWidth;
115 hwnd = CreateWindow(L"BUTTON", L"Stop",
116 WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON ,
117 x, 0, kButtonWidth, kURLBarHeight,
118 window_, (HMENU) IDC_NAV_STOP, instance_handle_, 0);
119 x += kButtonWidth;
121 // This control is positioned by PlatformResizeSubViews.
122 url_edit_view_ = CreateWindow(L"EDIT", 0,
123 WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT |
124 ES_AUTOVSCROLL | ES_AUTOHSCROLL,
125 x, 0, 0, 0, window_, 0, instance_handle_, 0);
127 default_edit_wnd_proc_ = gfx::SetWindowProc(url_edit_view_,
128 Shell::EditWndProc);
129 gfx::SetWindowUserData(url_edit_view_, this);
131 ShowWindow(window_, SW_SHOW);
133 SizeTo(width, height);
136 void Shell::PlatformSetContents() {
137 SetParent(web_contents_->GetView()->GetNativeView(), window_);
140 void Shell::SizeTo(int width, int height) {
141 RECT rc, rw;
142 GetClientRect(window_, &rc);
143 GetWindowRect(window_, &rw);
145 int client_width = rc.right - rc.left;
146 int window_width = rw.right - rw.left;
147 window_width = (window_width - client_width) + width;
149 int client_height = rc.bottom - rc.top;
150 int window_height = rw.bottom - rw.top;
151 window_height = (window_height - client_height) + height;
153 // Add space for the url bar.
154 window_height += kURLBarHeight;
156 SetWindowPos(window_, NULL, 0, 0, window_width, window_height,
157 SWP_NOMOVE | SWP_NOZORDER);
160 void Shell::PlatformResizeSubViews() {
161 RECT rc;
162 GetClientRect(window_, &rc);
164 int x = kButtonWidth * 4;
165 MoveWindow(url_edit_view_, x, 0, rc.right - x, kURLBarHeight, TRUE);
167 MoveWindow(GetContentView(), 0, kURLBarHeight, rc.right,
168 rc.bottom - kURLBarHeight, TRUE);
171 void Shell::Close() {
172 DestroyWindow(window_);
175 ATOM Shell::RegisterWindowClass() {
176 WNDCLASSEX window_class;
177 base::win::InitializeWindowClass(
178 kWindowClass,
179 &Shell::WndProc,
180 CS_HREDRAW | CS_VREDRAW,
183 LoadCursor(NULL, IDC_ARROW),
184 NULL,
185 MAKEINTRESOURCE(IDC_CONTENTSHELL),
186 NULL,
187 NULL,
188 &window_class);
189 instance_handle_ = window_class.hInstance;
190 return RegisterClassEx(&window_class);
193 LRESULT CALLBACK Shell::WndProc(HWND hwnd, UINT message, WPARAM wParam,
194 LPARAM lParam) {
195 Shell* shell = static_cast<Shell*>(gfx::GetWindowUserData(hwnd));
197 switch (message) {
198 case WM_COMMAND: {
199 int id = LOWORD(wParam);
200 switch (id) {
201 case IDM_NEW_WINDOW:
202 CreateNewWindow(
203 shell->web_contents()->GetBrowserContext(),
204 GURL(), NULL, MSG_ROUTING_NONE, gfx::Size());
205 break;
206 case IDM_CLOSE_WINDOW:
207 DestroyWindow(hwnd);
208 break;
209 case IDM_EXIT:
210 PlatformExit();
211 break;
212 case IDM_SHOW_DEVELOPER_TOOLS:
213 shell->ShowDevTools();
214 break;
215 case IDC_NAV_BACK:
216 shell->GoBackOrForward(-1);
217 break;
218 case IDC_NAV_FORWARD:
219 shell->GoBackOrForward(1);
220 break;
221 case IDC_NAV_RELOAD:
222 shell->Reload();
223 break;
224 case IDC_NAV_STOP:
225 shell->Stop();
226 break;
228 break;
230 case WM_DESTROY: {
231 delete shell;
232 return 0;
235 case WM_SIZE: {
236 if (shell->GetContentView())
237 shell->PlatformResizeSubViews();
238 return 0;
241 case WM_WINDOWPOSCHANGED: {
242 // Notify the content view that the window position of its parent window
243 // has been changed by sending window message
244 gfx::NativeView native_view = shell->GetContentView();
245 if (native_view) {
246 SendMessage(native_view, message, wParam, lParam);
248 break;
252 return DefWindowProc(hwnd, message, wParam, lParam);
255 LRESULT CALLBACK Shell::EditWndProc(HWND hwnd, UINT message,
256 WPARAM wParam, LPARAM lParam) {
257 Shell* shell = static_cast<Shell*>(gfx::GetWindowUserData(hwnd));
259 switch (message) {
260 case WM_CHAR:
261 if (wParam == VK_RETURN) {
262 wchar_t str[kMaxURLLength + 1]; // Leave room for adding a NULL;
263 *(str) = kMaxURLLength;
264 LRESULT str_len = SendMessage(hwnd, EM_GETLINE, 0, (LPARAM)str);
265 if (str_len > 0) {
266 str[str_len] = 0; // EM_GETLINE doesn't NULL terminate.
267 GURL url(str);
268 if (!url.has_scheme())
269 url = GURL(std::wstring(L"http://") + std::wstring(str));
270 shell->LoadURL(url);
273 return 0;
277 return CallWindowProc(shell->default_edit_wnd_proc_, hwnd, message, wParam,
278 lParam);
281 void Shell::PlatformSetTitle(const string16& text) {
282 ::SetWindowText(window_, text.c_str());
285 } // namespace content