1 /*
2 * Copyright (C) 2006, 2008 Apple Computer, 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 COMPUTER, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26 #include "stdafx.h"
27 #include "WinLauncher.h"
28 #include <WebKit/WebKitCOMAPI.h>
29
30 #include <commctrl.h>
31 #include <objbase.h>
32 #include <shlwapi.h>
33 #include <wininet.h>
34
35 #define MAX_LOADSTRING 100
36 #define URLBAR_HEIGHT 24
37
38 // Global Variables:
39 HINSTANCE hInst; // current instance
40 HWND hMainWnd;
41 HWND hURLBarWnd;
42 long DefEditProc;
43 IWebView* gWebView = 0;
44 HWND gViewWindow = 0;
45 WinLauncherWebHost* gWebHost = 0;
46 TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
47 TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name
48
49 // Forward declarations of functions included in this code module:
50 ATOM MyRegisterClass(HINSTANCE hInstance);
51 BOOL InitInstance(HINSTANCE, int);
52 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
53 INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
54 LRESULT CALLBACK MyEditProc(HWND, UINT, WPARAM, LPARAM);
55
56 static void loadURL(BSTR urlBStr);
57
updateAddressBar(IWebView * webView)58 HRESULT WinLauncherWebHost::updateAddressBar(IWebView* webView)
59 {
60 IWebFrame* mainFrame = 0;
61 IWebDataSource* dataSource = 0;
62 IWebMutableURLRequest* request = 0;
63 BSTR frameURL = 0;
64
65 HRESULT hr = S_OK;
66
67 hr = webView->mainFrame(&mainFrame);
68 if (FAILED(hr))
69 goto exit;
70
71 hr = mainFrame->dataSource(&dataSource);
72 if (FAILED(hr) || !dataSource)
73 hr = mainFrame->provisionalDataSource(&dataSource);
74 if (FAILED(hr) || !dataSource)
75 goto exit;
76
77 hr = dataSource->request(&request);
78 if (FAILED(hr) || !request)
79 goto exit;
80
81 hr = request->mainDocumentURL(&frameURL);
82 if (FAILED(hr))
83 goto exit;
84
85 SendMessage(hURLBarWnd, (UINT)WM_SETTEXT, 0, (LPARAM)frameURL);
86
87 exit:
88 if (mainFrame)
89 mainFrame->Release();
90 if (dataSource)
91 dataSource->Release();
92 if (request)
93 request->Release();
94 SysFreeString(frameURL);
95 return 0;
96 }
97
QueryInterface(REFIID riid,void ** ppvObject)98 HRESULT STDMETHODCALLTYPE WinLauncherWebHost::QueryInterface(REFIID riid, void** ppvObject)
99 {
100 *ppvObject = 0;
101 if (IsEqualGUID(riid, IID_IUnknown))
102 *ppvObject = static_cast<IWebFrameLoadDelegate*>(this);
103 else if (IsEqualGUID(riid, IID_IWebFrameLoadDelegate))
104 *ppvObject = static_cast<IWebFrameLoadDelegate*>(this);
105 else
106 return E_NOINTERFACE;
107
108 AddRef();
109 return S_OK;
110 }
111
AddRef(void)112 ULONG STDMETHODCALLTYPE WinLauncherWebHost::AddRef(void)
113 {
114 return ++m_refCount;
115 }
116
Release(void)117 ULONG STDMETHODCALLTYPE WinLauncherWebHost::Release(void)
118 {
119 ULONG newRef = --m_refCount;
120 if (!newRef)
121 delete(this);
122
123 return newRef;
124 }
125
resizeSubViews()126 static void resizeSubViews()
127 {
128 RECT rcClient;
129 GetClientRect(hMainWnd, &rcClient);
130 MoveWindow(hURLBarWnd, 0, 0, rcClient.right, URLBAR_HEIGHT, TRUE);
131 MoveWindow(gViewWindow, 0, URLBAR_HEIGHT, rcClient.right, rcClient.bottom - URLBAR_HEIGHT, TRUE);
132 }
133
_tWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR lpCmdLine,int nCmdShow)134 int APIENTRY _tWinMain(HINSTANCE hInstance,
135 HINSTANCE hPrevInstance,
136 LPTSTR lpCmdLine,
137 int nCmdShow)
138 {
139 #ifdef _CRTDBG_MAP_ALLOC
140 _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
141 _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
142 #endif
143
144 UNREFERENCED_PARAMETER(hPrevInstance);
145 UNREFERENCED_PARAMETER(lpCmdLine);
146
147 // TODO: Place code here.
148 MSG msg;
149 HACCEL hAccelTable;
150
151 INITCOMMONCONTROLSEX InitCtrlEx;
152
153 InitCtrlEx.dwSize = sizeof(INITCOMMONCONTROLSEX);
154 InitCtrlEx.dwICC = 0x00004000; //ICC_STANDARD_CLASSES;
155 InitCommonControlsEx(&InitCtrlEx);
156
157 // Initialize global strings
158 LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
159 LoadString(hInstance, IDC_WINLAUNCHER, szWindowClass, MAX_LOADSTRING);
160 MyRegisterClass(hInstance);
161
162 // Perform application initialization:
163 if (!InitInstance (hInstance, nCmdShow))
164 return FALSE;
165
166 // Init COM
167 OleInitialize(NULL);
168
169 hURLBarWnd = CreateWindow(L"EDIT", 0,
170 WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT | ES_AUTOVSCROLL,
171 0, 0, 0, 0,
172 hMainWnd,
173 0,
174 hInstance, 0);
175
176 DefEditProc = GetWindowLong(hURLBarWnd, GWL_WNDPROC);
177 SetWindowLong(hURLBarWnd, GWL_WNDPROC,(long)MyEditProc);
178 SetFocus(hURLBarWnd);
179
180 HRESULT hr = WebKitCreateInstance(CLSID_WebView, 0, IID_IWebView, (void**)&gWebView);
181 if (FAILED(hr))
182 goto exit;
183
184 gWebHost = new WinLauncherWebHost();
185 gWebHost->AddRef();
186 hr = gWebView->setFrameLoadDelegate(gWebHost);
187 if (FAILED(hr))
188 goto exit;
189
190 hr = gWebView->setHostWindow((OLE_HANDLE) hMainWnd);
191 if (FAILED(hr))
192 goto exit;
193
194 RECT clientRect;
195 GetClientRect(hMainWnd, &clientRect);
196 hr = gWebView->initWithFrame(clientRect, 0, 0);
197 if (FAILED(hr))
198 goto exit;
199
200 IWebFrame* frame;
201 hr = gWebView->mainFrame(&frame);
202 if (FAILED(hr))
203 goto exit;
204
205 static BSTR defaultHTML = SysAllocString(TEXT("<p style=\"background-color: #00FF00\">Testing</p><img src=\"http://webkit.org/images/icon-gold.png\" alt=\"Face\"><div style=\"border: solid blue\" contenteditable=\"true\">div with blue border</div><ul><li>foo<li>bar<li>baz</ul>"));
206 frame->loadHTMLString(defaultHTML, 0);
207 frame->Release();
208
209 IWebViewPrivate* viewExt;
210 hr = gWebView->QueryInterface(IID_IWebViewPrivate, (void**)&viewExt);
211 if (FAILED(hr))
212 goto exit;
213
214 hr = viewExt->viewWindow((OLE_HANDLE*) &gViewWindow);
215 viewExt->Release();
216 if (FAILED(hr) || !gViewWindow)
217 goto exit;
218
219 resizeSubViews();
220
221 ShowWindow(gViewWindow, nCmdShow);
222 UpdateWindow(gViewWindow);
223
224 hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WINLAUNCHER));
225
226 // Main message loop:
227 while (GetMessage(&msg, NULL, 0, 0)) {
228 if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) {
229 TranslateMessage(&msg);
230 DispatchMessage(&msg);
231 }
232 }
233
234 exit:
235 gWebView->Release();
236 shutDownWebKit();
237 #ifdef _CRTDBG_MAP_ALLOC
238 _CrtDumpMemoryLeaks();
239 #endif
240
241 // Shut down COM.
242 OleUninitialize();
243
244 return static_cast<int>(msg.wParam);
245 }
246
MyRegisterClass(HINSTANCE hInstance)247 ATOM MyRegisterClass(HINSTANCE hInstance)
248 {
249 WNDCLASSEX wcex;
250
251 wcex.cbSize = sizeof(WNDCLASSEX);
252
253 wcex.style = CS_HREDRAW | CS_VREDRAW;
254 wcex.lpfnWndProc = WndProc;
255 wcex.cbClsExtra = 0;
256 wcex.cbWndExtra = 0;
257 wcex.hInstance = hInstance;
258 wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WINLAUNCHER));
259 wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
260 wcex.hbrBackground = 0;
261 wcex.lpszMenuName = MAKEINTRESOURCE(IDC_WINLAUNCHER);
262 wcex.lpszClassName = szWindowClass;
263 wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
264
265 return RegisterClassEx(&wcex);
266 }
267
InitInstance(HINSTANCE hInstance,int nCmdShow)268 BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
269 {
270 hInst = hInstance; // Store instance handle in our global variable
271
272 hMainWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
273 CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
274
275 if (!hMainWnd)
276 return FALSE;
277
278 ShowWindow(hMainWnd, nCmdShow);
279 UpdateWindow(hMainWnd);
280
281 return TRUE;
282 }
283
WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)284 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
285 {
286 int wmId, wmEvent;
287 PAINTSTRUCT ps;
288 HDC hdc;
289
290 switch (message) {
291 case WM_COMMAND:
292 wmId = LOWORD(wParam);
293 wmEvent = HIWORD(wParam);
294 // Parse the menu selections:
295 switch (wmId) {
296 case IDM_ABOUT:
297 DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
298 break;
299 case IDM_EXIT:
300 DestroyWindow(hWnd);
301 break;
302 default:
303 return DefWindowProc(hWnd, message, wParam, lParam);
304 }
305 break;
306 case WM_DESTROY:
307 PostQuitMessage(0);
308 break;
309 case WM_SIZE:
310 if (!gWebView)
311 break;
312 resizeSubViews();
313 break;
314 default:
315 return DefWindowProc(hWnd, message, wParam, lParam);
316 }
317 return 0;
318 }
319
320
321 #define MAX_URL_LENGTH 1024
322
MyEditProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)323 LRESULT CALLBACK MyEditProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
324 {
325 switch (message) {
326 case WM_CHAR:
327 if (wParam == 13) { // Enter Key
328 wchar_t strPtr[MAX_URL_LENGTH];
329 *((LPWORD)strPtr) = MAX_URL_LENGTH;
330 int strLen = SendMessage(hDlg, EM_GETLINE, 0, (LPARAM)strPtr);
331
332 BSTR bstr = SysAllocStringLen(strPtr, strLen);
333 loadURL(bstr);
334 SysFreeString(bstr);
335
336 return 0;
337 } else
338 return (LRESULT)CallWindowProc((WNDPROC)DefEditProc,hDlg,message,wParam,lParam);
339 break;
340 default:
341 return (LRESULT)CallWindowProc((WNDPROC)DefEditProc,hDlg,message,wParam,lParam);
342 break;
343 }
344 return 0;
345 }
346
347
348 // Message handler for about box.
About(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)349 INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
350 {
351 UNREFERENCED_PARAMETER(lParam);
352 switch (message) {
353 case WM_INITDIALOG:
354 return (INT_PTR)TRUE;
355
356 case WM_COMMAND:
357 if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) {
358 EndDialog(hDlg, LOWORD(wParam));
359 return (INT_PTR)TRUE;
360 }
361 break;
362 }
363 return (INT_PTR)FALSE;
364 }
365
loadURL(BSTR urlBStr)366 static void loadURL(BSTR urlBStr)
367 {
368 IWebFrame* frame = 0;
369 IWebMutableURLRequest* request = 0;
370
371 static BSTR methodBStr = SysAllocString(TEXT("GET"));
372
373 if (urlBStr && urlBStr[0] && (PathFileExists(urlBStr) || PathIsUNC(urlBStr))) {
374 TCHAR fileURL[INTERNET_MAX_URL_LENGTH];
375 DWORD fileURLLength = sizeof(fileURL)/sizeof(fileURL[0]);
376
377 if (SUCCEEDED(UrlCreateFromPath(urlBStr, fileURL, &fileURLLength, 0)))
378 SysReAllocString(&urlBStr, fileURL);
379 }
380
381 HRESULT hr = gWebView->mainFrame(&frame);
382 if (FAILED(hr))
383 goto exit;
384
385 hr = WebKitCreateInstance(CLSID_WebMutableURLRequest, 0, IID_IWebMutableURLRequest, (void**)&request);
386 if (FAILED(hr))
387 goto exit;
388
389 hr = request->initWithURL(urlBStr, WebURLRequestUseProtocolCachePolicy, 60);
390 if (FAILED(hr))
391 goto exit;
392
393 hr = request->setHTTPMethod(methodBStr);
394 if (FAILED(hr))
395 goto exit;
396
397 hr = frame->loadRequest(request);
398 if (FAILED(hr))
399 goto exit;
400
401 SetFocus(gViewWindow);
402
403 exit:
404 if (frame)
405 frame->Release();
406 if (request)
407 request->Release();
408 }
409