|
1 /* |
|
2 * Copyright (C) 2006, 2008 Apple Computer, Inc. All rights reserved. |
|
3 * Copyright (C) 2009 Brent Fulgha. All rights reserved. |
|
4 * |
|
5 * Redistribution and use in source and binary forms, with or without |
|
6 * modification, are permitted provided that the following conditions |
|
7 * are met: |
|
8 * 1. Redistributions of source code must retain the above copyright |
|
9 * notice, this list of conditions and the following disclaimer. |
|
10 * 2. Redistributions in binary form must reproduce the above copyright |
|
11 * notice, this list of conditions and the following disclaimer in the |
|
12 * documentation and/or other materials provided with the distribution. |
|
13 * |
|
14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY |
|
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR |
|
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
|
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
|
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
|
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
|
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
|
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
25 */ |
|
26 |
|
27 #include "stdafx.h" |
|
28 #include "WinLauncher.h" |
|
29 #include <WebKit/WebKitCOMAPI.h> |
|
30 |
|
31 #include <commctrl.h> |
|
32 #include <commdlg.h> |
|
33 #include <objbase.h> |
|
34 #include <shlwapi.h> |
|
35 #include <wininet.h> |
|
36 |
|
37 #include "PrintWebUIDelegate.h" |
|
38 |
|
39 #define MAX_LOADSTRING 100 |
|
40 #define URLBAR_HEIGHT 24 |
|
41 |
|
42 // Global Variables: |
|
43 HINSTANCE hInst; // current instance |
|
44 HWND hMainWnd; |
|
45 HWND hURLBarWnd; |
|
46 long DefEditProc; |
|
47 IWebView* gWebView = 0; |
|
48 HWND gViewWindow = 0; |
|
49 WinLauncherWebHost* gWebHost = 0; |
|
50 PrintWebUIDelegate* gPrintDelegate = 0; |
|
51 TCHAR szTitle[MAX_LOADSTRING]; // The title bar text |
|
52 TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name |
|
53 |
|
54 // Forward declarations of functions included in this code module: |
|
55 ATOM MyRegisterClass(HINSTANCE hInstance); |
|
56 BOOL InitInstance(HINSTANCE, int); |
|
57 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); |
|
58 INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); |
|
59 LRESULT CALLBACK MyEditProc(HWND, UINT, WPARAM, LPARAM); |
|
60 |
|
61 static void loadURL(BSTR urlBStr); |
|
62 |
|
63 HRESULT WinLauncherWebHost::updateAddressBar(IWebView* webView) |
|
64 { |
|
65 IWebFrame* mainFrame = 0; |
|
66 IWebDataSource* dataSource = 0; |
|
67 IWebMutableURLRequest* request = 0; |
|
68 BSTR frameURL = 0; |
|
69 |
|
70 HRESULT hr = S_OK; |
|
71 |
|
72 hr = webView->mainFrame(&mainFrame); |
|
73 if (FAILED(hr)) |
|
74 goto exit; |
|
75 |
|
76 hr = mainFrame->dataSource(&dataSource); |
|
77 if (FAILED(hr) || !dataSource) |
|
78 hr = mainFrame->provisionalDataSource(&dataSource); |
|
79 if (FAILED(hr) || !dataSource) |
|
80 goto exit; |
|
81 |
|
82 hr = dataSource->request(&request); |
|
83 if (FAILED(hr) || !request) |
|
84 goto exit; |
|
85 |
|
86 hr = request->mainDocumentURL(&frameURL); |
|
87 if (FAILED(hr)) |
|
88 goto exit; |
|
89 |
|
90 SendMessage(hURLBarWnd, (UINT)WM_SETTEXT, 0, (LPARAM)frameURL); |
|
91 |
|
92 exit: |
|
93 if (mainFrame) |
|
94 mainFrame->Release(); |
|
95 if (dataSource) |
|
96 dataSource->Release(); |
|
97 if (request) |
|
98 request->Release(); |
|
99 SysFreeString(frameURL); |
|
100 return 0; |
|
101 } |
|
102 |
|
103 HRESULT STDMETHODCALLTYPE WinLauncherWebHost::QueryInterface(REFIID riid, void** ppvObject) |
|
104 { |
|
105 *ppvObject = 0; |
|
106 if (IsEqualGUID(riid, IID_IUnknown)) |
|
107 *ppvObject = static_cast<IWebFrameLoadDelegate*>(this); |
|
108 else if (IsEqualGUID(riid, IID_IWebFrameLoadDelegate)) |
|
109 *ppvObject = static_cast<IWebFrameLoadDelegate*>(this); |
|
110 else |
|
111 return E_NOINTERFACE; |
|
112 |
|
113 AddRef(); |
|
114 return S_OK; |
|
115 } |
|
116 |
|
117 ULONG STDMETHODCALLTYPE WinLauncherWebHost::AddRef(void) |
|
118 { |
|
119 return ++m_refCount; |
|
120 } |
|
121 |
|
122 ULONG STDMETHODCALLTYPE WinLauncherWebHost::Release(void) |
|
123 { |
|
124 ULONG newRef = --m_refCount; |
|
125 if (!newRef) |
|
126 delete(this); |
|
127 |
|
128 return newRef; |
|
129 } |
|
130 |
|
131 static void resizeSubViews() |
|
132 { |
|
133 RECT rcClient; |
|
134 GetClientRect(hMainWnd, &rcClient); |
|
135 MoveWindow(hURLBarWnd, 0, 0, rcClient.right, URLBAR_HEIGHT, TRUE); |
|
136 MoveWindow(gViewWindow, 0, URLBAR_HEIGHT, rcClient.right, rcClient.bottom - URLBAR_HEIGHT, TRUE); |
|
137 } |
|
138 |
|
139 int APIENTRY _tWinMain(HINSTANCE hInstance, |
|
140 HINSTANCE hPrevInstance, |
|
141 LPTSTR lpCmdLine, |
|
142 int nCmdShow) |
|
143 { |
|
144 #ifdef _CRTDBG_MAP_ALLOC |
|
145 _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR); |
|
146 _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); |
|
147 #endif |
|
148 |
|
149 UNREFERENCED_PARAMETER(hPrevInstance); |
|
150 UNREFERENCED_PARAMETER(lpCmdLine); |
|
151 |
|
152 // TODO: Place code here. |
|
153 MSG msg; |
|
154 HACCEL hAccelTable; |
|
155 |
|
156 INITCOMMONCONTROLSEX InitCtrlEx; |
|
157 |
|
158 InitCtrlEx.dwSize = sizeof(INITCOMMONCONTROLSEX); |
|
159 InitCtrlEx.dwICC = 0x00004000; //ICC_STANDARD_CLASSES; |
|
160 InitCommonControlsEx(&InitCtrlEx); |
|
161 |
|
162 // Initialize global strings |
|
163 LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); |
|
164 LoadString(hInstance, IDC_WINLAUNCHER, szWindowClass, MAX_LOADSTRING); |
|
165 MyRegisterClass(hInstance); |
|
166 |
|
167 // Perform application initialization: |
|
168 if (!InitInstance (hInstance, nCmdShow)) |
|
169 return FALSE; |
|
170 |
|
171 // Init COM |
|
172 OleInitialize(NULL); |
|
173 |
|
174 hURLBarWnd = CreateWindow(L"EDIT", 0, |
|
175 WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT | ES_AUTOVSCROLL, |
|
176 0, 0, 0, 0, |
|
177 hMainWnd, |
|
178 0, |
|
179 hInstance, 0); |
|
180 |
|
181 DefEditProc = GetWindowLong(hURLBarWnd, GWL_WNDPROC); |
|
182 SetWindowLong(hURLBarWnd, GWL_WNDPROC,(long)MyEditProc); |
|
183 SetFocus(hURLBarWnd); |
|
184 |
|
185 HRESULT hr = WebKitCreateInstance(CLSID_WebView, 0, IID_IWebView, (void**)&gWebView); |
|
186 if (FAILED(hr)) |
|
187 goto exit; |
|
188 |
|
189 gWebHost = new WinLauncherWebHost(); |
|
190 gWebHost->AddRef(); |
|
191 hr = gWebView->setFrameLoadDelegate(gWebHost); |
|
192 if (FAILED(hr)) |
|
193 goto exit; |
|
194 |
|
195 gPrintDelegate = new PrintWebUIDelegate; |
|
196 gPrintDelegate->AddRef(); |
|
197 hr = gWebView->setUIDelegate(gPrintDelegate); |
|
198 if (FAILED (hr)) |
|
199 goto exit; |
|
200 |
|
201 hr = gWebView->setHostWindow((OLE_HANDLE) hMainWnd); |
|
202 if (FAILED(hr)) |
|
203 goto exit; |
|
204 |
|
205 RECT clientRect; |
|
206 GetClientRect(hMainWnd, &clientRect); |
|
207 hr = gWebView->initWithFrame(clientRect, 0, 0); |
|
208 if (FAILED(hr)) |
|
209 goto exit; |
|
210 |
|
211 IWebFrame* frame; |
|
212 hr = gWebView->mainFrame(&frame); |
|
213 if (FAILED(hr)) |
|
214 goto exit; |
|
215 |
|
216 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>")); |
|
217 frame->loadHTMLString(defaultHTML, 0); |
|
218 frame->Release(); |
|
219 |
|
220 IWebViewPrivate* viewExt; |
|
221 hr = gWebView->QueryInterface(IID_IWebViewPrivate, (void**)&viewExt); |
|
222 if (FAILED(hr)) |
|
223 goto exit; |
|
224 |
|
225 hr = viewExt->viewWindow((OLE_HANDLE*) &gViewWindow); |
|
226 viewExt->Release(); |
|
227 if (FAILED(hr) || !gViewWindow) |
|
228 goto exit; |
|
229 |
|
230 resizeSubViews(); |
|
231 |
|
232 ShowWindow(gViewWindow, nCmdShow); |
|
233 UpdateWindow(gViewWindow); |
|
234 |
|
235 hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WINLAUNCHER)); |
|
236 |
|
237 // Main message loop: |
|
238 while (GetMessage(&msg, NULL, 0, 0)) { |
|
239 if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { |
|
240 TranslateMessage(&msg); |
|
241 DispatchMessage(&msg); |
|
242 } |
|
243 } |
|
244 |
|
245 exit: |
|
246 gPrintDelegate->Release(); |
|
247 gWebView->Release(); |
|
248 shutDownWebKit(); |
|
249 #ifdef _CRTDBG_MAP_ALLOC |
|
250 _CrtDumpMemoryLeaks(); |
|
251 #endif |
|
252 |
|
253 // Shut down COM. |
|
254 OleUninitialize(); |
|
255 |
|
256 return static_cast<int>(msg.wParam); |
|
257 } |
|
258 |
|
259 ATOM MyRegisterClass(HINSTANCE hInstance) |
|
260 { |
|
261 WNDCLASSEX wcex; |
|
262 |
|
263 wcex.cbSize = sizeof(WNDCLASSEX); |
|
264 |
|
265 wcex.style = CS_HREDRAW | CS_VREDRAW; |
|
266 wcex.lpfnWndProc = WndProc; |
|
267 wcex.cbClsExtra = 0; |
|
268 wcex.cbWndExtra = 0; |
|
269 wcex.hInstance = hInstance; |
|
270 wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WINLAUNCHER)); |
|
271 wcex.hCursor = LoadCursor(NULL, IDC_ARROW); |
|
272 wcex.hbrBackground = 0; |
|
273 wcex.lpszMenuName = MAKEINTRESOURCE(IDC_WINLAUNCHER); |
|
274 wcex.lpszClassName = szWindowClass; |
|
275 wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); |
|
276 |
|
277 return RegisterClassEx(&wcex); |
|
278 } |
|
279 |
|
280 BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) |
|
281 { |
|
282 hInst = hInstance; // Store instance handle in our global variable |
|
283 |
|
284 hMainWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, |
|
285 CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); |
|
286 |
|
287 if (!hMainWnd) |
|
288 return FALSE; |
|
289 |
|
290 ShowWindow(hMainWnd, nCmdShow); |
|
291 UpdateWindow(hMainWnd); |
|
292 |
|
293 return TRUE; |
|
294 } |
|
295 |
|
296 static BOOL CALLBACK AbortProc(HDC hDC, int Error) |
|
297 { |
|
298 MSG msg; |
|
299 while (::PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) { |
|
300 ::TranslateMessage(&msg); |
|
301 ::DispatchMessage(&msg); |
|
302 } |
|
303 |
|
304 return TRUE; |
|
305 } |
|
306 |
|
307 static HDC getPrinterDC() |
|
308 { |
|
309 PRINTDLG pdlg; |
|
310 memset(&pdlg, 0, sizeof(PRINTDLG)); |
|
311 pdlg.lStructSize = sizeof(PRINTDLG); |
|
312 pdlg.Flags = PD_PRINTSETUP | PD_RETURNDC; |
|
313 |
|
314 ::PrintDlg(&pdlg); |
|
315 |
|
316 return pdlg.hDC; |
|
317 } |
|
318 |
|
319 static void initDocStruct(DOCINFO* di, TCHAR* docname) |
|
320 { |
|
321 memset(di, 0, sizeof(DOCINFO)); |
|
322 di->cbSize = sizeof(DOCINFO); |
|
323 di->lpszDocName = docname; |
|
324 } |
|
325 |
|
326 void PrintView(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) |
|
327 { |
|
328 HDC printDC = getPrinterDC(); |
|
329 if (!printDC) { |
|
330 ::MessageBox(0, _T("Error creating printing DC"), _T("Error"), MB_APPLMODAL | MB_OK); |
|
331 return; |
|
332 } |
|
333 |
|
334 if (::SetAbortProc(printDC, AbortProc) == SP_ERROR) { |
|
335 ::MessageBox(0, _T("Error setting up AbortProc"), _T("Error"), MB_APPLMODAL | MB_OK); |
|
336 return; |
|
337 } |
|
338 |
|
339 IWebFrame* frame = 0; |
|
340 if (FAILED(gWebView->mainFrame(&frame))) |
|
341 goto exit; |
|
342 |
|
343 IWebFramePrivate* framePrivate = 0; |
|
344 if (FAILED(frame->QueryInterface(&framePrivate))) |
|
345 goto exit; |
|
346 |
|
347 framePrivate->setInPrintingMode(TRUE, printDC); |
|
348 |
|
349 UINT pageCount = 0; |
|
350 framePrivate->getPrintedPageCount(printDC, &pageCount); |
|
351 |
|
352 DOCINFO di; |
|
353 initDocStruct(&di, _T("WebKit Doc")); |
|
354 ::StartDoc(printDC, &di); |
|
355 |
|
356 // FIXME: Need CoreGraphics implementation |
|
357 void* graphicsContext = 0; |
|
358 for (size_t page = 1; page <= pageCount; ++page) { |
|
359 ::StartPage(printDC); |
|
360 framePrivate->spoolPages(printDC, page, page, graphicsContext); |
|
361 ::EndPage(printDC); |
|
362 } |
|
363 |
|
364 framePrivate->setInPrintingMode(FALSE, printDC); |
|
365 |
|
366 ::EndDoc(printDC); |
|
367 ::DeleteDC(printDC); |
|
368 |
|
369 exit: |
|
370 if (frame) |
|
371 frame->Release(); |
|
372 if (framePrivate) |
|
373 framePrivate->Release(); |
|
374 } |
|
375 |
|
376 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) |
|
377 { |
|
378 int wmId, wmEvent; |
|
379 PAINTSTRUCT ps; |
|
380 HDC hdc; |
|
381 |
|
382 switch (message) { |
|
383 case WM_COMMAND: |
|
384 wmId = LOWORD(wParam); |
|
385 wmEvent = HIWORD(wParam); |
|
386 // Parse the menu selections: |
|
387 switch (wmId) { |
|
388 case IDM_ABOUT: |
|
389 DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); |
|
390 break; |
|
391 case IDM_EXIT: |
|
392 DestroyWindow(hWnd); |
|
393 break; |
|
394 case IDM_PRINT: |
|
395 PrintView(hWnd, message, wParam, lParam); |
|
396 break; |
|
397 default: |
|
398 return DefWindowProc(hWnd, message, wParam, lParam); |
|
399 } |
|
400 break; |
|
401 case WM_DESTROY: |
|
402 PostQuitMessage(0); |
|
403 break; |
|
404 case WM_SIZE: |
|
405 if (!gWebView) |
|
406 break; |
|
407 resizeSubViews(); |
|
408 break; |
|
409 default: |
|
410 return DefWindowProc(hWnd, message, wParam, lParam); |
|
411 } |
|
412 return 0; |
|
413 } |
|
414 |
|
415 |
|
416 #define MAX_URL_LENGTH 1024 |
|
417 |
|
418 LRESULT CALLBACK MyEditProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) |
|
419 { |
|
420 switch (message) { |
|
421 case WM_CHAR: |
|
422 if (wParam == 13) { // Enter Key |
|
423 wchar_t strPtr[MAX_URL_LENGTH]; |
|
424 *((LPWORD)strPtr) = MAX_URL_LENGTH; |
|
425 int strLen = SendMessage(hDlg, EM_GETLINE, 0, (LPARAM)strPtr); |
|
426 |
|
427 BSTR bstr = SysAllocStringLen(strPtr, strLen); |
|
428 loadURL(bstr); |
|
429 SysFreeString(bstr); |
|
430 |
|
431 return 0; |
|
432 } else |
|
433 return (LRESULT)CallWindowProc((WNDPROC)DefEditProc,hDlg,message,wParam,lParam); |
|
434 break; |
|
435 default: |
|
436 return (LRESULT)CallWindowProc((WNDPROC)DefEditProc,hDlg,message,wParam,lParam); |
|
437 break; |
|
438 } |
|
439 return 0; |
|
440 } |
|
441 |
|
442 |
|
443 // Message handler for about box. |
|
444 INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) |
|
445 { |
|
446 UNREFERENCED_PARAMETER(lParam); |
|
447 switch (message) { |
|
448 case WM_INITDIALOG: |
|
449 return (INT_PTR)TRUE; |
|
450 |
|
451 case WM_COMMAND: |
|
452 if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { |
|
453 EndDialog(hDlg, LOWORD(wParam)); |
|
454 return (INT_PTR)TRUE; |
|
455 } |
|
456 break; |
|
457 } |
|
458 return (INT_PTR)FALSE; |
|
459 } |
|
460 |
|
461 static void loadURL(BSTR urlBStr) |
|
462 { |
|
463 IWebFrame* frame = 0; |
|
464 IWebMutableURLRequest* request = 0; |
|
465 |
|
466 static BSTR methodBStr = SysAllocString(TEXT("GET")); |
|
467 |
|
468 if (urlBStr && urlBStr[0] && (PathFileExists(urlBStr) || PathIsUNC(urlBStr))) { |
|
469 TCHAR fileURL[INTERNET_MAX_URL_LENGTH]; |
|
470 DWORD fileURLLength = sizeof(fileURL)/sizeof(fileURL[0]); |
|
471 |
|
472 if (SUCCEEDED(UrlCreateFromPath(urlBStr, fileURL, &fileURLLength, 0))) |
|
473 SysReAllocString(&urlBStr, fileURL); |
|
474 } |
|
475 |
|
476 HRESULT hr = gWebView->mainFrame(&frame); |
|
477 if (FAILED(hr)) |
|
478 goto exit; |
|
479 |
|
480 hr = WebKitCreateInstance(CLSID_WebMutableURLRequest, 0, IID_IWebMutableURLRequest, (void**)&request); |
|
481 if (FAILED(hr)) |
|
482 goto exit; |
|
483 |
|
484 hr = request->initWithURL(urlBStr, WebURLRequestUseProtocolCachePolicy, 60); |
|
485 if (FAILED(hr)) |
|
486 goto exit; |
|
487 |
|
488 hr = request->setHTTPMethod(methodBStr); |
|
489 if (FAILED(hr)) |
|
490 goto exit; |
|
491 |
|
492 hr = frame->loadRequest(request); |
|
493 if (FAILED(hr)) |
|
494 goto exit; |
|
495 |
|
496 SetFocus(gViewWindow); |
|
497 |
|
498 exit: |
|
499 if (frame) |
|
500 frame->Release(); |
|
501 if (request) |
|
502 request->Release(); |
|
503 } |