2008-12-12 Brent Fulgham <bfulgham@gmail.com>
[WebKit-https.git] / WebKitTools / WinLauncher / WinLauncher.cpp
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.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
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
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
112 ULONG STDMETHODCALLTYPE WinLauncherWebHost::AddRef(void)
113 {
114     return ++m_refCount;
115 }
116
117 ULONG STDMETHODCALLTYPE WinLauncherWebHost::Release(void)
118 {
119     ULONG newRef = --m_refCount;
120     if (!newRef)
121         delete(this);
122
123     return newRef;
124 }
125
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
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 = CoCreateInstance(CLSID_WebView, 0, CLSCTX_ALL, 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     static BSTR defaultHTML = 0;
205     if (!defaultHTML)
206         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>"));
207     frame->loadHTMLString(defaultHTML, 0);
208     frame->Release();
209
210     IWebViewPrivate* viewExt;
211     hr = gWebView->QueryInterface(IID_IWebViewPrivate, (void**)&viewExt);
212     if (FAILED(hr))
213         goto exit;
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 (int) msg.wParam;
245 }
246
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
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
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
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.
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
366 static void loadURL(BSTR urlBStr)
367 {
368     IWebFrame* frame = 0;
369     IWebMutableURLRequest* request = 0;
370     static BSTR methodBStr = 0;
371
372     if (!methodBStr)
373         methodBStr = SysAllocString(TEXT("GET"));
374
375     if (urlBStr && urlBStr[0] && (PathFileExists(urlBStr) || PathIsUNC(urlBStr))) {
376         TCHAR fileURL[INTERNET_MAX_URL_LENGTH];
377         DWORD fileURLLength = sizeof(fileURL)/sizeof(fileURL[0]);
378         if (SUCCEEDED(UrlCreateFromPath(urlBStr, fileURL, &fileURLLength, 0)))
379             urlBStr = fileURL;
380     }
381
382     HRESULT hr = gWebView->mainFrame(&frame);
383     if (FAILED(hr))
384         goto exit;
385
386     hr = CoCreateInstance(CLSID_WebMutableURLRequest, 0, CLSCTX_ALL, IID_IWebMutableURLRequest, (void**)&request);
387     if (FAILED(hr))
388         goto exit;
389
390     hr = request->initWithURL(urlBStr, WebURLRequestUseProtocolCachePolicy, 60);
391     if (FAILED(hr))
392         goto exit;
393
394     hr = request->setHTTPMethod(methodBStr);
395     if (FAILED(hr))
396         goto exit;
397
398     hr = frame->loadRequest(request);
399     if (FAILED(hr))
400         goto exit;
401
402     SetFocus(gViewWindow);
403
404 exit:
405     if (frame)
406         frame->Release();
407     if (request)
408         request->Release();
409 }