OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 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 <commctrl.h> | |
8 #include <fcntl.h> | |
9 #include <io.h> | |
10 #include <windows.h> | |
11 | |
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/base/win/hwnd_util.h" | |
18 | |
19 namespace { | |
20 | |
21 const wchar_t kWindowTitle[] = L"Content Shell"; | |
22 const wchar_t kWindowClass[] = L"CONTENT_SHELL"; | |
23 | |
24 const int kButtonWidth = 72; | |
25 const int kURLBarHeight = 24; | |
26 | |
27 const int kMaxURLLength = 1024; | |
28 | |
29 } // namespace | |
30 | |
31 namespace content { | |
32 | |
33 HINSTANCE Shell::instance_handle_; | |
34 | |
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(); | |
43 } | |
44 | |
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_); | |
50 } | |
51 | |
52 void Shell::PlatformCleanUp() { | |
53 // When the window is destroyed, tell the Edit field to forget about us, | |
54 // otherwise we will crash. | |
55 ui::SetWindowProc(url_edit_view_, default_edit_wnd_proc_); | |
56 ui::SetWindowUserData(url_edit_view_, NULL); | |
57 } | |
58 | |
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; | |
74 } | |
75 EnableWindow(GetDlgItem(window_, id), is_enabled); | |
76 } | |
77 | |
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())); | |
82 } | |
83 | |
84 void Shell::PlatformSetIsLoading(bool loading) { | |
85 } | |
86 | |
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 ui::SetWindowUserData(window_, this); | |
93 | |
94 HWND hwnd; | |
95 int x = 0; | |
96 | |
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; | |
102 | |
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; | |
108 | |
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; | |
114 | |
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; | |
120 | |
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); | |
126 | |
127 default_edit_wnd_proc_ = ui::SetWindowProc(url_edit_view_, | |
128 Shell::EditWndProc); | |
129 ui::SetWindowUserData(url_edit_view_, this); | |
130 | |
131 ShowWindow(window_, SW_SHOW); | |
132 | |
133 SizeTo(width, height); | |
134 } | |
135 | |
136 void Shell::PlatformSetContents() { | |
137 SetParent(web_contents_->GetView()->GetNativeView(), window_); | |
138 } | |
139 | |
140 void Shell::SizeTo(int width, int height) { | |
141 RECT rc, rw; | |
142 GetClientRect(window_, &rc); | |
143 GetWindowRect(window_, &rw); | |
144 | |
145 int client_width = rc.right - rc.left; | |
146 int window_width = rw.right - rw.left; | |
147 window_width = (window_width - client_width) + width; | |
148 | |
149 int client_height = rc.bottom - rc.top; | |
150 int window_height = rw.bottom - rw.top; | |
151 window_height = (window_height - client_height) + height; | |
152 | |
153 // Add space for the url bar. | |
154 window_height += kURLBarHeight; | |
155 | |
156 SetWindowPos(window_, NULL, 0, 0, window_width, window_height, | |
157 SWP_NOMOVE | SWP_NOZORDER); | |
158 } | |
159 | |
160 void Shell::PlatformResizeSubViews() { | |
161 RECT rc; | |
162 GetClientRect(window_, &rc); | |
163 | |
164 int x = kButtonWidth * 4; | |
165 MoveWindow(url_edit_view_, x, 0, rc.right - x, kURLBarHeight, TRUE); | |
166 | |
167 MoveWindow(GetContentView(), 0, kURLBarHeight, rc.right, | |
168 rc.bottom - kURLBarHeight, TRUE); | |
169 } | |
170 | |
171 void Shell::Close() { | |
172 DestroyWindow(window_); | |
173 } | |
174 | |
175 ATOM Shell::RegisterWindowClass() { | |
176 WNDCLASSEX window_class; | |
177 base::win::InitializeWindowClass( | |
178 kWindowClass, | |
179 &Shell::WndProc, | |
180 CS_HREDRAW | CS_VREDRAW, | |
181 0, | |
182 0, | |
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); | |
191 } | |
192 | |
193 LRESULT 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) { | |
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; | |
227 } | |
228 break; | |
229 } | |
230 case WM_DESTROY: { | |
231 delete shell; | |
232 return 0; | |
233 } | |
234 | |
235 case WM_SIZE: { | |
236 if (shell->GetContentView()) | |
237 shell->PlatformResizeSubViews(); | |
238 return 0; | |
239 } | |
240 | |
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); | |
247 } | |
248 break; | |
249 } | |
250 } | |
251 | |
252 return DefWindowProc(hwnd, message, wParam, lParam); | |
253 } | |
254 | |
255 LRESULT CALLBACK Shell::EditWndProc(HWND hwnd, UINT message, | |
256 WPARAM wParam, LPARAM lParam) { | |
257 Shell* shell = static_cast<Shell*>(ui::GetWindowUserData(hwnd)); | |
258 | |
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); | |
271 } | |
272 | |
273 return 0; | |
274 } | |
275 } | |
276 | |
277 return CallWindowProc(shell->default_edit_wnd_proc_, hwnd, message, wParam, | |
278 lParam); | |
279 } | |
280 | |
281 void Shell::PlatformSetTitle(const string16& text) { | |
282 ::SetWindowText(window_, text.c_str()); | |
283 } | |
284 | |
285 } // namespace content | |
OLD | NEW |