• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
BrowserWindow()39 BrowserWindow::BrowserWindow()
40     : m_window(0)
41     , m_rebarWindow(0)
42     , m_comboBoxWindow(0)
43 {
44 }
45 
BrowserWindowWndProc(HWND window,UINT message,WPARAM wParam,LPARAM lParam)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 
wndProc(HWND window,UINT message,WPARAM wParam,LPARAM lParam)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_ERASEBKGND:
74         lResult = 1;
75         break;
76 
77     case WM_COMMAND:
78         lResult = onCommand(LOWORD(wParam), handled);
79         break;
80 
81     case WM_SIZE:
82         onSize(LOWORD(lParam), HIWORD(lParam));
83         break;
84 
85     case WM_DESTROY:
86         onDestroy();
87         break;
88 
89     case WM_NCDESTROY:
90         onNCDestroy();
91         break;
92 
93     default:
94         handled = false;
95     }
96 
97     if (!handled)
98         lResult = ::DefWindowProc(window, message, wParam, lParam);
99 
100     return lResult;
101 }
102 
createWindow(int x,int y,int width,int height)103 void BrowserWindow::createWindow(int x, int y, int width, int height)
104 {
105     assert(!m_window);
106 
107     // Register the class.
108     WNDCLASSEX windowClass = { 0 };
109     windowClass.cbSize = sizeof(windowClass);
110     windowClass.style = 0;
111     windowClass.lpfnWndProc = BrowserWindowWndProc;
112     windowClass.cbClsExtra = 0;
113     windowClass.cbWndExtra = sizeof(this);
114     windowClass.hInstance = MiniBrowser::shared().instance();
115     windowClass.hIcon = 0;
116     windowClass.hCursor = ::LoadCursor(0, IDC_ARROW);
117     windowClass.hbrBackground = (HBRUSH)::GetStockObject(WHITE_BRUSH);
118     windowClass.lpszMenuName = MAKEINTRESOURCE(IDR_MAINFRAME);
119     windowClass.lpszClassName = L"MiniBrowser";
120     windowClass.hIconSm = 0;
121 
122     ::RegisterClassEx(&windowClass);
123 
124     ::CreateWindowW(L"MiniBrowser", L"MiniBrowser", WS_OVERLAPPEDWINDOW, x, y, width, height, 0, 0, MiniBrowser::shared().instance(), this);
125 }
126 
showWindow()127 void BrowserWindow::showWindow()
128 {
129     assert(m_window);
130 
131     ::ShowWindow(m_window, SW_SHOWNORMAL);
132 }
133 
goToURL(const std::wstring & url)134 void BrowserWindow::goToURL(const std::wstring& url)
135 {
136     m_browserView.goToURL(url);
137 }
138 
onCreate(LPCREATESTRUCT createStruct)139 void BrowserWindow::onCreate(LPCREATESTRUCT createStruct)
140 {
141     // Register our window.
142     MiniBrowser::shared().registerWindow(this);
143 
144     // Create the rebar control.
145     m_rebarWindow = ::CreateWindowEx(0, REBARCLASSNAME, 0, WS_VISIBLE | WS_BORDER | WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | CCS_NODIVIDER | CCS_NOPARENTALIGN | RBS_VARHEIGHT | RBS_BANDBORDERS,
146                                      0, 0, 0, 0, m_window, 0, createStruct->hInstance, 0);
147     REBARINFO rebarInfo = { 0 };
148     rebarInfo.cbSize = sizeof(rebarInfo);
149     rebarInfo.fMask = 0;
150     ::SendMessage(m_rebarWindow, RB_SETBARINFO, 0, (LPARAM)&rebarInfo);
151 
152     // Create the combo box control.
153     m_comboBoxWindow = ::CreateWindowEx(0, L"combobox", 0, WS_VISIBLE | WS_CHILD | WS_TABSTOP | WS_VSCROLL | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | CBS_AUTOHSCROLL | CBS_DROPDOWN,
154                                         0, 0, 0, 0, m_rebarWindow, 0, createStruct->hInstance, 0);
155     SendMessage(m_comboBoxWindow, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), MAKELPARAM(TRUE, 0));
156 
157     REBARBANDINFO bandInfo;
158     bandInfo.cbSize = sizeof(bandInfo);
159     bandInfo.fMask = RBBIM_STYLE | RBBIM_TEXT | RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_SIZE;
160     bandInfo.fStyle = RBBS_CHILDEDGE | RBBS_GRIPPERALWAYS;
161     bandInfo.lpText = L"Address";
162     bandInfo.hwndChild = m_comboBoxWindow;
163 
164     RECT comboBoxRect;
165     ::GetWindowRect(m_comboBoxWindow, &comboBoxRect);
166     bandInfo.cx = 100;
167     bandInfo.cxMinChild = comboBoxRect.right - comboBoxRect.left;
168     bandInfo.cyMinChild = comboBoxRect.bottom - comboBoxRect.top;
169 
170     // Add the band to the rebar.
171     int result = ::SendMessage(m_rebarWindow, RB_INSERTBAND, (WPARAM)-1, (LPARAM)&bandInfo);
172 
173     // Create the browser view.
174     RECT webViewRect = { 0, 0, 0, 0};
175     m_browserView.create(webViewRect, this);
176 }
177 
onDestroy()178 void BrowserWindow::onDestroy()
179 {
180     MiniBrowser::shared().unregisterWindow(this);
181 
182     // FIXME: Should we close the browser view here?
183 }
184 
onNCDestroy()185 void BrowserWindow::onNCDestroy()
186 {
187     delete this;
188 }
189 
onSize(int width,int height)190 void BrowserWindow::onSize(int width, int height)
191 {
192     RECT rebarRect;
193     ::GetClientRect(m_rebarWindow, &rebarRect);
194 
195     // Resize the rebar.
196     ::MoveWindow(m_rebarWindow, 0, 0, width, rebarRect.bottom - rebarRect.top, true);
197 
198     RECT webViewRect;
199     webViewRect.top = rebarRect.bottom;
200     webViewRect.left = 0;
201     webViewRect.right = width;
202     webViewRect.bottom = height;
203     m_browserView.setFrame(webViewRect);
204 }
205 
onCommand(int commandID,bool & handled)206 LRESULT BrowserWindow::onCommand(int commandID, bool& handled)
207 {
208     switch (commandID) {
209     case ID_FILE_NEW_WINDOW:
210         MiniBrowser::shared().createNewWindow();
211         break;
212     case ID_FILE_CLOSE:
213         ::PostMessage(m_window, WM_CLOSE, 0, 0);
214         break;
215     case ID_DEBUG_SHOW_WEB_VIEW: {
216         HMENU menu = ::GetMenu(m_window);
217         bool shouldHide = ::GetMenuState(menu, ID_DEBUG_SHOW_WEB_VIEW, MF_BYCOMMAND) & MF_CHECKED;
218 
219         ::CheckMenuItem(menu, ID_DEBUG_SHOW_WEB_VIEW, MF_BYCOMMAND | (shouldHide ? MF_UNCHECKED : MF_CHECKED));
220 
221         // Show or hide the web view.
222         HWND webViewWindow = WKViewGetWindow(m_browserView.webView());
223         ::ShowWindow(webViewWindow, shouldHide ? SW_HIDE : SW_SHOW);
224         break;
225     }
226     default:
227         handled = false;
228     }
229 
230     return 0;
231 }
232 
handleMessage(const MSG * message)233 bool BrowserWindow::handleMessage(const MSG* message)
234 {
235     if (message->hwnd != m_comboBoxWindow && !::IsChild(m_comboBoxWindow, message->hwnd))
236         return false;
237 
238     // Look for a WM_KEYDOWN message.
239     if (message->message != WM_KEYDOWN)
240         return false;
241 
242     // Look for the VK_RETURN key.
243     if (message->wParam != VK_RETURN)
244         return false;
245 
246     std::vector<WCHAR> buffer;
247     int textLength = ::GetWindowTextLength(m_comboBoxWindow);
248 
249     buffer.resize(textLength + 1);
250     ::GetWindowText(m_comboBoxWindow, &buffer[0], buffer.size());
251 
252     std::wstring url(&buffer[0], buffer.size() - 1);
253 
254     if (url.find(L"http://"))
255         url = L"http://" + url;
256 
257     m_browserView.goToURL(url);
258 
259     // We handled this message.
260     return true;
261 }
262