Make sure Spinneret inits and shuts down COM like a good boy.
[WebKit-https.git] / WebKitTools / Spinneret / Spinneret / Spinneret.cpp
1 /*
2  * Copyright (C) 2006 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 "Spinneret.h"
28 #include "WebView.h"
29 #include "WebFrame.h"
30
31 #include <commctrl.h>
32 #include <objbase.h>
33
34 #define MAX_LOADSTRING 100
35 #define URLBAR_HEIGHT  24
36
37 using namespace WebKit;
38
39 // Global Variables:
40 HINSTANCE hInst;                                // current instance
41 HWND hMainWnd;
42 HWND hURLBarWnd;
43 long DefEditProc;
44 WebView* gWebView = 0;
45 WebHost* 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 void SpinneretWebHost::updateLocationBar(const char* URL)
57 {
58     SendMessageA(hURLBarWnd, (UINT)WM_SETTEXT, 0, (LPARAM)URL);
59 }
60
61 void SpinneretWebHost::loadEnd(BOOL successful, DWORD error, LPCTSTR errorString)
62 {
63 }
64
65 static void resizeSubViews()
66 {
67     RECT rcClient;
68     GetClientRect(hMainWnd, &rcClient);
69     MoveWindow(hURLBarWnd, 0, 0, rcClient.right, URLBAR_HEIGHT, TRUE);
70     MoveWindow(gWebView->windowHandle(), 0, URLBAR_HEIGHT, rcClient.right, rcClient.bottom - URLBAR_HEIGHT, TRUE);
71 }
72
73 int APIENTRY _tWinMain(HINSTANCE hInstance,
74                      HINSTANCE hPrevInstance,
75                      LPTSTR    lpCmdLine,
76                      int       nCmdShow)
77 {
78 #ifdef _CRTDBG_MAP_ALLOC
79     _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
80     _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
81 #endif
82
83     UNREFERENCED_PARAMETER(hPrevInstance);
84     UNREFERENCED_PARAMETER(lpCmdLine);
85
86      // TODO: Place code here.
87     MSG msg;
88     HACCEL hAccelTable;
89
90     INITCOMMONCONTROLSEX InitCtrlEx;
91
92     InitCtrlEx.dwSize = sizeof(INITCOMMONCONTROLSEX);
93     InitCtrlEx.dwICC  = ICC_STANDARD_CLASSES;
94     InitCommonControlsEx(&InitCtrlEx);
95
96     // Initialize global strings
97     LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
98     LoadString(hInstance, IDC_SPINNERET, szWindowClass, MAX_LOADSTRING);
99     MyRegisterClass(hInstance);
100
101     // Perform application initialization:
102     if (!InitInstance (hInstance, nCmdShow))
103         return FALSE;
104
105     // Init COM
106     CoInitialize(NULL);
107
108     hURLBarWnd = CreateWindow(L"EDIT", 0,
109                         WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT | ES_AUTOVSCROLL, 
110                         0, 0, 0, 0,
111                         hMainWnd,
112                         0,
113                         hInstance, 0);
114
115     DefEditProc = GetWindowLong(hURLBarWnd, GWL_WNDPROC);
116     SetWindowLong(hURLBarWnd, GWL_WNDPROC,(long)MyEditProc);
117     SetFocus(hURLBarWnd);
118
119     gWebHost = new SpinneretWebHost();
120     gWebView = WebView::createWebView(hInstance, hMainWnd, gWebHost);
121     gWebView->mainFrame()->loadHTMLString("<p style=\"background-color: #00FF00\">Testing</p><img src=\"http://webkit.opendarwin.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>");
122
123     resizeSubViews();
124     ShowWindow(gWebView->windowHandle(), nCmdShow);
125     UpdateWindow(gWebView->windowHandle());
126
127     hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_SPINNERET));
128
129     // Main message loop:
130     while (GetMessage(&msg, NULL, 0, 0))
131     {
132         if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
133         {
134             TranslateMessage(&msg);
135             DispatchMessage(&msg);
136         }
137     }
138
139     delete gWebView;
140 #ifdef _CRTDBG_MAP_ALLOC
141     _CrtDumpMemoryLeaks();
142 #endif
143
144     // Shut down COM.
145     CoUninitialize();
146     
147     return (int) msg.wParam;
148 }
149
150 ATOM MyRegisterClass(HINSTANCE hInstance)
151 {
152     WNDCLASSEX wcex;
153
154     wcex.cbSize = sizeof(WNDCLASSEX);
155
156     wcex.style            = CS_HREDRAW | CS_VREDRAW;
157     wcex.lpfnWndProc    = WndProc;
158     wcex.cbClsExtra        = 0;
159     wcex.cbWndExtra        = 0;
160     wcex.hInstance        = hInstance;
161     wcex.hIcon            = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SPINNERET));
162     wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
163     wcex.hbrBackground    = 0;
164     wcex.lpszMenuName    = MAKEINTRESOURCE(IDC_SPINNERET);
165     wcex.lpszClassName    = szWindowClass;
166     wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
167
168     return RegisterClassEx(&wcex);
169 }
170
171 BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
172 {
173    hInst = hInstance; // Store instance handle in our global variable
174
175    hMainWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
176       CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
177
178    if (!hMainWnd)
179       return FALSE;
180
181    ShowWindow(hMainWnd, nCmdShow);
182    UpdateWindow(hMainWnd);
183
184    return TRUE;
185 }
186
187 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
188 {
189     int wmId, wmEvent;
190     PAINTSTRUCT ps;
191     HDC hdc;
192
193     switch (message)
194     {
195     case WM_COMMAND:
196         wmId    = LOWORD(wParam);
197         wmEvent = HIWORD(wParam);
198         // Parse the menu selections:
199         switch (wmId)
200         {
201         case IDM_ABOUT:
202             DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
203             break;
204         case IDM_EXIT:
205             DestroyWindow(hWnd);
206             break;
207         default:
208             return DefWindowProc(hWnd, message, wParam, lParam);
209         }
210         break;
211     case WM_DESTROY:
212         PostQuitMessage(0);
213         break;
214     case WM_SIZE:
215         if (!gWebView)
216             break;
217         resizeSubViews();
218         break; 
219     default:
220         return DefWindowProc(hWnd, message, wParam, lParam);
221     }
222     return 0;
223 }
224
225
226 #define MAX_URL_LENGTH  1024
227
228 LRESULT CALLBACK MyEditProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
229 {
230     switch (message) {
231         case WM_CHAR:
232             if( wParam == 13 ) { // Enter Key
233                 wchar_t strPtr[MAX_URL_LENGTH];
234                 char    cstrPtr[MAX_URL_LENGTH];
235                 *((LPWORD)strPtr) = MAX_URL_LENGTH; 
236                 int strLen = SendMessage(hDlg, EM_GETLINE, 0, (LPARAM)strPtr);
237
238                 int x;
239                 for(x = 0; x < strLen; x++)
240                     cstrPtr[x] = strPtr[x];
241                 cstrPtr[x] = 0;
242
243                 gWebView->mainFrame()->loadURL(cstrPtr);
244                 SetFocus(gWebView->windowHandle());
245
246                 return 0;
247             } else
248                 return (LRESULT)CallWindowProc((WNDPROC)DefEditProc,hDlg,message,wParam,lParam);
249             break;
250         default:
251              return (LRESULT)CallWindowProc((WNDPROC)DefEditProc,hDlg,message,wParam,lParam);
252         break;
253     }
254     return 0;
255 }
256
257
258 // Message handler for about box.
259 INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
260 {
261     UNREFERENCED_PARAMETER(lParam);
262     switch (message)
263     {
264     case WM_INITDIALOG:
265         return (INT_PTR)TRUE;
266
267     case WM_COMMAND:
268         if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
269         {
270             EndDialog(hDlg, LOWORD(wParam));
271             return (INT_PTR)TRUE;
272         }
273         break;
274     }
275     return (INT_PTR)FALSE;
276 }