Hide focus ring immediately in gesture end operation
[framework/web/webkit-efl.git] / Tools / WinLauncher / WinLauncher.cpp
1 /*
2  * Copyright (C) 2006, 2008 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  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
16  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
19  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
23  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
26  */
27
28 #include "stdafx.h"
29 #include "WinLauncher.h"
30
31 #include "DOMDefaultImpl.h"
32 #include "PrintWebUIDelegate.h"
33 #include <WebKit/WebKitCOMAPI.h>
34
35 #include <commctrl.h>
36 #include <commdlg.h>
37 #include <objbase.h>
38 #include <shellapi.h>
39 #include <shlwapi.h>
40 #include <string>
41 #include <wininet.h>
42
43 #define MAX_LOADSTRING 100
44 #define URLBAR_HEIGHT  24
45
46 // Global Variables:
47 HINSTANCE hInst;                                // current instance
48 HWND hMainWnd;
49 HWND hURLBarWnd;
50 WNDPROC DefEditProc = 0;
51 WNDPROC DefWebKitProc = 0;
52 IWebView* gWebView = 0;
53 IWebViewPrivate* gWebViewPrivate = 0;
54 HWND gViewWindow = 0;
55 WinLauncherWebHost* gWebHost = 0;
56 PrintWebUIDelegate* gPrintDelegate = 0;
57 TCHAR szTitle[MAX_LOADSTRING];                    // The title bar text
58 TCHAR szWindowClass[MAX_LOADSTRING];            // the main window class name
59
60 // Support moving the transparent window
61 POINT s_windowPosition = { 100, 100 };
62 SIZE s_windowSize = { 800, 400 };
63 bool s_usesLayeredWebView = false;
64 bool s_fullDesktop = false;
65
66 // Forward declarations of functions included in this code module:
67 ATOM                MyRegisterClass(HINSTANCE hInstance);
68 LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
69 INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);
70 LRESULT CALLBACK    MyEditProc(HWND, UINT, WPARAM, LPARAM);
71
72 static void loadURL(BSTR urlBStr);
73
74 static bool usesLayeredWebView()
75 {
76     return s_usesLayeredWebView;
77 }
78
79 static bool shouldUseFullDesktop()
80 {
81     return s_fullDesktop;
82 }
83
84 class SimpleEventListener : public DOMEventListener {
85 public:
86     SimpleEventListener(LPWSTR type)
87     {
88         wcsncpy_s(m_eventType, 100, type, 100);
89         m_eventType[99] = 0;
90     }
91
92     virtual HRESULT STDMETHODCALLTYPE handleEvent(IDOMEvent* evt)
93     {
94         wchar_t message[255];
95         wcscpy_s(message, 255, m_eventType);
96         wcscat_s(message, 255, L" event fired!");
97         ::MessageBox(0, message, L"Event Handler", MB_OK);
98         return S_OK;
99     }
100
101 private:
102     wchar_t m_eventType[100];
103 };
104
105 HRESULT WinLauncherWebHost::updateAddressBar(IWebView* webView)
106 {
107     IWebFrame* mainFrame = 0;
108     IWebDataSource* dataSource = 0;
109     IWebMutableURLRequest* request = 0;
110     BSTR frameURL = 0;
111
112     HRESULT hr = S_OK;
113
114     hr = webView->mainFrame(&mainFrame);
115     if (FAILED(hr))
116         goto exit;
117
118     hr = mainFrame->dataSource(&dataSource);
119     if (FAILED(hr) || !dataSource)
120         hr = mainFrame->provisionalDataSource(&dataSource);
121     if (FAILED(hr) || !dataSource)
122         goto exit;
123
124     hr = dataSource->request(&request);
125     if (FAILED(hr) || !request)
126         goto exit;
127
128     hr = request->mainDocumentURL(&frameURL);
129     if (FAILED(hr))
130         goto exit;
131
132     SendMessage(hURLBarWnd, (UINT)WM_SETTEXT, 0, (LPARAM)frameURL);
133
134 exit:
135     if (mainFrame)
136         mainFrame->Release();
137     if (dataSource)
138         dataSource->Release();
139     if (request)
140         request->Release();
141     SysFreeString(frameURL);
142     return 0;
143 }
144
145 HRESULT STDMETHODCALLTYPE WinLauncherWebHost::didFailProvisionalLoadWithError(IWebView*, IWebError *error, IWebFrame*)
146 {
147     BSTR errorDescription = 0;
148     HRESULT hr = error->localizedDescription(&errorDescription);
149     if (FAILED(hr))
150         errorDescription = L"Failed to load page and to localize error description.";
151
152     ::MessageBoxW(0, static_cast<LPCWSTR>(errorDescription), L"Error", MB_APPLMODAL | MB_OK);
153     if (SUCCEEDED(hr))
154         SysFreeString(errorDescription);
155
156     return S_OK;
157 }
158
159 HRESULT STDMETHODCALLTYPE WinLauncherWebHost::QueryInterface(REFIID riid, void** ppvObject)
160 {
161     *ppvObject = 0;
162     if (IsEqualGUID(riid, IID_IUnknown))
163         *ppvObject = static_cast<IWebFrameLoadDelegate*>(this);
164     else if (IsEqualGUID(riid, IID_IWebFrameLoadDelegate))
165         *ppvObject = static_cast<IWebFrameLoadDelegate*>(this);
166     else
167         return E_NOINTERFACE;
168
169     AddRef();
170     return S_OK;
171 }
172
173 ULONG STDMETHODCALLTYPE WinLauncherWebHost::AddRef(void)
174 {
175     return ++m_refCount;
176 }
177
178 ULONG STDMETHODCALLTYPE WinLauncherWebHost::Release(void)
179 {
180     ULONG newRef = --m_refCount;
181     if (!newRef)
182         delete(this);
183
184     return newRef;
185 }
186
187 HRESULT WinLauncherWebHost::didFinishLoadForFrame(IWebView* webView, IWebFrame* frame)
188 {
189     IDOMDocument* doc = 0;
190     frame->DOMDocument(&doc);
191
192     IDOMElement* element = 0;
193     IDOMEventTarget* target = 0;
194     HRESULT hr = doc->getElementById(L"webkit logo", &element);
195     if (!SUCCEEDED(hr))
196         goto exit;
197
198     hr = element->QueryInterface(IID_IDOMEventTarget, reinterpret_cast<void**>(&target));
199     if (!SUCCEEDED(hr))
200         goto exit;
201
202     hr = target->addEventListener(L"click", new SimpleEventListener (L"webkit logo click"), FALSE);
203     if (!SUCCEEDED(hr))
204         goto exit;
205
206 exit:
207     if (target)
208         target->Release();
209     if (element)
210         element->Release();
211     if (doc)
212         doc->Release();
213
214     return hr;
215 }
216
217 static void resizeSubViews()
218 {
219     if (usesLayeredWebView() || !gViewWindow)
220         return;
221
222     RECT rcClient;
223     GetClientRect(hMainWnd, &rcClient);
224     MoveWindow(hURLBarWnd, 0, 0, rcClient.right, URLBAR_HEIGHT, TRUE);
225     MoveWindow(gViewWindow, 0, URLBAR_HEIGHT, rcClient.right, rcClient.bottom - URLBAR_HEIGHT, TRUE);
226 }
227
228 static void subclassForLayeredWindow()
229 {
230     hMainWnd = gViewWindow;
231     DefWebKitProc = reinterpret_cast<WNDPROC>(::GetWindowLongPtr(hMainWnd, GWL_WNDPROC));
232     ::SetWindowLongPtr(hMainWnd, GWL_WNDPROC, reinterpret_cast<LONG_PTR>(WndProc));
233 }
234
235 static void computeFullDesktopFrame()
236 {
237     RECT desktop;
238     if (!::SystemParametersInfo(SPI_GETWORKAREA, 0, static_cast<void*>(&desktop), 0))
239         return;
240
241     s_windowPosition.x = 0;
242     s_windowPosition.y = 0;
243     s_windowSize.cx = desktop.right - desktop.left;
244     s_windowSize.cy = desktop.bottom - desktop.top;
245 }
246
247 BOOL WINAPI DllMain(HINSTANCE dllInstance, DWORD reason, LPVOID)
248 {
249     if (reason == DLL_PROCESS_ATTACH)
250         hInst = dllInstance;
251
252     return TRUE;
253 }
254
255 extern "C" __declspec(dllexport) int WINAPI dllLauncherEntryPoint(HINSTANCE, HINSTANCE, LPTSTR, int nCmdShow)
256 {
257 #ifdef _CRTDBG_MAP_ALLOC
258     _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
259     _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
260 #endif
261
262      // TODO: Place code here.
263     MSG msg = {0};
264     HACCEL hAccelTable;
265
266     INITCOMMONCONTROLSEX InitCtrlEx;
267
268     InitCtrlEx.dwSize = sizeof(INITCOMMONCONTROLSEX);
269     InitCtrlEx.dwICC  = 0x00004000; //ICC_STANDARD_CLASSES;
270     InitCommonControlsEx(&InitCtrlEx);
271
272     int argc = 0;
273     WCHAR** argv = CommandLineToArgvW(GetCommandLineW(), &argc);
274     for (int i = 1; i < argc; ++i) {
275         if (!wcsicmp(argv[i], L"--transparent"))
276             s_usesLayeredWebView = true;
277         else if (!wcsicmp(argv[i], L"--desktop"))
278             s_fullDesktop = true;
279     }
280
281     // Initialize global strings
282     LoadString(hInst, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
283     LoadString(hInst, IDC_WINLAUNCHER, szWindowClass, MAX_LOADSTRING);
284     MyRegisterClass(hInst);
285
286     if (shouldUseFullDesktop())
287         computeFullDesktopFrame();
288
289     // Init COM
290     OleInitialize(NULL);
291
292     if (usesLayeredWebView()) {
293         hURLBarWnd = CreateWindow(L"EDIT", L"Type URL Here",
294                     WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_BORDER | ES_LEFT | ES_AUTOVSCROLL, 
295                     s_windowPosition.x, s_windowPosition.y + s_windowSize.cy, s_windowSize.cx, URLBAR_HEIGHT,
296                     0,
297                     0,
298                     hInst, 0);
299     } else {
300         hMainWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
301                        CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, 0, 0, hInst, 0);
302
303         if (!hMainWnd)
304             return FALSE;
305
306         hURLBarWnd = CreateWindow(L"EDIT", 0,
307                     WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT | ES_AUTOVSCROLL, 
308                     0, 0, 0, 0,
309                     hMainWnd,
310                     0,
311                     hInst, 0);
312
313         ShowWindow(hMainWnd, nCmdShow);
314         UpdateWindow(hMainWnd);
315     }
316
317     DefEditProc = reinterpret_cast<WNDPROC>(GetWindowLongPtr(hURLBarWnd, GWL_WNDPROC));
318     SetWindowLongPtr(hURLBarWnd, GWL_WNDPROC, reinterpret_cast<LONG_PTR>(MyEditProc));
319     SetFocus(hURLBarWnd);
320
321     RECT clientRect = { s_windowPosition.x, s_windowPosition.y, s_windowPosition.x + s_windowSize.cx, s_windowPosition.y + s_windowSize.cy };
322
323     IWebPreferences* tmpPreferences = 0;
324     IWebPreferences* standardPreferences = 0;
325     if (FAILED(WebKitCreateInstance(CLSID_WebPreferences, 0, IID_IWebPreferences, reinterpret_cast<void**>(&tmpPreferences))))
326         goto exit;
327
328     if (FAILED(tmpPreferences->standardPreferences(&standardPreferences)))
329         goto exit;
330
331     standardPreferences->setAcceleratedCompositingEnabled(TRUE);
332
333     HRESULT hr = WebKitCreateInstance(CLSID_WebView, 0, IID_IWebView, reinterpret_cast<void**>(&gWebView));
334     if (FAILED(hr))
335         goto exit;
336
337     hr = gWebView->QueryInterface(IID_IWebViewPrivate, reinterpret_cast<void**>(&gWebViewPrivate));
338     if (FAILED(hr))
339         goto exit;
340
341     gWebHost = new WinLauncherWebHost();
342     gWebHost->AddRef();
343     hr = gWebView->setFrameLoadDelegate(gWebHost);
344     if (FAILED(hr))
345         goto exit;
346
347     gPrintDelegate = new PrintWebUIDelegate;
348     gPrintDelegate->AddRef();
349     hr = gWebView->setUIDelegate(gPrintDelegate);
350     if (FAILED (hr))
351         goto exit;
352
353     hr = gWebView->setHostWindow(reinterpret_cast<OLE_HANDLE>(hMainWnd));
354     if (FAILED(hr))
355         goto exit;
356
357     hr = gWebView->initWithFrame(clientRect, 0, 0);
358     if (FAILED(hr))
359         goto exit;
360
361     IWebFrame* frame;
362     hr = gWebView->mainFrame(&frame);
363     if (FAILED(hr))
364         goto exit;
365
366     static BSTR defaultHTML = SysAllocString(TEXT("<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>"));
367     frame->loadHTMLString(defaultHTML, 0);
368     frame->Release();
369
370     hr = gWebViewPrivate->setTransparent(usesLayeredWebView());
371     if (FAILED(hr))
372         goto exit;
373
374     hr = gWebViewPrivate->setUsesLayeredWindow(usesLayeredWebView());
375     if (FAILED(hr))
376         goto exit;
377
378     hr = gWebViewPrivate->viewWindow(reinterpret_cast<OLE_HANDLE*>(&gViewWindow));
379     if (FAILED(hr) || !gViewWindow)
380         goto exit;
381
382     if (usesLayeredWebView())
383         subclassForLayeredWindow();
384
385     resizeSubViews();
386
387     ShowWindow(gViewWindow, nCmdShow);
388     UpdateWindow(gViewWindow);
389
390     hAccelTable = LoadAccelerators(hInst, MAKEINTRESOURCE(IDC_WINLAUNCHER));
391
392     // Main message loop:
393     while (GetMessage(&msg, NULL, 0, 0)) {
394         if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) {
395             TranslateMessage(&msg);
396             DispatchMessage(&msg);
397         }
398     }
399
400 exit:
401     gPrintDelegate->Release();
402     if (gWebViewPrivate)
403         gWebViewPrivate->Release();
404     gWebView->Release();
405     if (standardPreferences)
406         standardPreferences->Release();
407     tmpPreferences->Release();
408
409     shutDownWebKit();
410 #ifdef _CRTDBG_MAP_ALLOC
411     _CrtDumpMemoryLeaks();
412 #endif
413
414     // Shut down COM.
415     OleUninitialize();
416     
417     return static_cast<int>(msg.wParam);
418 }
419
420 ATOM MyRegisterClass(HINSTANCE hInstance)
421 {
422     WNDCLASSEX wcex;
423
424     wcex.cbSize = sizeof(WNDCLASSEX);
425
426     wcex.style          = CS_HREDRAW | CS_VREDRAW;
427     wcex.lpfnWndProc    = WndProc;
428     wcex.cbClsExtra     = 0;
429     wcex.cbWndExtra     = 0;
430     wcex.hInstance      = hInstance;
431     wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WINLAUNCHER));
432     wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
433     wcex.hbrBackground  = 0;
434     wcex.lpszMenuName   = MAKEINTRESOURCE(IDC_WINLAUNCHER);
435     wcex.lpszClassName  = szWindowClass;
436     wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
437
438     return RegisterClassEx(&wcex);
439 }
440
441 static BOOL CALLBACK AbortProc(HDC hDC, int Error)
442 {
443     MSG msg;
444     while (::PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
445         ::TranslateMessage(&msg);
446         ::DispatchMessage(&msg);
447     }
448
449     return TRUE;
450 }
451
452 static HDC getPrinterDC()
453 {
454     PRINTDLG pdlg;
455     memset(&pdlg, 0, sizeof(PRINTDLG));
456     pdlg.lStructSize = sizeof(PRINTDLG);
457     pdlg.Flags = PD_PRINTSETUP | PD_RETURNDC;
458
459     ::PrintDlg(&pdlg);
460
461     return pdlg.hDC;
462 }
463
464 static void initDocStruct(DOCINFO* di, TCHAR* docname)
465 {
466     memset(di, 0, sizeof(DOCINFO));
467     di->cbSize = sizeof(DOCINFO);
468     di->lpszDocName = docname;
469 }
470
471 void PrintView(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
472 {
473     HDC printDC = getPrinterDC();
474     if (!printDC) {
475         ::MessageBoxW(0, L"Error creating printing DC", L"Error", MB_APPLMODAL | MB_OK);
476         return;
477     }
478
479     if (::SetAbortProc(printDC, AbortProc) == SP_ERROR) {
480         ::MessageBoxW(0, L"Error setting up AbortProc", L"Error", MB_APPLMODAL | MB_OK);
481         return;
482     }
483
484     IWebFrame* frame = 0;
485     IWebFramePrivate* framePrivate = 0;
486     if (FAILED(gWebView->mainFrame(&frame)))
487         goto exit;
488
489     if (FAILED(frame->QueryInterface(&framePrivate)))
490         goto exit;
491
492     framePrivate->setInPrintingMode(TRUE, printDC);
493
494     UINT pageCount = 0;
495     framePrivate->getPrintedPageCount(printDC, &pageCount);
496
497     DOCINFO di;
498     initDocStruct(&di, L"WebKit Doc");
499     ::StartDoc(printDC, &di);
500
501     // FIXME: Need CoreGraphics implementation
502     void* graphicsContext = 0;
503     for (size_t page = 1; page <= pageCount; ++page) {
504         ::StartPage(printDC);
505         framePrivate->spoolPages(printDC, page, page, graphicsContext);
506         ::EndPage(printDC);
507     }
508
509     framePrivate->setInPrintingMode(FALSE, printDC);
510
511     ::EndDoc(printDC);
512     ::DeleteDC(printDC);
513
514 exit:
515     if (frame)
516         frame->Release();
517     if (framePrivate)
518         framePrivate->Release();
519 }
520
521 static const int dragBarHeight = 30;
522
523 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
524 {
525     WNDPROC parentProc = usesLayeredWebView() ? DefWebKitProc : DefWindowProc;
526
527     switch (message) {
528     case WM_NCHITTEST:
529         if (usesLayeredWebView()) {
530             RECT window;
531             ::GetWindowRect(hWnd, &window);
532             // For testing our transparent window, we need a region to use as a handle for
533             // dragging. The right way to do this would be to query the web view to see what's
534             // under the mouse. However, for testing purposes we just use an arbitrary
535             // 30 pixel band at the top of the view as an arbitrary gripping location.
536             //
537             // When we are within this bad, return HT_CAPTION to tell Windows we want to
538             // treat this region as if it were the title bar on a normal window.
539             int y = HIWORD(lParam);
540
541             if ((y > window.top) && (y < window.top + dragBarHeight))
542                 return HTCAPTION;
543         }
544         return CallWindowProc(parentProc, hWnd, message, wParam, lParam);
545     case WM_COMMAND: {
546         int wmId = LOWORD(wParam);
547         int wmEvent = HIWORD(wParam);
548         // Parse the menu selections:
549         switch (wmId) {
550         case IDM_ABOUT:
551             DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
552             break;
553         case IDM_EXIT:
554             DestroyWindow(hWnd);
555             break;
556         case IDM_PRINT:
557             PrintView(hWnd, message, wParam, lParam);
558             break;
559         default:
560             return CallWindowProc(parentProc, hWnd, message, wParam, lParam);
561         }
562         }
563         break;
564     case WM_DESTROY:
565         PostQuitMessage(0);
566         break;
567     case WM_SIZE:
568         if (!gWebView || usesLayeredWebView())
569            return CallWindowProc(parentProc, hWnd, message, wParam, lParam);
570
571         resizeSubViews();
572         break;
573     default:
574         return CallWindowProc(parentProc, hWnd, message, wParam, lParam);
575     }
576
577     return 0;
578 }
579
580 #define MAX_URL_LENGTH  1024
581
582 LRESULT CALLBACK MyEditProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
583 {
584     switch (message) {
585         case WM_CHAR:
586             if (wParam == 13) { // Enter Key
587                 wchar_t strPtr[MAX_URL_LENGTH];
588                 *((LPWORD)strPtr) = MAX_URL_LENGTH; 
589                 int strLen = SendMessage(hDlg, EM_GETLINE, 0, (LPARAM)strPtr);
590
591                 BSTR bstr = SysAllocStringLen(strPtr, strLen);
592                 loadURL(bstr);
593                 SysFreeString(bstr);
594
595                 return 0;
596             } else
597                 return (LRESULT)CallWindowProc((WNDPROC)DefEditProc,hDlg,message,wParam,lParam);
598             break;
599         default:
600              return (LRESULT)CallWindowProc((WNDPROC)DefEditProc,hDlg,message,wParam,lParam);
601         break;
602     }
603 }
604
605
606 // Message handler for about box.
607 INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
608 {
609     UNREFERENCED_PARAMETER(lParam);
610     switch (message) {
611     case WM_INITDIALOG:
612         return (INT_PTR)TRUE;
613
614     case WM_COMMAND:
615         if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) {
616             EndDialog(hDlg, LOWORD(wParam));
617             return (INT_PTR)TRUE;
618         }
619         break;
620     }
621     return (INT_PTR)FALSE;
622 }
623
624 static void loadURL(BSTR urlBStr)
625 {
626     IWebFrame* frame = 0;
627     IWebMutableURLRequest* request = 0;
628
629     static BSTR methodBStr = SysAllocString(TEXT("GET"));
630
631     if (urlBStr && urlBStr[0] && (PathFileExists(urlBStr) || PathIsUNC(urlBStr))) {
632         TCHAR fileURL[INTERNET_MAX_URL_LENGTH];
633         DWORD fileURLLength = sizeof(fileURL)/sizeof(fileURL[0]);
634
635         if (SUCCEEDED(UrlCreateFromPath(urlBStr, fileURL, &fileURLLength, 0)))
636             SysReAllocString(&urlBStr, fileURL);
637     }
638
639     HRESULT hr = gWebView->mainFrame(&frame);
640     if (FAILED(hr))
641         goto exit;
642
643     hr = WebKitCreateInstance(CLSID_WebMutableURLRequest, 0, IID_IWebMutableURLRequest, (void**)&request);
644     if (FAILED(hr))
645         goto exit;
646
647     hr = request->initWithURL(urlBStr, WebURLRequestUseProtocolCachePolicy, 60);
648     if (FAILED(hr))
649         goto exit;
650
651     hr = request->setHTTPMethod(methodBStr);
652     if (FAILED(hr))
653         goto exit;
654
655     hr = frame->loadRequest(request);
656     if (FAILED(hr))
657         goto exit;
658
659     SetFocus(gViewWindow);
660
661 exit:
662     if (frame)
663         frame->Release();
664     if (request)
665         request->Release();
666 }