Add beginnings of the Help viewer.
[wine] / dlls / hhctrl.ocx / help.c
1 /*
2  * Help Viewer Implementation
3  *
4  * Copyright 2005 James Hawkins
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include <stdarg.h>
22
23 #include "windef.h"
24 #include "winbase.h"
25 #include "wingdi.h"
26 #include "winuser.h"
27 #include "winnls.h"
28 #include "commctrl.h"
29 #include "htmlhelp.h"
30 #include "ole2.h"
31
32 /* Window type defaults */
33
34 #define WINTYPE_DEFAULT_X       280
35 #define WINTYPE_DEFAULT_Y       100
36 #define WINTYPE_DEFAULT_WIDTH   740
37 #define WINTYPE_DEFAULT_HEIGHT  640
38
39 typedef struct tagHHInfo
40 {
41     HH_WINTYPEW *pHHWinType;
42     HINSTANCE hInstance;
43     LPCWSTR szCmdLine;
44     HFONT hFont;
45 } HHInfo;
46
47 static LPWSTR HH_ANSIToUnicode(LPCSTR ansi)
48 {
49     LPWSTR unicode;
50     int count;
51
52     count = MultiByteToWideChar(CP_ACP, 0, ansi, -1, NULL, 0);
53     unicode = HeapAlloc(GetProcessHeap(), 0, count * sizeof(WCHAR));
54     MultiByteToWideChar(CP_ACP, 0, ansi, -1, unicode, count);
55
56     return unicode;
57 }
58
59 /* Toolbar */
60
61 static BOOL HH_AddToolbar(HHInfo *pHHInfo)
62 {
63     return TRUE;
64 }
65
66 /* Navigation Pane */
67
68 static BOOL HH_AddNavigationPane(HHInfo *pHHInfo)
69 {
70     return TRUE;
71 }
72
73 /* HTML Pane */
74
75 static BOOL HH_AddHTMLPane(HHInfo *pHHInfo)
76 {
77     return TRUE;
78 }
79
80 /* Viewer Window */
81
82 LRESULT CALLBACK Help_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
83 {
84     PAINTSTRUCT ps;
85     HDC hdc;
86
87     switch (message)
88     {
89
90         case WM_PAINT:
91             hdc = BeginPaint(hWnd, &ps);
92             EndPaint(hWnd, &ps);
93             break;
94         case WM_DESTROY:
95             PostQuitMessage(0);
96             break;
97
98         default:
99             return DefWindowProcW(hWnd, message, wParam, lParam);
100     }
101
102     return 0;
103 }
104
105 static BOOL HH_CreateHelpWindow(HHInfo *pHHInfo)
106 {
107     HWND hWnd;
108     HINSTANCE hInstance = pHHInfo->hInstance;
109     WNDCLASSEXW wcex;
110     DWORD dwStyles, dwExStyles;
111     DWORD x, y, width, height;
112
113     static const WCHAR windowClassW[] = {
114         'H','H',' ', 'P','a','r','e','n','t',0
115     };
116
117     static const WCHAR windowTitleW[] = {
118         'H','T','M','L',' ','H','e','l','p',0
119     };
120
121     wcex.cbSize         = sizeof(WNDCLASSEXW);
122     wcex.style          = CS_HREDRAW | CS_VREDRAW;
123     wcex.lpfnWndProc    = (WNDPROC)Help_WndProc;
124     wcex.cbClsExtra     = 0;
125     wcex.cbWndExtra     = 0;
126     wcex.hInstance      = hInstance;
127     wcex.hIcon          = LoadIconW(NULL, (LPCWSTR)IDI_APPLICATION);
128     wcex.hCursor        = LoadCursorW(NULL, (LPCWSTR)IDC_ARROW);
129     wcex.hbrBackground  = (HBRUSH)(COLOR_BACKGROUND + 1);
130     wcex.lpszMenuName   = NULL;
131     wcex.lpszClassName  = windowClassW;
132     wcex.hIconSm        = LoadIconW(NULL, (LPCWSTR)IDI_APPLICATION);
133
134     RegisterClassExW(&wcex);
135
136     dwStyles = WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
137     dwExStyles = WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR |
138                  WS_EX_WINDOWEDGE | WS_EX_APPWINDOW;
139
140     /* these will be loaded from the CHM file in the future if they're provided */
141     x = WINTYPE_DEFAULT_X;
142     y = WINTYPE_DEFAULT_Y;
143     width = WINTYPE_DEFAULT_WIDTH;
144     height = WINTYPE_DEFAULT_HEIGHT;
145
146     hWnd = CreateWindowExW(dwExStyles, windowClassW, windowTitleW, dwStyles,
147                            x, y, width, height, NULL, NULL, hInstance, NULL);
148     if (!hWnd)
149         return FALSE;
150
151     ShowWindow(hWnd, SW_SHOW);
152     UpdateWindow(hWnd);
153
154     /* store the pointer to the HH info struct */
155     SetWindowLongPtrW(hWnd, GWLP_USERDATA, (LONG_PTR)pHHInfo);
156
157     pHHInfo->pHHWinType->hwndHelp = hWnd;
158     return TRUE;
159 }
160
161 static void HH_CreateFont(HHInfo *pHHInfo)
162 {
163     LOGFONTW lf;
164
165     GetObjectW(GetStockObject(ANSI_VAR_FONT), sizeof(LOGFONTW), &lf);
166     lf.lfWeight = FW_NORMAL;
167     lf.lfItalic = FALSE;
168     lf.lfUnderline = FALSE;
169
170     pHHInfo->hFont = CreateFontIndirectW(&lf);
171 }
172
173 static void HH_InitRequiredControls(DWORD dwControls)
174 {
175     INITCOMMONCONTROLSEX icex;
176
177     icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
178     icex.dwICC = dwControls;
179     InitCommonControlsEx(&icex);
180 }
181
182 /* Creates the whole package */
183 static BOOL HH_CreateViewer(HHInfo *pHHInfo)
184 {
185     HH_CreateFont(pHHInfo);
186
187     if (!HH_CreateHelpWindow(pHHInfo))
188         return FALSE;
189
190     HH_InitRequiredControls(ICC_BAR_CLASSES);
191
192     if (!HH_AddToolbar(pHHInfo))
193         return FALSE;
194
195     if (!HH_AddNavigationPane(pHHInfo))
196         return FALSE;
197
198     if (!HH_AddHTMLPane(pHHInfo))
199         return FALSE;
200
201     return TRUE;
202 }
203
204 static HHInfo *HH_OpenHH(HINSTANCE hInstance, LPCWSTR szCmdLine)
205 {
206     HHInfo *pHHInfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(HHInfo));
207
208     pHHInfo->pHHWinType = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(HH_WINTYPEW));
209     pHHInfo->hInstance = hInstance;
210     pHHInfo->szCmdLine = szCmdLine;
211
212     return pHHInfo;
213 }
214
215 static void HH_Close(HHInfo *pHHInfo)
216 {
217     if (!pHHInfo)
218         return;
219
220     HeapFree(GetProcessHeap(), 0, pHHInfo->pHHWinType);
221 }
222
223 /* FIXME: Check szCmdLine for bad arguments */
224 int WINAPI doWinMain(HINSTANCE hInstance, LPSTR szCmdLine)
225 {
226     MSG msg;
227     HHInfo *pHHInfo;
228
229     if (OleInitialize(NULL) != S_OK)
230         return -1;
231
232     pHHInfo = HH_OpenHH(hInstance, HH_ANSIToUnicode(szCmdLine));
233     if (!pHHInfo || !HH_CreateViewer(pHHInfo))
234     {
235         OleUninitialize();
236         return -1;
237     }
238
239     while (GetMessageW(&msg, 0, 0, 0))
240     {
241         TranslateMessage(&msg);
242         DispatchMessageW(&msg);
243     }
244
245     HH_Close(pHHInfo);
246     HeapFree(GetProcessHeap(), 0, pHHInfo);
247     OleUninitialize();
248
249     return 0;
250 }