4d60115a25344bf5c1e934170c15d2d73cf53dcd
[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     delete gWebView;
236 #ifdef _CRTDBG_MAP_ALLOC
237     _CrtDumpMemoryLeaks();
238 #endif
239
240     // Shut down COM.
241     OleUninitialize();
242     
243     return (int) msg.wParam;
244 }
245
246 ATOM MyRegisterClass(HINSTANCE hInstance)
247 {
248     WNDCLASSEX wcex;
249
250     wcex.cbSize = sizeof(WNDCLASSEX);
251
252     wcex.style          = CS_HREDRAW | CS_VREDRAW;
253     wcex.lpfnWndProc    = WndProc;
254     wcex.cbClsExtra     = 0;
255     wcex.cbWndExtra     = 0;
256     wcex.hInstance      = hInstance;
257     wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WINLAUNCHER));
258     wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
259     wcex.hbrBackground  = 0;
260     wcex.lpszMenuName   = MAKEINTRESOURCE(IDC_WINLAUNCHER);
261     wcex.lpszClassName  = szWindowClass;
262     wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
263
264     return RegisterClassEx(&wcex);
265 }
266
267 BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
268 {
269    hInst = hInstance; // Store instance handle in our global variable
270
271    hMainWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
272       CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
273
274    if (!hMainWnd)
275       return FALSE;
276
277    ShowWindow(hMainWnd, nCmdShow);
278    UpdateWindow(hMainWnd);
279
280    return TRUE;
281 }
282
283 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
284 {
285     int wmId, wmEvent;
286     PAINTSTRUCT ps;
287     HDC hdc;
288
289     switch (message) {
290     case WM_COMMAND:
291         wmId    = LOWORD(wParam);
292         wmEvent = HIWORD(wParam);
293         // Parse the menu selections:
294         switch (wmId) {
295             case IDM_ABOUT:
296                 DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
297                 break;
298             case IDM_EXIT:
299                 DestroyWindow(hWnd);
300                 break;
301             default:
302                 return DefWindowProc(hWnd, message, wParam, lParam);
303         }
304         break;
305     case WM_DESTROY:
306         PostQuitMessage(0);
307         break;
308     case WM_SIZE:
309         if (!gWebView)
310             break;
311         resizeSubViews();
312         break; 
313     default:
314         return DefWindowProc(hWnd, message, wParam, lParam);
315     }
316     return 0;
317 }
318
319
320 #define MAX_URL_LENGTH  1024
321
322 LRESULT CALLBACK MyEditProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
323 {
324     switch (message) {
325         case WM_CHAR:
326             if( wParam == 13 ) { // Enter Key
327                 wchar_t strPtr[MAX_URL_LENGTH];
328                 *((LPWORD)strPtr) = MAX_URL_LENGTH; 
329                 int strLen = SendMessage(hDlg, EM_GETLINE, 0, (LPARAM)strPtr);
330
331                 BSTR bstr = SysAllocStringLen(strPtr, strLen);
332                 loadURL(bstr);
333                 SysFreeString(bstr);
334
335                 return 0;
336             } else
337                 return (LRESULT)CallWindowProc((WNDPROC)DefEditProc,hDlg,message,wParam,lParam);
338             break;
339         default:
340              return (LRESULT)CallWindowProc((WNDPROC)DefEditProc,hDlg,message,wParam,lParam);
341         break;
342     }
343     return 0;
344 }
345
346
347 // Message handler for about box.
348 INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
349 {
350     UNREFERENCED_PARAMETER(lParam);
351     switch (message) {
352     case WM_INITDIALOG:
353         return (INT_PTR)TRUE;
354
355     case WM_COMMAND:
356         if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) {
357             EndDialog(hDlg, LOWORD(wParam));
358             return (INT_PTR)TRUE;
359         }
360         break;
361     }
362     return (INT_PTR)FALSE;
363 }
364
365 static void loadURL(BSTR urlBStr)
366 {
367     IWebFrame* frame = 0;
368     IWebMutableURLRequest* request = 0;
369     static BSTR methodBStr = 0;
370
371     if (!methodBStr)
372         methodBStr = SysAllocString(TEXT("GET"));
373
374     if (urlBStr && urlBStr[0] && (PathFileExists(urlBStr) || PathIsUNC(urlBStr))) {
375         TCHAR fileURL[INTERNET_MAX_URL_LENGTH];
376         DWORD fileURLLength = sizeof(fileURL)/sizeof(fileURL[0]);
377         if (SUCCEEDED(UrlCreateFromPath(urlBStr, fileURL, &fileURLLength, 0)))
378             urlBStr = fileURL;
379     }
380
381     HRESULT hr = gWebView->mainFrame(&frame);
382     if (FAILED(hr))
383         goto exit;
384
385     hr = CoCreateInstance(CLSID_WebMutableURLRequest, 0, CLSCTX_ALL, IID_IWebMutableURLRequest, (void**)&request);
386     if (FAILED(hr))
387         goto exit;
388
389     hr = request->initWithURL(urlBStr, WebURLRequestUseProtocolCachePolicy, 0);
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 }