|
1 /* |
|
2 * Copyright (C) 2010 Apple Inc. All rights reserved. |
|
3 * |
|
4 * Redistribution and use in source and binary forms, with or without |
|
5 * modification, are permitted provided that the following conditions |
|
6 * are met: |
|
7 * 1. Redistributions of source code must retain the above copyright |
|
8 * notice, this list of conditions and the following disclaimer. |
|
9 * 2. Redistributions in binary form must reproduce the above copyright |
|
10 * notice, this list of conditions and the following disclaimer in the |
|
11 * documentation and/or other materials provided with the distribution. |
|
12 * |
|
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' |
|
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
|
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS |
|
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
|
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
|
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
|
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
|
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
|
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
|
23 * THE POSSIBILITY OF SUCH DAMAGE. |
|
24 */ |
|
25 |
|
26 #include "StdAfx.h" |
|
27 #include "BrowserWindow.h" |
|
28 #include "MiniBrowser.h" |
|
29 #include "Resource.h" |
|
30 |
|
31 #include <assert.h> |
|
32 #include <commctrl.h> |
|
33 #include <shlwapi.h> |
|
34 #include <vector> |
|
35 #include <wininet.h> |
|
36 |
|
37 using namespace std; |
|
38 |
|
39 BrowserWindow::BrowserWindow() |
|
40 : m_window(0) |
|
41 , m_rebarWindow(0) |
|
42 , m_comboBoxWindow(0) |
|
43 { |
|
44 } |
|
45 |
|
46 LRESULT CALLBACK BrowserWindow::BrowserWindowWndProc(HWND window, UINT message, WPARAM wParam, LPARAM lParam) |
|
47 { |
|
48 LONG_PTR longPtr = ::GetWindowLongPtr(window, 0); |
|
49 |
|
50 if (BrowserWindow* browserView = reinterpret_cast<BrowserWindow*>(longPtr)) |
|
51 return browserView->wndProc(window, message, wParam, lParam); |
|
52 |
|
53 if (message == WM_CREATE) { |
|
54 LPCREATESTRUCT createStruct = reinterpret_cast<LPCREATESTRUCT>(lParam); |
|
55 BrowserWindow* browserWindow = static_cast<BrowserWindow*>(createStruct->lpCreateParams); |
|
56 browserWindow->m_window = window; |
|
57 |
|
58 ::SetWindowLongPtr(window, 0, (LONG_PTR)browserWindow); |
|
59 |
|
60 browserWindow->onCreate(createStruct); |
|
61 return 0; |
|
62 } |
|
63 |
|
64 return ::DefWindowProc(window, message, wParam, lParam); |
|
65 } |
|
66 |
|
67 LRESULT BrowserWindow::wndProc(HWND window, UINT message, WPARAM wParam, LPARAM lParam) |
|
68 { |
|
69 LRESULT lResult = 0; |
|
70 bool handled = true; |
|
71 |
|
72 switch (message) { |
|
73 case WM_COMMAND: |
|
74 lResult = onCommand(LOWORD(wParam), handled); |
|
75 break; |
|
76 |
|
77 case WM_SIZE: |
|
78 onSize(LOWORD(lParam), HIWORD(lParam)); |
|
79 break; |
|
80 |
|
81 case WM_DESTROY: |
|
82 onDestroy(); |
|
83 break; |
|
84 |
|
85 case WM_NCDESTROY: |
|
86 onNCDestroy(); |
|
87 break; |
|
88 |
|
89 default: |
|
90 handled = false; |
|
91 } |
|
92 |
|
93 if (!handled) |
|
94 lResult = ::DefWindowProc(window, message, wParam, lParam); |
|
95 |
|
96 return lResult; |
|
97 } |
|
98 |
|
99 void BrowserWindow::createWindow(int x, int y, int width, int height) |
|
100 { |
|
101 assert(!m_window); |
|
102 |
|
103 // Register the class. |
|
104 WNDCLASSEX windowClass = { 0 }; |
|
105 windowClass.cbSize = sizeof(windowClass); |
|
106 windowClass.style = 0; |
|
107 windowClass.lpfnWndProc = BrowserWindowWndProc; |
|
108 windowClass.cbClsExtra = 0; |
|
109 windowClass.cbWndExtra = sizeof(this); |
|
110 windowClass.hInstance = MiniBrowser::shared().instance(); |
|
111 windowClass.hIcon = 0; |
|
112 windowClass.hCursor = ::LoadCursor(0, IDC_ARROW); |
|
113 windowClass.hbrBackground = (HBRUSH)::GetStockObject(WHITE_BRUSH); |
|
114 windowClass.lpszMenuName = MAKEINTRESOURCE(IDR_MAINFRAME); |
|
115 windowClass.lpszClassName = L"MiniBrowser"; |
|
116 windowClass.hIconSm = 0; |
|
117 |
|
118 ::RegisterClassEx(&windowClass); |
|
119 |
|
120 ::CreateWindowW(L"MiniBrowser", L"MiniBrowser", WS_OVERLAPPEDWINDOW, x, y, width, height, 0, 0, MiniBrowser::shared().instance(), this); |
|
121 } |
|
122 |
|
123 void BrowserWindow::showWindow() |
|
124 { |
|
125 assert(m_window); |
|
126 |
|
127 ::ShowWindow(m_window, SW_SHOWNORMAL); |
|
128 } |
|
129 |
|
130 void BrowserWindow::goToURL(const std::wstring& url) |
|
131 { |
|
132 m_browserView.goToURL(url); |
|
133 } |
|
134 |
|
135 void BrowserWindow::onCreate(LPCREATESTRUCT createStruct) |
|
136 { |
|
137 // Register our window. |
|
138 MiniBrowser::shared().registerWindow(this); |
|
139 |
|
140 // Create the rebar control. |
|
141 m_rebarWindow = ::CreateWindowEx(0, REBARCLASSNAME, 0, WS_VISIBLE | WS_BORDER | WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | CCS_NODIVIDER | CCS_NOPARENTALIGN | RBS_VARHEIGHT | RBS_BANDBORDERS, |
|
142 0, 0, 0, 0, m_window, 0, createStruct->hInstance, 0); |
|
143 REBARINFO rebarInfo = { 0 }; |
|
144 rebarInfo.cbSize = sizeof(rebarInfo); |
|
145 rebarInfo.fMask = 0; |
|
146 ::SendMessage(m_rebarWindow, RB_SETBARINFO, 0, (LPARAM)&rebarInfo); |
|
147 |
|
148 // Create the combo box control. |
|
149 m_comboBoxWindow = ::CreateWindowEx(0, L"combobox", 0, WS_VISIBLE | WS_CHILD | WS_TABSTOP | WS_VSCROLL | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | CBS_AUTOHSCROLL | CBS_DROPDOWN, |
|
150 0, 0, 0, 0, m_rebarWindow, 0, createStruct->hInstance, 0); |
|
151 SendMessage(m_comboBoxWindow, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), MAKELPARAM(TRUE, 0)); |
|
152 |
|
153 REBARBANDINFO bandInfo; |
|
154 bandInfo.cbSize = sizeof(bandInfo); |
|
155 bandInfo.fMask = RBBIM_STYLE | RBBIM_TEXT | RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_SIZE; |
|
156 bandInfo.fStyle = RBBS_CHILDEDGE | RBBS_GRIPPERALWAYS; |
|
157 bandInfo.lpText = L"Address"; |
|
158 bandInfo.hwndChild = m_comboBoxWindow; |
|
159 |
|
160 RECT comboBoxRect; |
|
161 ::GetWindowRect(m_comboBoxWindow, &comboBoxRect); |
|
162 bandInfo.cx = 100; |
|
163 bandInfo.cxMinChild = comboBoxRect.right - comboBoxRect.left; |
|
164 bandInfo.cyMinChild = comboBoxRect.bottom - comboBoxRect.top; |
|
165 |
|
166 // Add the band to the rebar. |
|
167 int result = ::SendMessage(m_rebarWindow, RB_INSERTBAND, (WPARAM)-1, (LPARAM)&bandInfo); |
|
168 |
|
169 // Create the browser view. |
|
170 RECT webViewRect = { 0, 0, 0, 0}; |
|
171 m_browserView.create(webViewRect, this); |
|
172 } |
|
173 |
|
174 void BrowserWindow::onDestroy() |
|
175 { |
|
176 MiniBrowser::shared().unregisterWindow(this); |
|
177 |
|
178 // FIXME: Should we close the browser view here? |
|
179 } |
|
180 |
|
181 void BrowserWindow::onNCDestroy() |
|
182 { |
|
183 delete this; |
|
184 } |
|
185 |
|
186 void BrowserWindow::onSize(int width, int height) |
|
187 { |
|
188 RECT rebarRect; |
|
189 ::GetClientRect(m_rebarWindow, &rebarRect); |
|
190 |
|
191 // Resize the rebar. |
|
192 ::MoveWindow(m_rebarWindow, 0, 0, width, rebarRect.bottom - rebarRect.top, true); |
|
193 |
|
194 RECT webViewRect; |
|
195 webViewRect.top = rebarRect.bottom; |
|
196 webViewRect.left = 0; |
|
197 webViewRect.right = width; |
|
198 webViewRect.bottom = height; |
|
199 m_browserView.setFrame(webViewRect); |
|
200 } |
|
201 |
|
202 LRESULT BrowserWindow::onCommand(int commandID, bool& handled) |
|
203 { |
|
204 switch (commandID) { |
|
205 case ID_FILE_NEW_WINDOW: |
|
206 MiniBrowser::shared().createNewWindow(); |
|
207 break; |
|
208 case ID_FILE_CLOSE: |
|
209 ::PostMessage(m_window, WM_CLOSE, 0, 0); |
|
210 break; |
|
211 case ID_DEBUG_SHOW_WEB_VIEW: { |
|
212 HMENU menu = ::GetMenu(m_window); |
|
213 bool shouldHide = ::GetMenuState(menu, ID_DEBUG_SHOW_WEB_VIEW, MF_BYCOMMAND) & MF_CHECKED; |
|
214 |
|
215 ::CheckMenuItem(menu, ID_DEBUG_SHOW_WEB_VIEW, MF_BYCOMMAND | (shouldHide ? MF_UNCHECKED : MF_CHECKED)); |
|
216 |
|
217 // Show or hide the web view. |
|
218 HWND webViewWindow = WKViewGetWindow(m_browserView.webView()); |
|
219 ::ShowWindow(webViewWindow, shouldHide ? SW_HIDE : SW_SHOW); |
|
220 break; |
|
221 } |
|
222 default: |
|
223 handled = false; |
|
224 } |
|
225 |
|
226 return 0; |
|
227 } |
|
228 |
|
229 bool BrowserWindow::handleMessage(const MSG* message) |
|
230 { |
|
231 if (message->hwnd != m_comboBoxWindow && !::IsChild(m_comboBoxWindow, message->hwnd)) |
|
232 return false; |
|
233 |
|
234 // Look for a WM_KEYDOWN message. |
|
235 if (message->message != WM_KEYDOWN) |
|
236 return false; |
|
237 |
|
238 // Look for the VK_RETURN key. |
|
239 if (message->wParam != VK_RETURN) |
|
240 return false; |
|
241 |
|
242 std::vector<WCHAR> buffer; |
|
243 int textLength = ::GetWindowTextLength(m_comboBoxWindow); |
|
244 |
|
245 buffer.resize(textLength + 1); |
|
246 ::GetWindowText(m_comboBoxWindow, &buffer[0], buffer.size()); |
|
247 |
|
248 std::wstring url(&buffer[0], buffer.size() - 1); |
|
249 |
|
250 if (url.find(L"http://")) |
|
251 url = L"http://" + url; |
|
252 |
|
253 m_browserView.goToURL(url); |
|
254 |
|
255 // We handled this message. |
|
256 return true; |
|
257 } |