Export the temp buffer functionality in the debug functions interface
[wine/testsucceed.git] / dlls / hhctrl.ocx / help.c
blobd8217e72e0ff0d12ccfcac24888e5fe88833cabf
1 /*
2 * Help Viewer Implementation
4 * Copyright 2005 James Hawkins
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.
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.
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
21 #include <stdarg.h>
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 #include "wine/unicode.h"
33 #include "resource.h"
34 #include "chm.h"
35 #include "webbrowser.h"
37 /* Window type defaults */
39 #define WINTYPE_DEFAULT_X 280
40 #define WINTYPE_DEFAULT_Y 100
41 #define WINTYPE_DEFAULT_WIDTH 740
42 #define WINTYPE_DEFAULT_HEIGHT 640
43 #define WINTYPE_DEFAULT_NAVWIDTH 250
45 static const WCHAR szEmpty[] = {0};
47 typedef struct tagHHInfo
49 HH_WINTYPEW *pHHWinType;
50 CHMInfo *pCHMInfo;
51 WBInfo *pWBInfo;
52 HINSTANCE hInstance;
53 LPWSTR szCmdLine;
54 HWND hwndTabCtrl;
55 HWND hwndSizeBar;
56 HFONT hFont;
57 } HHInfo;
59 extern HINSTANCE hhctrl_hinstance;
61 static LPWSTR HH_ANSIToUnicode(LPCSTR ansi)
63 LPWSTR unicode;
64 int count;
66 count = MultiByteToWideChar(CP_ACP, 0, ansi, -1, NULL, 0);
67 unicode = HeapAlloc(GetProcessHeap(), 0, count * sizeof(WCHAR));
68 MultiByteToWideChar(CP_ACP, 0, ansi, -1, unicode, count);
70 return unicode;
73 /* Loads a string from the resource file */
74 static LPWSTR HH_LoadString(DWORD dwID)
76 LPWSTR string = NULL;
77 int iSize;
79 iSize = LoadStringW(hhctrl_hinstance, dwID, NULL, 0);
80 iSize += 2; /* some strings (tab text) needs double-null termination */
82 string = HeapAlloc(GetProcessHeap(), 0, iSize * sizeof(WCHAR));
83 LoadStringW(hhctrl_hinstance, dwID, string, iSize);
85 return string;
88 /* Size Bar */
90 #define SIZEBAR_WIDTH 4
92 static const WCHAR szSizeBarClass[] = {
93 'H','H',' ','S','i','z','e','B','a','r',0
96 /* Draw the SizeBar */
97 static void SB_OnPaint(HWND hWnd)
99 PAINTSTRUCT ps;
100 HDC hdc;
101 RECT rc;
103 hdc = BeginPaint(hWnd, &ps);
105 GetClientRect(hWnd, &rc);
107 /* dark frame */
108 rc.right += 1;
109 rc.bottom -= 1;
110 FrameRect(hdc, &rc, GetStockObject(GRAY_BRUSH));
112 /* white highlight */
113 SelectObject(hdc, GetStockObject(WHITE_PEN));
114 MoveToEx(hdc, rc.right, 1, NULL);
115 LineTo(hdc, 1, 1);
116 LineTo(hdc, 1, rc.bottom - 1);
119 MoveToEx(hdc, 0, rc.bottom, NULL);
120 LineTo(hdc, rc.right, rc.bottom);
122 EndPaint(hWnd, &ps);
125 LRESULT CALLBACK SizeBar_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
127 switch (message)
129 case WM_PAINT:
130 SB_OnPaint(hWnd);
131 break;
132 default:
133 return DefWindowProcW(hWnd, message, wParam, lParam);
136 return 0;
139 static void HH_RegisterSizeBarClass(HHInfo *pHHInfo)
141 WNDCLASSEXW wcex;
143 wcex.cbSize = sizeof(WNDCLASSEXW);
144 wcex.style = 0;
145 wcex.lpfnWndProc = (WNDPROC)SizeBar_WndProc;
146 wcex.cbClsExtra = 0;
147 wcex.cbWndExtra = 0;
148 wcex.hInstance = pHHInfo->hInstance;
149 wcex.hIcon = LoadIconW(NULL, (LPCWSTR)IDI_APPLICATION);
150 wcex.hCursor = LoadCursorW(NULL, (LPCWSTR)IDC_SIZEWE);
151 wcex.hbrBackground = (HBRUSH)(COLOR_MENU + 1);
152 wcex.lpszMenuName = NULL;
153 wcex.lpszClassName = szSizeBarClass;
154 wcex.hIconSm = LoadIconW(NULL, (LPCWSTR)IDI_APPLICATION);
156 RegisterClassExW(&wcex);
159 static void SB_GetSizeBarRect(HHInfo *pHHInfo, RECT *rc)
161 RECT rectWND, rectTB, rectNP;
163 GetClientRect(pHHInfo->pHHWinType->hwndHelp, &rectWND);
164 GetClientRect(pHHInfo->pHHWinType->hwndToolBar, &rectTB);
165 GetClientRect(pHHInfo->pHHWinType->hwndNavigation, &rectNP);
167 rc->left = rectNP.right;
168 rc->top = rectTB.bottom;
169 rc->bottom = rectWND.bottom - rectTB.bottom;
170 rc->right = SIZEBAR_WIDTH;
173 static BOOL HH_AddSizeBar(HHInfo *pHHInfo)
175 HWND hWnd;
176 HWND hwndParent = pHHInfo->pHHWinType->hwndHelp;
177 DWORD dwStyles = WS_CHILDWINDOW | WS_VISIBLE | WS_OVERLAPPED;
178 DWORD dwExStyles = WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR;
179 RECT rc;
181 SB_GetSizeBarRect(pHHInfo, &rc);
183 hWnd = CreateWindowExW(dwExStyles, szSizeBarClass, szEmpty, dwStyles,
184 rc.left, rc.top, rc.right, rc.bottom,
185 hwndParent, NULL, pHHInfo->hInstance, NULL);
186 if (!hWnd)
187 return FALSE;
189 pHHInfo->hwndSizeBar = hWnd;
190 return TRUE;
193 /* Child Window */
195 static const WCHAR szChildClass[] = {
196 'H','H',' ','C','h','i','l','d',0
199 static void Child_OnPaint(HWND hWnd)
201 PAINTSTRUCT ps;
202 HDC hdc;
203 RECT rc;
205 hdc = BeginPaint(hWnd, &ps);
207 /* Only paint the Navigation pane, identified by the fact
208 * that it has a child window
210 if (GetWindow(hWnd, GW_CHILD))
212 GetClientRect(hWnd, &rc);
214 /* set the border color */
215 SelectObject(hdc, GetStockObject(DC_PEN));
216 SetDCPenColor(hdc, GetSysColor(COLOR_BTNSHADOW));
218 /* Draw the top border */
219 LineTo(hdc, rc.right, 0);
221 SelectObject(hdc, GetStockObject(WHITE_PEN));
222 MoveToEx(hdc, 0, 1, NULL);
223 LineTo(hdc, rc.right, 1);
226 EndPaint(hWnd, &ps);
229 LRESULT CALLBACK Child_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
231 switch (message)
233 case WM_PAINT:
234 Child_OnPaint(hWnd);
235 break;
236 default:
237 return DefWindowProcW(hWnd, message, wParam, lParam);
240 return 0;
243 static void HH_RegisterChildWndClass(HHInfo *pHHInfo)
245 WNDCLASSEXW wcex;
247 wcex.cbSize = sizeof(WNDCLASSEXW);
248 wcex.style = 0;
249 wcex.lpfnWndProc = (WNDPROC)Child_WndProc;
250 wcex.cbClsExtra = 0;
251 wcex.cbWndExtra = 0;
252 wcex.hInstance = pHHInfo->hInstance;
253 wcex.hIcon = LoadIconW(NULL, (LPCWSTR)IDI_APPLICATION);
254 wcex.hCursor = LoadCursorW(NULL, (LPCWSTR)IDC_ARROW);
255 wcex.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
256 wcex.lpszMenuName = NULL;
257 wcex.lpszClassName = szChildClass;
258 wcex.hIconSm = LoadIconW(NULL, (LPCWSTR)IDI_APPLICATION);
260 RegisterClassExW(&wcex);
263 /* Toolbar */
265 #define ICON_SIZE 20
267 static void TB_OnClick(HWND hWnd, DWORD dwID)
269 HHInfo *pHHInfo = (HHInfo *)GetWindowLongPtrW(hWnd, GWLP_USERDATA);
271 switch (dwID)
273 case IDTB_STOP:
274 WB_DoPageAction(pHHInfo->pWBInfo, WB_STOP);
275 break;
276 case IDTB_REFRESH:
277 WB_DoPageAction(pHHInfo->pWBInfo, WB_REFRESH);
278 break;
279 case IDTB_BACK:
280 WB_DoPageAction(pHHInfo->pWBInfo, WB_GOBACK);
281 break;
282 case IDTB_HOME:
284 WCHAR szUrl[MAX_PATH];
286 CHM_CreateITSUrl(pHHInfo->pCHMInfo, pHHInfo->pHHWinType->pszHome, szUrl);
287 WB_Navigate(pHHInfo->pWBInfo, szUrl);
288 break;
290 case IDTB_FORWARD:
291 WB_DoPageAction(pHHInfo->pWBInfo, WB_GOFORWARD);
292 break;
293 case IDTB_EXPAND:
294 case IDTB_CONTRACT:
295 case IDTB_SYNC:
296 case IDTB_PRINT:
297 case IDTB_OPTIONS:
298 case IDTB_BROWSE_FWD:
299 case IDTB_BROWSE_BACK:
300 case IDTB_JUMP1:
301 case IDTB_JUMP2:
302 case IDTB_CUSTOMIZE:
303 case IDTB_ZOOM:
304 case IDTB_TOC_NEXT:
305 case IDTB_TOC_PREV:
306 break;
310 static void TB_AddButton(TBBUTTON *pButtons, DWORD dwIndex, DWORD dwID)
312 /* FIXME: Load the correct button bitmaps */
313 pButtons[dwIndex].iBitmap = STD_PRINT;
314 pButtons[dwIndex].idCommand = dwID;
315 pButtons[dwIndex].fsState = TBSTATE_ENABLED;
316 pButtons[dwIndex].fsStyle = BTNS_BUTTON;
317 pButtons[dwIndex].dwData = 0;
318 pButtons[dwIndex].iString = 0;
321 static void TB_AddButtonsFromFlags(TBBUTTON *pButtons, DWORD dwButtonFlags, LPDWORD pdwNumButtons)
323 *pdwNumButtons = 0;
325 if (dwButtonFlags & HHWIN_BUTTON_EXPAND)
326 TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_EXPAND);
328 if (dwButtonFlags & HHWIN_BUTTON_BACK)
329 TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_BACK);
331 if (dwButtonFlags & HHWIN_BUTTON_FORWARD)
332 TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_FORWARD);
334 if (dwButtonFlags & HHWIN_BUTTON_STOP)
335 TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_STOP);
337 if (dwButtonFlags & HHWIN_BUTTON_REFRESH)
338 TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_REFRESH);
340 if (dwButtonFlags & HHWIN_BUTTON_HOME)
341 TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_HOME);
343 if (dwButtonFlags & HHWIN_BUTTON_SYNC)
344 TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_SYNC);
346 if (dwButtonFlags & HHWIN_BUTTON_OPTIONS)
347 TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_OPTIONS);
349 if (dwButtonFlags & HHWIN_BUTTON_PRINT)
350 TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_PRINT);
352 if (dwButtonFlags & HHWIN_BUTTON_JUMP1)
353 TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_JUMP1);
355 if (dwButtonFlags & HHWIN_BUTTON_JUMP2)
356 TB_AddButton(pButtons,(*pdwNumButtons)++, IDTB_JUMP2);
358 if (dwButtonFlags & HHWIN_BUTTON_ZOOM)
359 TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_ZOOM);
361 if (dwButtonFlags & HHWIN_BUTTON_TOC_NEXT)
362 TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_TOC_NEXT);
364 if (dwButtonFlags & HHWIN_BUTTON_TOC_PREV)
365 TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_TOC_PREV);
368 static BOOL HH_AddToolbar(HHInfo *pHHInfo)
370 HWND hToolbar;
371 HWND hwndParent = pHHInfo->pHHWinType->hwndHelp;
372 DWORD toolbarFlags;
373 TBBUTTON buttons[IDTB_TOC_PREV - IDTB_EXPAND];
374 TBADDBITMAP tbAB;
375 DWORD dwStyles, dwExStyles;
376 DWORD dwNumButtons, dwIndex;
378 if (pHHInfo->pHHWinType->fsWinProperties & HHWIN_PARAM_TB_FLAGS)
379 toolbarFlags = pHHInfo->pHHWinType->fsToolBarFlags;
380 else
381 toolbarFlags = HHWIN_DEF_BUTTONS;
383 TB_AddButtonsFromFlags(buttons, toolbarFlags, &dwNumButtons);
385 dwStyles = WS_CHILDWINDOW | WS_VISIBLE | TBSTYLE_FLAT |
386 TBSTYLE_WRAPABLE | TBSTYLE_TOOLTIPS | CCS_NODIVIDER;
387 dwExStyles = WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR;
389 hToolbar = CreateWindowExW(dwExStyles, TOOLBARCLASSNAMEW, NULL, dwStyles,
390 0, 0, 0, 0, hwndParent, NULL,
391 pHHInfo->hInstance, NULL);
392 if (!hToolbar)
393 return FALSE;
395 SendMessageW(hToolbar, TB_SETBITMAPSIZE, 0, MAKELONG(ICON_SIZE, ICON_SIZE));
396 SendMessageW(hToolbar, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
397 SendMessageW(hToolbar, WM_SETFONT, (WPARAM)pHHInfo->hFont, TRUE);
399 /* FIXME: Load correct icons for all buttons */
400 tbAB.hInst = HINST_COMMCTRL;
401 tbAB.nID = IDB_STD_LARGE_COLOR;
402 SendMessageW(hToolbar, TB_ADDBITMAP, 0, (LPARAM)&tbAB);
404 for (dwIndex = 0; dwIndex < dwNumButtons; dwIndex++)
406 LPWSTR szBuf = HH_LoadString(buttons[dwIndex].idCommand);
407 DWORD dwLen = strlenW(szBuf);
408 szBuf[dwLen + 2] = 0; /* Double-null terminate */
410 buttons[dwIndex].iString = (DWORD)SendMessageW(hToolbar, TB_ADDSTRINGW, 0, (LPARAM)szBuf);
411 HeapFree(GetProcessHeap(), 0, szBuf);
414 SendMessageW(hToolbar, TB_ADDBUTTONSW, dwNumButtons, (LPARAM)&buttons);
415 SendMessageW(hToolbar, TB_AUTOSIZE, 0, 0);
416 ShowWindow(hToolbar, SW_SHOW);
418 pHHInfo->pHHWinType->hwndToolBar = hToolbar;
419 return TRUE;
422 /* Navigation Pane */
424 #define TAB_TOP_PADDING 8
425 #define TAB_RIGHT_PADDING 4
427 static void NP_GetNavigationRect(HHInfo *pHHInfo, RECT *rc)
429 HWND hwndParent = pHHInfo->pHHWinType->hwndHelp;
430 HWND hwndToolbar = pHHInfo->pHHWinType->hwndToolBar;
431 RECT rectWND, rectTB;
433 GetClientRect(hwndParent, &rectWND);
434 GetClientRect(hwndToolbar, &rectTB);
436 rc->left = 0;
437 rc->top = rectTB.bottom;
438 rc->bottom = rectWND.bottom - rectTB.bottom;
440 if (pHHInfo->pHHWinType->fsValidMembers & HHWIN_PARAM_NAV_WIDTH)
441 rc->right = pHHInfo->pHHWinType->iNavWidth;
442 else
443 rc->right = WINTYPE_DEFAULT_NAVWIDTH;
446 static void NP_CreateTab(HINSTANCE hInstance, HWND hwndTabCtrl, DWORD dwStrID, DWORD dwIndex)
448 TCITEMW tie;
449 LPWSTR tabText = HH_LoadString(dwStrID);
451 tie.mask = TCIF_TEXT;
452 tie.pszText = tabText;
454 TabCtrl_InsertItemW(hwndTabCtrl, dwIndex, &tie);
455 HeapFree(GetProcessHeap(), 0, tabText);
458 static BOOL HH_AddNavigationPane(HHInfo *pHHInfo)
460 HWND hWnd, hwndTabCtrl;
461 HWND hwndParent = pHHInfo->pHHWinType->hwndHelp;
462 DWORD dwStyles = WS_CHILDWINDOW | WS_VISIBLE;
463 DWORD dwExStyles = WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR;
464 DWORD dwIndex = 0;
465 RECT rc;
467 NP_GetNavigationRect(pHHInfo, &rc);
469 hWnd = CreateWindowExW(dwExStyles, szChildClass, szEmpty, dwStyles,
470 rc.left, rc.top, rc.right, rc.bottom,
471 hwndParent, NULL, pHHInfo->hInstance, NULL);
472 if (!hWnd)
473 return FALSE;
475 hwndTabCtrl = CreateWindowExW(dwExStyles, WC_TABCONTROLW, szEmpty, dwStyles,
476 0, TAB_TOP_PADDING,
477 rc.right - TAB_RIGHT_PADDING,
478 rc.bottom - TAB_TOP_PADDING,
479 hWnd, NULL, pHHInfo->hInstance, NULL);
480 if (!hwndTabCtrl)
481 return FALSE;
483 if (*pHHInfo->pHHWinType->pszToc)
484 NP_CreateTab(pHHInfo->hInstance, hwndTabCtrl, IDS_CONTENTS, dwIndex++);
486 if (*pHHInfo->pHHWinType->pszIndex)
487 NP_CreateTab(pHHInfo->hInstance, hwndTabCtrl, IDS_INDEX, dwIndex++);
489 if (pHHInfo->pHHWinType->fsWinProperties & HHWIN_PROP_TAB_SEARCH)
490 NP_CreateTab(pHHInfo->hInstance, hwndTabCtrl, IDS_SEARCH, dwIndex++);
492 if (pHHInfo->pHHWinType->fsWinProperties & HHWIN_PROP_TAB_FAVORITES)
493 NP_CreateTab(pHHInfo->hInstance, hwndTabCtrl, IDS_FAVORITES, dwIndex++);
495 SendMessageW(hwndTabCtrl, WM_SETFONT, (WPARAM)pHHInfo->hFont, TRUE);
497 pHHInfo->hwndTabCtrl = hwndTabCtrl;
498 pHHInfo->pHHWinType->hwndNavigation = hWnd;
499 return TRUE;
502 /* HTML Pane */
504 static void HP_GetHTMLRect(HHInfo *pHHInfo, RECT *rc)
506 RECT rectTB, rectWND, rectNP, rectSB;
508 GetClientRect(pHHInfo->pHHWinType->hwndHelp, &rectWND);
509 GetClientRect(pHHInfo->pHHWinType->hwndToolBar, &rectTB);
510 GetClientRect(pHHInfo->pHHWinType->hwndNavigation, &rectNP);
511 GetClientRect(pHHInfo->hwndSizeBar, &rectSB);
513 rc->left = rectNP.right + rectSB.right;
514 rc->top = rectTB.bottom;
515 rc->right = rectWND.right - rc->left;
516 rc->bottom = rectWND.bottom - rectTB.bottom;
519 static BOOL HH_AddHTMLPane(HHInfo *pHHInfo)
521 HWND hWnd;
522 HWND hwndParent = pHHInfo->pHHWinType->hwndHelp;
523 DWORD dwStyles = WS_CHILDWINDOW | WS_VISIBLE | WS_CLIPCHILDREN;
524 DWORD dwExStyles = WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR | WS_EX_CLIENTEDGE;
525 RECT rc;
527 HP_GetHTMLRect(pHHInfo, &rc);
529 hWnd = CreateWindowExW(dwExStyles, szChildClass, szEmpty, dwStyles,
530 rc.left, rc.top, rc.right, rc.bottom,
531 hwndParent, NULL, pHHInfo->hInstance, NULL);
532 if (!hWnd)
533 return FALSE;
535 if (!WB_EmbedBrowser(pHHInfo->pWBInfo, hWnd))
536 return FALSE;
538 /* store the pointer to the HH info struct */
539 SetWindowLongPtrW(hWnd, GWLP_USERDATA, (LONG_PTR)pHHInfo);
541 ShowWindow(hWnd, SW_SHOW);
542 UpdateWindow(hWnd);
544 pHHInfo->pHHWinType->hwndHTML = hWnd;
545 return TRUE;
548 /* Viewer Window */
550 static void Help_OnSize(HWND hWnd)
552 HHInfo *pHHInfo = (HHInfo *)GetWindowLongPtrW(hWnd, GWLP_USERDATA);
553 DWORD dwSize;
554 RECT rc;
556 if (!pHHInfo)
557 return;
559 NP_GetNavigationRect(pHHInfo, &rc);
560 SetWindowPos(pHHInfo->pHHWinType->hwndNavigation, HWND_TOP, 0, 0,
561 rc.right, rc.bottom, SWP_NOMOVE);
563 GetClientRect(pHHInfo->pHHWinType->hwndNavigation, &rc);
564 SetWindowPos(pHHInfo->hwndTabCtrl, HWND_TOP, 0, 0,
565 rc.right - TAB_RIGHT_PADDING,
566 rc.bottom - TAB_TOP_PADDING, SWP_NOMOVE);
568 SB_GetSizeBarRect(pHHInfo, &rc);
569 SetWindowPos(pHHInfo->hwndSizeBar, HWND_TOP, rc.left, rc.top,
570 rc.right, rc.bottom, SWP_SHOWWINDOW);
572 HP_GetHTMLRect(pHHInfo, &rc);
573 SetWindowPos(pHHInfo->pHHWinType->hwndHTML, HWND_TOP, rc.left, rc.top,
574 rc.right, rc.bottom, SWP_SHOWWINDOW);
576 /* Resize browser window taking the frame size into account */
577 dwSize = GetSystemMetrics(SM_CXFRAME);
578 WB_ResizeBrowser(pHHInfo->pWBInfo, rc.right - dwSize, rc.bottom - dwSize);
581 LRESULT CALLBACK Help_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
583 PAINTSTRUCT ps;
584 HDC hdc;
586 switch (message)
588 case WM_COMMAND:
589 if (HIWORD(wParam) == BN_CLICKED)
590 TB_OnClick(hWnd, LOWORD(wParam));
591 break;
592 case WM_SIZE:
593 Help_OnSize(hWnd);
594 break;
595 case WM_PAINT:
596 hdc = BeginPaint(hWnd, &ps);
597 EndPaint(hWnd, &ps);
598 break;
599 case WM_DESTROY:
600 PostQuitMessage(0);
601 break;
603 default:
604 return DefWindowProcW(hWnd, message, wParam, lParam);
607 return 0;
610 static BOOL HH_CreateHelpWindow(HHInfo *pHHInfo)
612 HWND hWnd;
613 HINSTANCE hInstance = pHHInfo->hInstance;
614 RECT winPos = pHHInfo->pHHWinType->rcWindowPos;
615 WNDCLASSEXW wcex;
616 DWORD dwStyles, dwExStyles;
617 DWORD x, y, width, height;
619 static const WCHAR windowClassW[] = {
620 'H','H',' ', 'P','a','r','e','n','t',0
623 wcex.cbSize = sizeof(WNDCLASSEXW);
624 wcex.style = CS_HREDRAW | CS_VREDRAW;
625 wcex.lpfnWndProc = (WNDPROC)Help_WndProc;
626 wcex.cbClsExtra = 0;
627 wcex.cbWndExtra = 0;
628 wcex.hInstance = hInstance;
629 wcex.hIcon = LoadIconW(NULL, (LPCWSTR)IDI_APPLICATION);
630 wcex.hCursor = LoadCursorW(NULL, (LPCWSTR)IDC_ARROW);
631 wcex.hbrBackground = (HBRUSH)(COLOR_MENU + 1);
632 wcex.lpszMenuName = NULL;
633 wcex.lpszClassName = windowClassW;
634 wcex.hIconSm = LoadIconW(NULL, (LPCWSTR)IDI_APPLICATION);
636 RegisterClassExW(&wcex);
638 /* Read in window parameters if available */
639 if (pHHInfo->pHHWinType->fsValidMembers & HHWIN_PARAM_STYLES)
640 dwStyles = pHHInfo->pHHWinType->dwStyles;
641 else
642 dwStyles = WS_OVERLAPPEDWINDOW | WS_VISIBLE |
643 WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
645 if (pHHInfo->pHHWinType->fsValidMembers & HHWIN_PARAM_EXSTYLES)
646 dwExStyles = pHHInfo->pHHWinType->dwExStyles;
647 else
648 dwExStyles = WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_APPWINDOW |
649 WS_EX_WINDOWEDGE | WS_EX_RIGHTSCROLLBAR;
651 if (pHHInfo->pHHWinType->fsValidMembers & HHWIN_PARAM_RECT)
653 x = winPos.left;
654 y = winPos.top;
655 width = winPos.right - x;
656 height = winPos.bottom - y;
658 else
660 x = WINTYPE_DEFAULT_X;
661 y = WINTYPE_DEFAULT_Y;
662 width = WINTYPE_DEFAULT_WIDTH;
663 height = WINTYPE_DEFAULT_HEIGHT;
666 hWnd = CreateWindowExW(dwExStyles, windowClassW, pHHInfo->pHHWinType->pszCaption,
667 dwStyles, x, y, width, height, NULL, NULL, hInstance, NULL);
668 if (!hWnd)
669 return FALSE;
671 ShowWindow(hWnd, SW_SHOW);
672 UpdateWindow(hWnd);
674 /* store the pointer to the HH info struct */
675 SetWindowLongPtrW(hWnd, GWLP_USERDATA, (LONG_PTR)pHHInfo);
677 pHHInfo->pHHWinType->hwndHelp = hWnd;
678 return TRUE;
681 static void HH_CreateFont(HHInfo *pHHInfo)
683 LOGFONTW lf;
685 GetObjectW(GetStockObject(ANSI_VAR_FONT), sizeof(LOGFONTW), &lf);
686 lf.lfWeight = FW_NORMAL;
687 lf.lfItalic = FALSE;
688 lf.lfUnderline = FALSE;
690 pHHInfo->hFont = CreateFontIndirectW(&lf);
693 static void HH_InitRequiredControls(DWORD dwControls)
695 INITCOMMONCONTROLSEX icex;
697 icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
698 icex.dwICC = dwControls;
699 InitCommonControlsEx(&icex);
702 /* Creates the whole package */
703 static BOOL HH_CreateViewer(HHInfo *pHHInfo)
705 HH_CreateFont(pHHInfo);
707 if (!HH_CreateHelpWindow(pHHInfo))
708 return FALSE;
710 HH_InitRequiredControls(ICC_BAR_CLASSES);
712 if (!HH_AddToolbar(pHHInfo))
713 return FALSE;
715 HH_RegisterChildWndClass(pHHInfo);
717 if (!HH_AddNavigationPane(pHHInfo))
718 return FALSE;
720 HH_RegisterSizeBarClass(pHHInfo);
722 if (!HH_AddSizeBar(pHHInfo))
723 return FALSE;
725 if (!HH_AddHTMLPane(pHHInfo))
726 return FALSE;
728 return TRUE;
731 static HHInfo *HH_OpenHH(HINSTANCE hInstance, LPWSTR szCmdLine)
733 HHInfo *pHHInfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(HHInfo));
735 pHHInfo->pHHWinType = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(HH_WINTYPEW));
736 pHHInfo->pCHMInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(CHMInfo));
737 pHHInfo->pWBInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(WBInfo));
738 pHHInfo->hInstance = hInstance;
739 pHHInfo->szCmdLine = szCmdLine;
741 return pHHInfo;
744 static void HH_Close(HHInfo *pHHInfo)
746 if (!pHHInfo)
747 return;
749 /* Free allocated strings */
750 if (pHHInfo->pHHWinType)
752 HeapFree(GetProcessHeap(), 0, (LPWSTR)pHHInfo->pHHWinType->pszType);
753 HeapFree(GetProcessHeap(), 0, (LPWSTR)pHHInfo->pHHWinType->pszCaption);
754 HeapFree(GetProcessHeap(), 0, (LPWSTR)pHHInfo->pHHWinType->pszToc);
755 HeapFree(GetProcessHeap(), 0, (LPWSTR)pHHInfo->pHHWinType->pszType);
756 HeapFree(GetProcessHeap(), 0, (LPWSTR)pHHInfo->pHHWinType->pszIndex);
757 HeapFree(GetProcessHeap(), 0, (LPWSTR)pHHInfo->pHHWinType->pszFile);
758 HeapFree(GetProcessHeap(), 0, (LPWSTR)pHHInfo->pHHWinType->pszHome);
759 HeapFree(GetProcessHeap(), 0, (LPWSTR)pHHInfo->pHHWinType->pszJump1);
760 HeapFree(GetProcessHeap(), 0, (LPWSTR)pHHInfo->pHHWinType->pszJump2);
761 HeapFree(GetProcessHeap(), 0, (LPWSTR)pHHInfo->pHHWinType->pszUrlJump1);
762 HeapFree(GetProcessHeap(), 0, (LPWSTR)pHHInfo->pHHWinType->pszUrlJump2);
765 HeapFree(GetProcessHeap(), 0, pHHInfo->pHHWinType);
766 HeapFree(GetProcessHeap(), 0, pHHInfo->szCmdLine);
768 if (pHHInfo->pCHMInfo)
770 CHM_CloseCHM(pHHInfo->pCHMInfo);
771 HeapFree(GetProcessHeap(), 0, pHHInfo->pCHMInfo);
774 if (pHHInfo->pWBInfo)
776 WB_UnEmbedBrowser(pHHInfo->pWBInfo);
777 HeapFree(GetProcessHeap(), 0, pHHInfo->pWBInfo);
781 static void HH_OpenDefaultTopic(HHInfo *pHHInfo)
783 WCHAR url[MAX_PATH];
784 LPCWSTR defTopic = pHHInfo->pHHWinType->pszFile;
786 CHM_CreateITSUrl(pHHInfo->pCHMInfo, defTopic, url);
787 WB_Navigate(pHHInfo->pWBInfo, url);
790 static BOOL HH_OpenCHM(HHInfo *pHHInfo)
792 if (!CHM_OpenCHM(pHHInfo->pCHMInfo, pHHInfo->szCmdLine))
793 return FALSE;
795 if (!CHM_LoadWinTypeFromCHM(pHHInfo->pCHMInfo, pHHInfo->pHHWinType))
796 return FALSE;
798 return TRUE;
801 /* FIXME: Check szCmdLine for bad arguments */
802 int WINAPI doWinMain(HINSTANCE hInstance, LPSTR szCmdLine)
804 MSG msg;
805 HHInfo *pHHInfo;
807 if (OleInitialize(NULL) != S_OK)
808 return -1;
810 pHHInfo = HH_OpenHH(hInstance, HH_ANSIToUnicode(szCmdLine));
811 if (!pHHInfo || !HH_OpenCHM(pHHInfo) || !HH_CreateViewer(pHHInfo))
813 OleUninitialize();
814 return -1;
817 HH_OpenDefaultTopic(pHHInfo);
819 while (GetMessageW(&msg, 0, 0, 0))
821 TranslateMessage(&msg);
822 DispatchMessageW(&msg);
825 HH_Close(pHHInfo);
826 HeapFree(GetProcessHeap(), 0, pHHInfo);
827 OleUninitialize();
829 return 0;