2 * Copyright (C) 2006, 2008, 2013 Apple Computer, Inc. All rights reserved.
3 * Copyright (C) 2009, 2011 Brent Fulgham. All rights reserved.
4 * Copyright (C) 2009, 2010, 2011 Appcelerator, Inc. All rights reserved.
5 * Copyright (C) 2013 Alex Christensen. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
24 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 #include "WinLauncher.h"
32 #include "AccessibilityDelegate.h"
33 #include "DOMDefaultImpl.h"
34 #include "PrintWebUIDelegate.h"
35 #include "WinLauncherLibResource.h"
36 #include <WebKit/WebKitCOMAPI.h>
37 #include <wtf/ExportMacros.h>
38 #include <wtf/Platform.h>
41 #include <CoreFoundation/CFRunLoop.h>
58 #define MAX_LOADSTRING 100
59 #define URLBAR_HEIGHT 24
60 #define CONTROLBUTTON_WIDTH 24
62 static const int maxHistorySize = 10;
64 typedef _com_ptr_t<_com_IIID<IWebFrame, &__uuidof(IWebFrame)>> IWebFramePtr;
65 typedef _com_ptr_t<_com_IIID<IWebHistory, &__uuidof(IWebHistory)>> IWebHistoryPtr;
66 typedef _com_ptr_t<_com_IIID<IWebHistoryItem, &__uuidof(IWebHistoryItem)>> IWebHistoryItemPtr;
67 typedef _com_ptr_t<_com_IIID<IWebInspector, &__uuidof(IWebInspector)>> IWebInspectorPtr;
68 typedef _com_ptr_t<_com_IIID<IWebMutableURLRequest, &__uuidof(IWebMutableURLRequest)>> IWebMutableURLRequestPtr;
69 typedef _com_ptr_t<_com_IIID<IWebPreferences, &__uuidof(IWebPreferences)>> IWebPreferencesPtr;
70 typedef _com_ptr_t<_com_IIID<IWebPreferencesPrivate, &__uuidof(IWebPreferencesPrivate)>> IWebPreferencesPrivatePtr;
71 typedef _com_ptr_t<_com_IIID<IWebView, &__uuidof(IWebView)>> IWebViewPtr;
72 typedef _com_ptr_t<_com_IIID<IWebViewPrivate, &__uuidof(IWebViewPrivate)>> IWebViewPrivatePtr;
75 HINSTANCE hInst; // current instance
79 HWND hForwardButtonWnd;
80 WNDPROC DefEditProc = 0;
81 WNDPROC DefButtonProc = 0;
82 WNDPROC DefWebKitProc = 0;
83 IWebInspectorPtr gInspector;
85 IWebViewPrivatePtr gWebViewPrivate;
86 IWebPreferencesPtr gStandardPreferences;
87 IWebPreferencesPrivatePtr gPrefsPrivate;
89 WinLauncherWebHost* gWebHost = 0;
90 PrintWebUIDelegate* gPrintDelegate = 0;
91 AccessibilityDelegate* gAccessibilityDelegate = 0;
92 IWebHistoryPtr gWebHistory;
93 std::vector<IWebHistoryItemPtr> gHistoryItems;
94 TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
95 TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name
97 // Support moving the transparent window
98 POINT s_windowPosition = { 100, 100 };
99 SIZE s_windowSize = { 800, 400 };
100 bool s_usesLayeredWebView = false;
101 bool s_fullDesktop = false;
103 // Forward declarations of functions included in this code module:
104 ATOM MyRegisterClass(HINSTANCE hInstance);
105 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
106 INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
107 LRESULT CALLBACK EditProc(HWND, UINT, WPARAM, LPARAM);
108 LRESULT CALLBACK BackButtonProc(HWND, UINT, WPARAM, LPARAM);
109 LRESULT CALLBACK ForwardButtonProc(HWND, UINT, WPARAM, LPARAM);
110 LRESULT CALLBACK ReloadButtonProc(HWND, UINT, WPARAM, LPARAM);
112 static void loadURL(BSTR urlBStr);
114 static bool usesLayeredWebView()
116 return s_usesLayeredWebView;
119 static bool shouldUseFullDesktop()
121 return s_fullDesktop;
124 class SimpleEventListener : public DOMEventListener {
126 SimpleEventListener(LPWSTR type)
128 wcsncpy_s(m_eventType, 100, type, 100);
132 virtual HRESULT STDMETHODCALLTYPE handleEvent(IDOMEvent* evt)
134 wchar_t message[255];
135 wcscpy_s(message, 255, m_eventType);
136 wcscat_s(message, 255, L" event fired!");
137 ::MessageBox(0, message, L"Event Handler", MB_OK);
142 wchar_t m_eventType[100];
145 typedef _com_ptr_t<_com_IIID<IWebDataSource, &__uuidof(IWebDataSource)>> IWebDataSourcePtr;
147 HRESULT WinLauncherWebHost::updateAddressBar(IWebView* webView)
149 IWebFramePtr mainFrame;
150 HRESULT hr = webView->mainFrame(&mainFrame.GetInterfacePtr());
154 IWebDataSourcePtr dataSource;
155 hr = mainFrame->dataSource(&dataSource.GetInterfacePtr());
156 if (FAILED(hr) || !dataSource)
157 hr = mainFrame->provisionalDataSource(&dataSource.GetInterfacePtr());
158 if (FAILED(hr) || !dataSource)
161 IWebMutableURLRequestPtr request;
162 hr = dataSource->request(&request.GetInterfacePtr());
163 if (FAILED(hr) || !request)
167 hr = request->mainDocumentURL(frameURL.GetAddress());
171 ::SendMessage(hURLBarWnd, static_cast<UINT>(WM_SETTEXT), 0, reinterpret_cast<LPARAM>(frameURL.GetBSTR()));
176 HRESULT WinLauncherWebHost::didFailProvisionalLoadWithError(IWebView*, IWebError *error, IWebFrame*)
178 _bstr_t errorDescription;
179 HRESULT hr = error->localizedDescription(errorDescription.GetAddress());
181 errorDescription = L"Failed to load page and to localize error description.";
183 ::MessageBoxW(0, static_cast<LPCWSTR>(errorDescription), L"Error", MB_APPLMODAL | MB_OK);
188 HRESULT STDMETHODCALLTYPE WinLauncherWebHost::QueryInterface(REFIID riid, void** ppvObject)
191 if (IsEqualGUID(riid, IID_IUnknown))
192 *ppvObject = static_cast<IWebFrameLoadDelegate*>(this);
193 else if (IsEqualGUID(riid, IID_IWebFrameLoadDelegate))
194 *ppvObject = static_cast<IWebFrameLoadDelegate*>(this);
196 return E_NOINTERFACE;
202 ULONG STDMETHODCALLTYPE WinLauncherWebHost::AddRef(void)
207 ULONG STDMETHODCALLTYPE WinLauncherWebHost::Release(void)
209 ULONG newRef = --m_refCount;
216 static void updateMenuItemForHistoryItem(HMENU menu, IWebHistoryItem& historyItem, int currentHistoryItem)
218 UINT menuID = IDM_HISTORY_LINK0 + currentHistoryItem;
220 MENUITEMINFO menuItemInfo = {0};
221 menuItemInfo.cbSize = sizeof(MENUITEMINFO);
222 menuItemInfo.fMask = MIIM_TYPE;
223 menuItemInfo.fType = MFT_STRING;
226 historyItem.title(title.GetAddress());
227 menuItemInfo.dwTypeData = static_cast<LPWSTR>(title);
229 ::SetMenuItemInfo(menu, menuID, FALSE, &menuItemInfo);
230 ::EnableMenuItem(menu, menuID, MF_BYCOMMAND | MF_ENABLED);
233 static void showLastVisitedSites(IWebView& webView)
235 HMENU menu = ::GetMenu(hMainWnd);
237 _com_ptr_t<_com_IIID<IWebBackForwardList, &__uuidof(IWebBackForwardList)>> backForwardList;
238 HRESULT hr = webView.backForwardList(&backForwardList.GetInterfacePtr());
243 hr = backForwardList->capacity(&capacity);
248 hr = backForwardList->backListCount(&backCount);
252 UINT backSetting = MF_BYCOMMAND | (backCount) ? MF_ENABLED : MF_DISABLED;
253 ::EnableMenuItem(menu, IDM_HISTORY_BACKWARD, backSetting);
255 int forwardCount = 0;
256 hr = backForwardList->forwardListCount(&forwardCount);
260 UINT forwardSetting = MF_BYCOMMAND | (forwardCount) ? MF_ENABLED : MF_DISABLED;
261 ::EnableMenuItem(menu, IDM_HISTORY_FORWARD, forwardSetting);
263 IWebHistoryItemPtr currentItem;
264 hr = backForwardList->currentItem(¤tItem.GetInterfacePtr());
268 hr = gWebHistory->addItems(1, ¤tItem.GetInterfacePtr());
272 _com_ptr_t<_com_IIID<IWebHistoryPrivate, &__uuidof(IWebHistoryPrivate)>> webHistory;
273 hr = gWebHistory->QueryInterface(IID_IWebHistoryPrivate, reinterpret_cast<void**>(&webHistory.GetInterfacePtr()));
277 int totalListCount = 0;
278 hr = webHistory->allItems(&totalListCount, 0);
282 gHistoryItems.resize(totalListCount);
284 std::vector<IWebHistoryItem*> historyToLoad(totalListCount);
285 hr = webHistory->allItems(&totalListCount, historyToLoad.data());
290 for (auto cur = historyToLoad.begin(); cur != historyToLoad.end(); ++cur) {
291 gHistoryItems[i].Attach(*cur);
295 int allItemsOffset = 0;
296 if (totalListCount > maxHistorySize)
297 allItemsOffset = totalListCount - maxHistorySize;
299 int currentHistoryItem = 0;
300 for (int i = 0; i < totalListCount; ++i) {
301 updateMenuItemForHistoryItem(menu, *(gHistoryItems[allItemsOffset + currentHistoryItem]), currentHistoryItem);
302 ++currentHistoryItem;
305 // Hide any history we aren't using yet.
306 for (int i = currentHistoryItem; i < maxHistorySize; ++i)
307 ::EnableMenuItem(menu, IDM_HISTORY_LINK0 + i, MF_BYCOMMAND | MF_DISABLED);
310 typedef _com_ptr_t<_com_IIID<IDOMDocument, &__uuidof(IDOMDocument)>> IDOMDocumentPtr;
311 typedef _com_ptr_t<_com_IIID<IDOMElement, &__uuidof(IDOMElement)>> IDOMElementPtr;
312 typedef _com_ptr_t<_com_IIID<IDOMEventTarget, &__uuidof(IDOMEventTarget)>> IDOMEventTargetPtr;
314 HRESULT WinLauncherWebHost::didFinishLoadForFrame(IWebView* webView, IWebFrame* frame)
317 frame->DOMDocument(&doc.GetInterfacePtr());
319 IDOMElementPtr element;
320 IDOMEventTargetPtr target;
322 showLastVisitedSites(*webView);
324 // The following is for the test page:
325 HRESULT hr = doc->getElementById(L"webkit logo", &element.GetInterfacePtr());
329 hr = element->QueryInterface(IID_IDOMEventTarget, reinterpret_cast<void**>(&target.GetInterfacePtr()));
333 hr = target->addEventListener(L"click", new SimpleEventListener (L"webkit logo click"), FALSE);
340 static void resizeSubViews()
342 if (usesLayeredWebView() || !gViewWindow)
346 GetClientRect(hMainWnd, &rcClient);
347 MoveWindow(hBackButtonWnd, 0, 0, CONTROLBUTTON_WIDTH, URLBAR_HEIGHT, TRUE);
348 MoveWindow(hForwardButtonWnd, CONTROLBUTTON_WIDTH, 0, CONTROLBUTTON_WIDTH, URLBAR_HEIGHT, TRUE);
349 MoveWindow(hURLBarWnd, CONTROLBUTTON_WIDTH * 2, 0, rcClient.right, URLBAR_HEIGHT, TRUE);
350 MoveWindow(gViewWindow, 0, URLBAR_HEIGHT, rcClient.right, rcClient.bottom - URLBAR_HEIGHT, TRUE);
353 static void subclassForLayeredWindow()
355 hMainWnd = gViewWindow;
356 #if defined _M_AMD64 || defined _WIN64
357 DefWebKitProc = reinterpret_cast<WNDPROC>(::GetWindowLongPtr(hMainWnd, GWLP_WNDPROC));
358 ::SetWindowLongPtr(hMainWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(WndProc));
360 DefWebKitProc = reinterpret_cast<WNDPROC>(::GetWindowLong(hMainWnd, GWL_WNDPROC));
361 ::SetWindowLong(hMainWnd, GWL_WNDPROC, reinterpret_cast<LONG_PTR>(WndProc));
365 static void computeFullDesktopFrame()
368 if (!::SystemParametersInfo(SPI_GETWORKAREA, 0, static_cast<void*>(&desktop), 0))
371 s_windowPosition.x = 0;
372 s_windowPosition.y = 0;
373 s_windowSize.cx = desktop.right - desktop.left;
374 s_windowSize.cy = desktop.bottom - desktop.top;
377 BOOL WINAPI DllMain(HINSTANCE dllInstance, DWORD reason, LPVOID)
379 if (reason == DLL_PROCESS_ATTACH)
385 static bool setToDefaultPreferences()
387 HRESULT hr = gStandardPreferences->QueryInterface(IID_IWebPreferencesPrivate, reinterpret_cast<void**>(&gPrefsPrivate.GetInterfacePtr()));
392 gStandardPreferences->setAVFoundationEnabled(TRUE);
393 gPrefsPrivate->setAcceleratedCompositingEnabled(TRUE);
396 gPrefsPrivate->setFullScreenEnabled(TRUE);
397 gPrefsPrivate->setShowDebugBorders(FALSE);
398 gPrefsPrivate->setShowRepaintCounter(FALSE);
400 gStandardPreferences->setLoadsImagesAutomatically(TRUE);
401 gPrefsPrivate->setAuthorAndUserStylesEnabled(TRUE);
402 gStandardPreferences->setJavaScriptEnabled(TRUE);
403 gPrefsPrivate->setAllowUniversalAccessFromFileURLs(FALSE);
404 gPrefsPrivate->setAllowFileAccessFromFileURLs(TRUE);
406 gPrefsPrivate->setDeveloperExtrasEnabled(TRUE);
413 extern "C" void _CFRunLoopSetWindowsMessageQueueMask(CFRunLoopRef, uint32_t, CFStringRef);
416 extern "C" __declspec(dllexport) int WINAPI dllLauncherEntryPoint(HINSTANCE, HINSTANCE, LPTSTR, int nCmdShow)
418 #ifdef _CRTDBG_MAP_ALLOC
419 _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
420 _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
423 // TODO: Place code here.
427 INITCOMMONCONTROLSEX InitCtrlEx;
429 InitCtrlEx.dwSize = sizeof(INITCOMMONCONTROLSEX);
430 InitCtrlEx.dwICC = 0x00004000; //ICC_STANDARD_CLASSES;
431 InitCommonControlsEx(&InitCtrlEx);
433 _bstr_t requestedURL;
435 WCHAR** argv = CommandLineToArgvW(GetCommandLineW(), &argc);
436 for (int i = 1; i < argc; ++i) {
437 if (!wcsicmp(argv[i], L"--transparent"))
438 s_usesLayeredWebView = true;
439 else if (!wcsicmp(argv[i], L"--desktop"))
440 s_fullDesktop = true;
441 else if (!requestedURL)
442 requestedURL = argv[i];
445 // Initialize global strings
446 LoadString(hInst, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
447 LoadString(hInst, IDC_WINLAUNCHER, szWindowClass, MAX_LOADSTRING);
448 MyRegisterClass(hInst);
450 if (shouldUseFullDesktop())
451 computeFullDesktopFrame();
456 if (usesLayeredWebView()) {
457 hURLBarWnd = CreateWindow(L"EDIT", L"Type URL Here",
458 WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_BORDER | ES_LEFT | ES_AUTOVSCROLL,
459 s_windowPosition.x, s_windowPosition.y + s_windowSize.cy, s_windowSize.cx, URLBAR_HEIGHT,
464 hMainWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
465 CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, 0, 0, hInst, 0);
470 hBackButtonWnd = CreateWindow(L"BUTTON", L"<", WS_CHILD | WS_VISIBLE | BS_TEXT, 0, 0, 0, 0, hMainWnd, 0, hInst, 0);
471 hForwardButtonWnd = CreateWindow(L"BUTTON", L">", WS_CHILD | WS_VISIBLE | BS_TEXT, CONTROLBUTTON_WIDTH, 0, 0, 0, hMainWnd, 0, hInst, 0);
472 hURLBarWnd = CreateWindow(L"EDIT", 0, WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT | ES_AUTOVSCROLL, CONTROLBUTTON_WIDTH * 2, 0, 0, 0, hMainWnd, 0, hInst, 0);
474 ShowWindow(hMainWnd, nCmdShow);
475 UpdateWindow(hMainWnd);
478 DefEditProc = reinterpret_cast<WNDPROC>(GetWindowLongPtr(hURLBarWnd, GWLP_WNDPROC));
479 DefButtonProc = reinterpret_cast<WNDPROC>(GetWindowLongPtr(hBackButtonWnd, GWLP_WNDPROC));
480 SetWindowLongPtr(hURLBarWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(EditProc));
481 SetWindowLongPtr(hBackButtonWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(BackButtonProc));
482 SetWindowLongPtr(hForwardButtonWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(ForwardButtonProc));
484 SetFocus(hURLBarWnd);
486 RECT clientRect = { s_windowPosition.x, s_windowPosition.y, s_windowPosition.x + s_windowSize.cx, s_windowPosition.y + s_windowSize.cy };
488 IWebPreferencesPtr tmpPreferences;
489 if (FAILED(WebKitCreateInstance(CLSID_WebPreferences, 0, IID_IWebPreferences, reinterpret_cast<void**>(&tmpPreferences.GetInterfacePtr()))))
492 if (FAILED(tmpPreferences->standardPreferences(&gStandardPreferences.GetInterfacePtr())))
495 if (!setToDefaultPreferences())
498 HRESULT hr = WebKitCreateInstance(CLSID_WebView, 0, IID_IWebView, reinterpret_cast<void**>(&gWebView.GetInterfacePtr()));
502 hr = gWebView->QueryInterface(IID_IWebViewPrivate, reinterpret_cast<void**>(&gWebViewPrivate.GetInterfacePtr()));
506 hr = WebKitCreateInstance(CLSID_WebHistory, 0, __uuidof(gWebHistory), reinterpret_cast<void**>(&gWebHistory.GetInterfacePtr()));
510 gWebHost = new WinLauncherWebHost();
512 hr = gWebView->setFrameLoadDelegate(gWebHost);
516 gPrintDelegate = new PrintWebUIDelegate;
517 gPrintDelegate->AddRef();
518 hr = gWebView->setUIDelegate(gPrintDelegate);
522 gAccessibilityDelegate = new AccessibilityDelegate;
523 gAccessibilityDelegate->AddRef();
524 hr = gWebView->setAccessibilityDelegate(gAccessibilityDelegate);
528 hr = gWebView->setHostWindow(reinterpret_cast<OLE_HANDLE>(hMainWnd));
532 hr = gWebView->initWithFrame(clientRect, 0, 0);
538 hr = gWebView->mainFrame(&frame.GetInterfacePtr());
542 _bstr_t defaultHTML(L"<p style=\"background-color: #00FF00\">Testing</p><img id=\"webkit logo\" src=\"http://webkit.org/images/icon-gold.png\" alt=\"Face\"><div style=\"border: solid blue; background: white;\" contenteditable=\"true\">div with blue border</div><ul><li>foo<li>bar<li>baz</ul>");
543 frame->loadHTMLString(defaultHTML.GetBSTR(), 0);
546 hr = gWebViewPrivate->setTransparent(usesLayeredWebView());
550 hr = gWebViewPrivate->setUsesLayeredWindow(usesLayeredWebView());
554 hr = gWebViewPrivate->viewWindow(reinterpret_cast<OLE_HANDLE*>(&gViewWindow));
555 if (FAILED(hr) || !gViewWindow)
558 if (usesLayeredWebView())
559 subclassForLayeredWindow();
563 ShowWindow(gViewWindow, nCmdShow);
564 UpdateWindow(gViewWindow);
566 hAccelTable = LoadAccelerators(hInst, MAKEINTRESOURCE(IDC_WINLAUNCHER));
568 if (requestedURL.length())
569 loadURL(requestedURL.GetBSTR());
571 // Main message loop:
573 _CFRunLoopSetWindowsMessageQueueMask(CFRunLoopGetMain(), QS_ALLINPUT | QS_ALLPOSTMESSAGE, kCFRunLoopDefaultMode);
576 while (GetMessage(&msg, NULL, 0, 0)) {
577 if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) {
578 TranslateMessage(&msg);
579 DispatchMessage(&msg);
585 gPrintDelegate->Release();
588 #ifdef _CRTDBG_MAP_ALLOC
589 _CrtDumpMemoryLeaks();
595 return static_cast<int>(msg.wParam);
598 ATOM MyRegisterClass(HINSTANCE hInstance)
602 wcex.cbSize = sizeof(WNDCLASSEX);
604 wcex.style = CS_HREDRAW | CS_VREDRAW;
605 wcex.lpfnWndProc = WndProc;
608 wcex.hInstance = hInstance;
609 wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WINLAUNCHER));
610 wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
611 wcex.hbrBackground = 0;
612 wcex.lpszMenuName = MAKEINTRESOURCE(IDC_WINLAUNCHER);
613 wcex.lpszClassName = szWindowClass;
614 wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
616 return RegisterClassEx(&wcex);
619 static BOOL CALLBACK AbortProc(HDC hDC, int Error)
622 while (::PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
623 ::TranslateMessage(&msg);
624 ::DispatchMessage(&msg);
630 static HDC getPrinterDC()
633 memset(&pdlg, 0, sizeof(PRINTDLG));
634 pdlg.lStructSize = sizeof(PRINTDLG);
635 pdlg.Flags = PD_PRINTSETUP | PD_RETURNDC;
642 static void initDocStruct(DOCINFO* di, TCHAR* docname)
644 memset(di, 0, sizeof(DOCINFO));
645 di->cbSize = sizeof(DOCINFO);
646 di->lpszDocName = docname;
649 typedef _com_ptr_t<_com_IIID<IWebFramePrivate, &__uuidof(IWebFramePrivate)>> IWebFramePrivatePtr;
651 void PrintView(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
653 HDC printDC = getPrinterDC();
655 ::MessageBoxW(0, L"Error creating printing DC", L"Error", MB_APPLMODAL | MB_OK);
659 if (::SetAbortProc(printDC, AbortProc) == SP_ERROR) {
660 ::MessageBoxW(0, L"Error setting up AbortProc", L"Error", MB_APPLMODAL | MB_OK);
665 IWebFramePrivatePtr framePrivate;
666 if (FAILED(gWebView->mainFrame(&frame.GetInterfacePtr())))
669 if (FAILED(frame->QueryInterface(&framePrivate.GetInterfacePtr())))
672 framePrivate->setInPrintingMode(TRUE, printDC);
675 framePrivate->getPrintedPageCount(printDC, &pageCount);
678 initDocStruct(&di, L"WebKit Doc");
679 ::StartDoc(printDC, &di);
681 // FIXME: Need CoreGraphics implementation
682 void* graphicsContext = 0;
683 for (size_t page = 1; page <= pageCount; ++page) {
684 ::StartPage(printDC);
685 framePrivate->spoolPages(printDC, page, page, graphicsContext);
689 framePrivate->setInPrintingMode(FALSE, printDC);
695 static void ToggleMenuItem(HWND hWnd, UINT menuID)
697 HMENU menu = ::GetMenu(hWnd);
700 ::memset(&info, 0x00, sizeof(info));
701 info.cbSize = sizeof(info);
702 info.fMask = MIIM_STATE;
704 if (!::GetMenuItemInfo(menu, menuID, FALSE, &info))
707 BOOL newState = !(info.fState & MFS_CHECKED);
709 if (!gStandardPreferences || !gPrefsPrivate)
713 case IDM_AVFOUNDATION:
714 gStandardPreferences->setAVFoundationEnabled(newState);
716 case IDM_ACC_COMPOSITING:
717 gPrefsPrivate->setAcceleratedCompositingEnabled(newState);
719 case IDM_WK_FULLSCREEN:
720 gPrefsPrivate->setFullScreenEnabled(newState);
722 case IDM_COMPOSITING_BORDERS:
723 gPrefsPrivate->setShowDebugBorders(newState);
724 gPrefsPrivate->setShowRepaintCounter(newState);
726 case IDM_DISABLE_IMAGES:
727 gStandardPreferences->setLoadsImagesAutomatically(!newState);
729 case IDM_DISABLE_STYLES:
730 gPrefsPrivate->setAuthorAndUserStylesEnabled(!newState);
732 case IDM_DISABLE_JAVASCRIPT:
733 gStandardPreferences->setJavaScriptEnabled(!newState);
735 case IDM_DISABLE_LOCAL_FILE_RESTRICTIONS:
736 gPrefsPrivate->setAllowUniversalAccessFromFileURLs(newState);
737 gPrefsPrivate->setAllowFileAccessFromFileURLs(newState);
741 info.fState = (newState) ? MFS_CHECKED : MFS_UNCHECKED;
743 ::SetMenuItemInfo(menu, menuID, FALSE, &info);
746 static void LaunchInspector(HWND hwnd)
748 if (!gWebViewPrivate)
751 if (!SUCCEEDED(gWebViewPrivate->inspector(&gInspector.GetInterfacePtr())))
757 static void NavigateForwardOrBackward(HWND hWnd, UINT menuID)
762 BOOL wentBackOrForward = FALSE;
763 if (IDM_HISTORY_FORWARD == menuID)
764 gWebView->goForward(&wentBackOrForward);
766 gWebView->goBack(&wentBackOrForward);
769 static void NavigateToHistory(HWND hWnd, UINT menuID)
774 int historyEntry = menuID - IDM_HISTORY_LINK0;
775 if (historyEntry > gHistoryItems.size())
778 IWebHistoryItemPtr desiredHistoryItem = gHistoryItems[historyEntry];
779 if (!desiredHistoryItem)
782 BOOL succeeded = FALSE;
783 gWebView->goToBackForwardItem(desiredHistoryItem, &succeeded);
786 desiredHistoryItem->URLString(frameURL.GetAddress());
788 ::SendMessage(hURLBarWnd, (UINT)WM_SETTEXT, 0, (LPARAM)frameURL.GetBSTR());
791 static const int dragBarHeight = 30;
793 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
795 WNDPROC parentProc = usesLayeredWebView() ? DefWebKitProc : DefWindowProc;
799 if (usesLayeredWebView()) {
801 ::GetWindowRect(hWnd, &window);
802 // For testing our transparent window, we need a region to use as a handle for
803 // dragging. The right way to do this would be to query the web view to see what's
804 // under the mouse. However, for testing purposes we just use an arbitrary
805 // 30 pixel band at the top of the view as an arbitrary gripping location.
807 // When we are within this bad, return HT_CAPTION to tell Windows we want to
808 // treat this region as if it were the title bar on a normal window.
809 int y = HIWORD(lParam);
811 if ((y > window.top) && (y < window.top + dragBarHeight))
814 return CallWindowProc(parentProc, hWnd, message, wParam, lParam);
816 int wmId = LOWORD(wParam);
817 int wmEvent = HIWORD(wParam);
818 if (wmId >= IDM_HISTORY_LINK0 && wmId <= IDM_HISTORY_LINK9) {
819 NavigateToHistory(hWnd, wmId);
822 // Parse the menu selections:
825 DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
831 PrintView(hWnd, message, wParam, lParam);
833 case IDM_WEB_INSPECTOR:
834 LaunchInspector(hWnd);
836 case IDM_HISTORY_BACKWARD:
837 case IDM_HISTORY_FORWARD:
838 NavigateForwardOrBackward(hWnd, wmId);
840 case IDM_AVFOUNDATION:
841 case IDM_ACC_COMPOSITING:
842 case IDM_WK_FULLSCREEN:
843 case IDM_COMPOSITING_BORDERS:
844 case IDM_DISABLE_IMAGES:
845 case IDM_DISABLE_STYLES:
846 case IDM_DISABLE_JAVASCRIPT:
847 case IDM_DISABLE_LOCAL_FILE_RESTRICTIONS:
848 ToggleMenuItem(hWnd, wmId);
851 return CallWindowProc(parentProc, hWnd, message, wParam, lParam);
857 CFRunLoopStop(CFRunLoopGetMain());
862 if (!gWebView || usesLayeredWebView())
863 return CallWindowProc(parentProc, hWnd, message, wParam, lParam);
868 return CallWindowProc(parentProc, hWnd, message, wParam, lParam);
874 LRESULT CALLBACK EditProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
878 if (wParam == 13) { // Enter Key
879 wchar_t strPtr[INTERNET_MAX_URL_LENGTH];
880 *((LPWORD)strPtr) = INTERNET_MAX_URL_LENGTH;
881 int strLen = SendMessage(hDlg, EM_GETLINE, 0, (LPARAM)strPtr);
884 _bstr_t bstr(strPtr);
890 return CallWindowProc(DefEditProc, hDlg, message, wParam, lParam);
894 LRESULT CALLBACK BackButtonProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
896 BOOL wentBack = FALSE;
899 gWebView->goBack(&wentBack);
901 return CallWindowProc(DefButtonProc, hDlg, message, wParam, lParam);
905 LRESULT CALLBACK ForwardButtonProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
907 BOOL wentForward = FALSE;
910 gWebView->goForward(&wentForward);
912 return CallWindowProc(DefButtonProc, hDlg, message, wParam, lParam);
916 // Message handler for about box.
917 INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
919 UNREFERENCED_PARAMETER(lParam);
922 return (INT_PTR)TRUE;
925 if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) {
926 EndDialog(hDlg, LOWORD(wParam));
927 return (INT_PTR)TRUE;
931 return (INT_PTR)FALSE;
934 static void loadURL(BSTR urlBStr)
936 if (urlBStr && urlBStr[0] && (PathFileExists(urlBStr) || PathIsUNC(urlBStr))) {
937 TCHAR fileURL[INTERNET_MAX_URL_LENGTH];
938 DWORD fileURLLength = sizeof(fileURL)/sizeof(fileURL[0]);
940 if (SUCCEEDED(UrlCreateFromPath(urlBStr, fileURL, &fileURLLength, 0)))
941 SysReAllocString(&urlBStr, fileURL);
945 HRESULT hr = gWebView->mainFrame(&frame.GetInterfacePtr());
949 IWebMutableURLRequestPtr request;
950 hr = WebKitCreateInstance(CLSID_WebMutableURLRequest, 0, IID_IWebMutableURLRequest, (void**)&request);
954 hr = request->initWithURL(wcsstr(urlBStr, L"://") ? urlBStr : _bstr_t(L"http://") + urlBStr, WebURLRequestUseProtocolCachePolicy, 60);
958 _bstr_t methodBStr(L"GET");
959 hr = request->setHTTPMethod(methodBStr);
963 hr = frame->loadRequest(request);
967 SetFocus(gViewWindow);