blob: a4991892514dcfa17a6773aeebb16759fcb51817 [file] [log] [blame]
[email protected]9fbd3f862011-09-20 23:31:341// 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
3// found in the LICENSE file.
4
5#include "content/shell/shell.h"
6
7#include <windows.h>
8#include <commctrl.h>
9
10#include "base/message_loop.h"
11#include "base/string_piece.h"
[email protected]e99ca5112011-09-26 17:22:5412#include "base/utf_string_conversions.h"
[email protected]9fbd3f862011-09-20 23:31:3413#include "base/win/resource_util.h"
[email protected]e99ca5112011-09-26 17:22:5414#include "content/browser/tab_contents/tab_contents.h"
[email protected]9fbd3f862011-09-20 23:31:3415#include "content/shell/resource.h"
16#include "googleurl/src/gurl.h"
17#include "grit/webkit_resources.h"
18#include "grit/webkit_chromium_resources.h"
[email protected]e99ca5112011-09-26 17:22:5419#include "ipc/ipc_message.h"
[email protected]9fbd3f862011-09-20 23:31:3420#include "net/base/net_module.h"
21#include "ui/base/win/hwnd_util.h"
22
23namespace {
24
25static const wchar_t kWindowTitle[] = L"Content Shell";
26static const wchar_t kWindowClass[] = L"CONTENT_SHELL";
27
28static const int kButtonWidth = 72;
29static const int kURLBarHeight = 24;
30
31static const int kMaxURLLength = 1024;
32
33static base::StringPiece GetRawDataResource(HMODULE module, int resource_id) {
34 void* data_ptr;
35 size_t data_size;
36 return base::win::GetDataResourceFromModule(module, resource_id, &data_ptr,
37 &data_size)
38 ? base::StringPiece(static_cast<char*>(data_ptr), data_size)
39 : base::StringPiece();
40}
41
42} // namespace
43
44namespace content {
45
46HINSTANCE Shell::instance_handle_;
47
48void Shell::PlatformInitialize() {
49 instance_handle_ = ::GetModuleHandle(NULL);
50
51 INITCOMMONCONTROLSEX InitCtrlEx;
52 InitCtrlEx.dwSize = sizeof(INITCOMMONCONTROLSEX);
53 InitCtrlEx.dwICC = ICC_STANDARD_CLASSES;
54 InitCommonControlsEx(&InitCtrlEx);
55 RegisterWindowClass();
56}
57
58base::StringPiece Shell::PlatformResourceProvider(int key) {
59 return GetRawDataResource(::GetModuleHandle(NULL), key);
60}
61
[email protected]e99ca5112011-09-26 17:22:5462void Shell::PlatformExit() {
63}
64
[email protected]9fbd3f862011-09-20 23:31:3465void Shell::PlatformCleanUp() {
66 // When the window is destroyed, tell the Edit field to forget about us,
67 // otherwise we will crash.
[email protected]46d04fa2011-10-06 18:32:4368 ui::SetWindowProc(url_edit_view_, default_edit_wnd_proc_);
69 ui::SetWindowUserData(url_edit_view_, NULL);
[email protected]9fbd3f862011-09-20 23:31:3470}
71
72void Shell::PlatformEnableUIControl(UIControl control, bool is_enabled) {
73 int id;
74 switch (control) {
75 case BACK_BUTTON:
76 id = IDC_NAV_BACK;
77 break;
78 case FORWARD_BUTTON:
79 id = IDC_NAV_FORWARD;
80 break;
81 case STOP_BUTTON:
82 id = IDC_NAV_STOP;
83 break;
84 default:
85 NOTREACHED() << "Unknown UI control";
86 return;
87 }
[email protected]46d04fa2011-10-06 18:32:4388 EnableWindow(GetDlgItem(window_, id), is_enabled);
[email protected]9fbd3f862011-09-20 23:31:3489}
90
[email protected]e99ca5112011-09-26 17:22:5491void Shell::PlatformSetAddressBarURL(const GURL& url) {
92 std::wstring url_string = UTF8ToWide(url.spec());
[email protected]46d04fa2011-10-06 18:32:4393 SendMessage(url_edit_view_, WM_SETTEXT, 0,
[email protected]e99ca5112011-09-26 17:22:5494 reinterpret_cast<LPARAM>(url_string.c_str()));
95}
96
[email protected]9fbd3f862011-09-20 23:31:3497void Shell::PlatformCreateWindow() {
[email protected]46d04fa2011-10-06 18:32:4398 window_ = CreateWindow(kWindowClass, kWindowTitle,
99 WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
100 CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
101 NULL, NULL, instance_handle_, NULL);
102 ui::SetWindowUserData(window_, this);
[email protected]9fbd3f862011-09-20 23:31:34103
104 HWND hwnd;
105 int x = 0;
106
107 hwnd = CreateWindow(L"BUTTON", L"Back",
108 WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON ,
109 x, 0, kButtonWidth, kURLBarHeight,
[email protected]46d04fa2011-10-06 18:32:43110 window_, (HMENU) IDC_NAV_BACK, instance_handle_, 0);
[email protected]9fbd3f862011-09-20 23:31:34111 x += kButtonWidth;
112
113 hwnd = CreateWindow(L"BUTTON", L"Forward",
114 WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON ,
115 x, 0, kButtonWidth, kURLBarHeight,
[email protected]46d04fa2011-10-06 18:32:43116 window_, (HMENU) IDC_NAV_FORWARD, instance_handle_, 0);
[email protected]9fbd3f862011-09-20 23:31:34117 x += kButtonWidth;
118
119 hwnd = CreateWindow(L"BUTTON", L"Reload",
120 WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON ,
121 x, 0, kButtonWidth, kURLBarHeight,
[email protected]46d04fa2011-10-06 18:32:43122 window_, (HMENU) IDC_NAV_RELOAD, instance_handle_, 0);
[email protected]9fbd3f862011-09-20 23:31:34123 x += kButtonWidth;
124
125 hwnd = CreateWindow(L"BUTTON", L"Stop",
126 WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON ,
127 x, 0, kButtonWidth, kURLBarHeight,
[email protected]46d04fa2011-10-06 18:32:43128 window_, (HMENU) IDC_NAV_STOP, instance_handle_, 0);
[email protected]9fbd3f862011-09-20 23:31:34129 x += kButtonWidth;
130
131 // This control is positioned by PlatformResizeSubViews.
[email protected]46d04fa2011-10-06 18:32:43132 url_edit_view_ = CreateWindow(L"EDIT", 0,
133 WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT |
134 ES_AUTOVSCROLL | ES_AUTOHSCROLL,
135 x, 0, 0, 0, window_, 0, instance_handle_, 0);
[email protected]9fbd3f862011-09-20 23:31:34136
[email protected]46d04fa2011-10-06 18:32:43137 default_edit_wnd_proc_ = ui::SetWindowProc(url_edit_view_,
138 Shell::EditWndProc);
139 ui::SetWindowUserData(url_edit_view_, this);
[email protected]9fbd3f862011-09-20 23:31:34140
[email protected]46d04fa2011-10-06 18:32:43141 ShowWindow(window_, SW_SHOW);
[email protected]9fbd3f862011-09-20 23:31:34142}
143
144void Shell::PlatformSizeTo(int width, int height) {
145 RECT rc, rw;
[email protected]46d04fa2011-10-06 18:32:43146 GetClientRect(window_, &rc);
147 GetWindowRect(window_, &rw);
[email protected]9fbd3f862011-09-20 23:31:34148
149 int client_width = rc.right - rc.left;
150 int window_width = rw.right - rw.left;
151 window_width = (window_width - client_width) + width;
152
153 int client_height = rc.bottom - rc.top;
154 int window_height = rw.bottom - rw.top;
155 window_height = (window_height - client_height) + height;
156
157 // Add space for the url bar.
158 window_height += kURLBarHeight;
159
[email protected]46d04fa2011-10-06 18:32:43160 SetWindowPos(window_, NULL, 0, 0, window_width, window_height,
[email protected]9fbd3f862011-09-20 23:31:34161 SWP_NOMOVE | SWP_NOZORDER);
162}
163
164void Shell::PlatformResizeSubViews() {
165 RECT rc;
[email protected]46d04fa2011-10-06 18:32:43166 GetClientRect(window_, &rc);
[email protected]9fbd3f862011-09-20 23:31:34167
168 int x = kButtonWidth * 4;
[email protected]46d04fa2011-10-06 18:32:43169 MoveWindow(url_edit_view_, x, 0, rc.right - x, kURLBarHeight, TRUE);
[email protected]9fbd3f862011-09-20 23:31:34170
171 MoveWindow(GetContentView(), 0, kURLBarHeight, rc.right,
172 rc.bottom - kURLBarHeight, TRUE);
173}
174
175ATOM Shell::RegisterWindowClass() {
176 WNDCLASSEX wcex = {
177 sizeof(WNDCLASSEX),
178 CS_HREDRAW | CS_VREDRAW,
179 Shell::WndProc,
180 0,
181 0,
182 instance_handle_,
183 NULL,
184 LoadCursor(NULL, IDC_ARROW),
185 0,
186 MAKEINTRESOURCE(IDC_CONTENTSHELL),
187 kWindowClass,
188 NULL,
189 };
190 return RegisterClassEx(&wcex);
191}
192
193LRESULT CALLBACK Shell::WndProc(HWND hwnd, UINT message, WPARAM wParam,
194 LPARAM lParam) {
195 Shell* shell = static_cast<Shell*>(ui::GetWindowUserData(hwnd));
196
197 switch (message) {
198 case WM_COMMAND: {
199 int id = LOWORD(wParam);
200 switch (id) {
[email protected]e99ca5112011-09-26 17:22:54201 case IDM_NEW_WINDOW:
202 CreateNewWindow(
203 shell->tab_contents()->browser_context(),
204 GURL(), NULL, MSG_ROUTING_NONE, NULL);
205 break;
206 case IDM_CLOSE_WINDOW:
[email protected]9fbd3f862011-09-20 23:31:34207 DestroyWindow(hwnd);
208 break;
[email protected]e99ca5112011-09-26 17:22:54209 case IDM_EXIT:
210 PlatformExit();
211 break;
[email protected]9fbd3f862011-09-20 23:31:34212 case IDC_NAV_BACK:
213 shell->GoBackOrForward(-1);
214 break;
215 case IDC_NAV_FORWARD:
216 shell->GoBackOrForward(1);
217 break;
218 case IDC_NAV_RELOAD:
219 case IDC_NAV_STOP: {
220 if (id == IDC_NAV_RELOAD) {
221 shell->Reload();
222 } else {
223 shell->Stop();
224 }
225 break;
226 }
227 break;
228 }
229 break;
230 }
231 case WM_DESTROY: {
232 delete shell;
[email protected]e99ca5112011-09-26 17:22:54233 if (windows_.empty())
[email protected]9fbd3f862011-09-20 23:31:34234 MessageLoop::current()->Quit();
235 return 0;
236 }
237
238 case WM_SIZE: {
239 if (shell->GetContentView())
240 shell->PlatformResizeSubViews();
241 return 0;
242 }
243 }
244
245 return DefWindowProc(hwnd, message, wParam, lParam);
246}
247
248LRESULT CALLBACK Shell::EditWndProc(HWND hwnd, UINT message,
249 WPARAM wParam, LPARAM lParam) {
250 Shell* shell = static_cast<Shell*>(ui::GetWindowUserData(hwnd));
251
252 switch (message) {
253 case WM_CHAR:
254 if (wParam == VK_RETURN) {
255 wchar_t str[kMaxURLLength + 1]; // Leave room for adding a NULL;
256 *(str) = kMaxURLLength;
257 LRESULT str_len = SendMessage(hwnd, EM_GETLINE, 0, (LPARAM)str);
258 if (str_len > 0) {
259 str[str_len] = 0; // EM_GETLINE doesn't NULL terminate.
[email protected]e99ca5112011-09-26 17:22:54260 GURL url(str);
261 if (!url.has_scheme())
262 url = GURL(std::wstring(L"http://") + std::wstring(str));
263 shell->LoadURL(url);
[email protected]9fbd3f862011-09-20 23:31:34264 }
265
266 return 0;
267 }
268 }
269
270 return CallWindowProc(shell->default_edit_wnd_proc_, hwnd, message, wParam,
271 lParam);
272}
273
274} // namespace content