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
31 #include "wine/unicode.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;
59 extern HINSTANCE hhctrl_hinstance;
61 static LPWSTR HH_ANSIToUnicode(LPCSTR ansi)
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);
73 /* Loads a string from the resource file */
74 static LPWSTR HH_LoadString(DWORD dwID)
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);
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)
103 hdc = BeginPaint(hWnd, &ps);
105 GetClientRect(hWnd, &rc);
110 FrameRect(hdc, &rc, GetStockObject(GRAY_BRUSH));
112 /* white highlight */
113 SelectObject(hdc, GetStockObject(WHITE_PEN));
114 MoveToEx(hdc, rc.right, 1, NULL);
116 LineTo(hdc, 1, rc.bottom - 1);
119 MoveToEx(hdc, 0, rc.bottom, NULL);
120 LineTo(hdc, rc.right, rc.bottom);
125 LRESULT CALLBACK SizeBar_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
133 return DefWindowProcW(hWnd, message, wParam, lParam);
139 static void HH_RegisterSizeBarClass(HHInfo *pHHInfo)
143 wcex.cbSize = sizeof(WNDCLASSEXW);
145 wcex.lpfnWndProc = (WNDPROC)SizeBar_WndProc;
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)
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;
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);
189 pHHInfo->hwndSizeBar = hWnd;
195 static const WCHAR szChildClass[] = {
196 'H','H',' ','C','h','i','l','d',0
199 static void Child_OnPaint(HWND hWnd)
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);
229 LRESULT CALLBACK Child_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
237 return DefWindowProcW(hWnd, message, wParam, lParam);
243 static void HH_RegisterChildWndClass(HHInfo *pHHInfo)
247 wcex.cbSize = sizeof(WNDCLASSEXW);
249 wcex.lpfnWndProc = (WNDPROC)Child_WndProc;
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);
267 static void TB_OnClick(HWND hWnd, DWORD dwID)
269 HHInfo *pHHInfo = (HHInfo *)GetWindowLongPtrW(hWnd, GWLP_USERDATA);
274 WB_DoPageAction(pHHInfo->pWBInfo, WB_STOP);
277 WB_DoPageAction(pHHInfo->pWBInfo, WB_REFRESH);
280 WB_DoPageAction(pHHInfo->pWBInfo, WB_GOBACK);
284 WCHAR szUrl[MAX_PATH];
286 CHM_CreateITSUrl(pHHInfo->pCHMInfo, pHHInfo->pHHWinType->pszHome, szUrl);
287 WB_Navigate(pHHInfo->pWBInfo, szUrl);
291 WB_DoPageAction(pHHInfo->pWBInfo, WB_GOFORWARD);
298 case IDTB_BROWSE_FWD:
299 case IDTB_BROWSE_BACK:
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)
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)
371 HWND hwndParent = pHHInfo->pHHWinType->hwndHelp;
373 TBBUTTON buttons[IDTB_TOC_PREV - IDTB_EXPAND];
375 DWORD dwStyles, dwExStyles;
376 DWORD dwNumButtons, dwIndex;
378 if (pHHInfo->pHHWinType->fsWinProperties & HHWIN_PARAM_TB_FLAGS)
379 toolbarFlags = pHHInfo->pHHWinType->fsToolBarFlags;
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);
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;
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);
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;
443 rc->right = WINTYPE_DEFAULT_NAVWIDTH;
446 static void NP_CreateTab(HINSTANCE hInstance, HWND hwndTabCtrl, DWORD dwStrID, DWORD dwIndex)
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;
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);
475 hwndTabCtrl = CreateWindowExW(dwExStyles, WC_TABCONTROLW, szEmpty, dwStyles,
477 rc.right - TAB_RIGHT_PADDING,
478 rc.bottom - TAB_TOP_PADDING,
479 hWnd, NULL, pHHInfo->hInstance, NULL);
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;
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)
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;
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);
535 if (!WB_EmbedBrowser(pHHInfo->pWBInfo, hWnd))
538 /* store the pointer to the HH info struct */
539 SetWindowLongPtrW(hWnd, GWLP_USERDATA, (LONG_PTR)pHHInfo);
541 ShowWindow(hWnd, SW_SHOW);
544 pHHInfo->pHHWinType->hwndHTML = hWnd;
550 static void Help_OnSize(HWND hWnd, LPARAM lParam)
552 HHInfo *pHHInfo = (HHInfo *)GetWindowLongPtrW(hWnd, GWLP_USERDATA);
558 /* Only resize the Navigation pane and SizeBar vertically */
561 NP_GetNavigationRect(pHHInfo, &rc);
562 SetWindowPos(pHHInfo->pHHWinType->hwndNavigation, HWND_TOP, 0, 0,
563 rc.right, rc.bottom, SWP_NOMOVE);
565 GetClientRect(pHHInfo->pHHWinType->hwndNavigation, &rc);
566 SetWindowPos(pHHInfo->hwndTabCtrl, HWND_TOP, 0, 0,
567 rc.right - TAB_RIGHT_PADDING,
568 rc.bottom - TAB_TOP_PADDING, SWP_NOMOVE);
570 SB_GetSizeBarRect(pHHInfo, &rc);
571 SetWindowPos(pHHInfo->hwndSizeBar, HWND_TOP, 0, 0,
572 rc.right, rc.bottom, SWP_NOMOVE);
575 HP_GetHTMLRect(pHHInfo, &rc);
576 SetWindowPos(pHHInfo->pHHWinType->hwndHTML, HWND_TOP, 0, 0,
577 LOWORD(lParam), HIWORD(lParam), SWP_NOMOVE);
580 LRESULT CALLBACK Help_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
588 if (HIWORD(wParam) == BN_CLICKED)
589 TB_OnClick(hWnd, LOWORD(wParam));
592 Help_OnSize(hWnd, lParam);
595 hdc = BeginPaint(hWnd, &ps);
603 return DefWindowProcW(hWnd, message, wParam, lParam);
609 static BOOL HH_CreateHelpWindow(HHInfo *pHHInfo)
612 HINSTANCE hInstance = pHHInfo->hInstance;
613 RECT winPos = pHHInfo->pHHWinType->rcWindowPos;
615 DWORD dwStyles, dwExStyles;
616 DWORD x, y, width, height;
618 static const WCHAR windowClassW[] = {
619 'H','H',' ', 'P','a','r','e','n','t',0
622 wcex.cbSize = sizeof(WNDCLASSEXW);
623 wcex.style = CS_HREDRAW | CS_VREDRAW;
624 wcex.lpfnWndProc = (WNDPROC)Help_WndProc;
627 wcex.hInstance = hInstance;
628 wcex.hIcon = LoadIconW(NULL, (LPCWSTR)IDI_APPLICATION);
629 wcex.hCursor = LoadCursorW(NULL, (LPCWSTR)IDC_ARROW);
630 wcex.hbrBackground = (HBRUSH)(COLOR_MENU + 1);
631 wcex.lpszMenuName = NULL;
632 wcex.lpszClassName = windowClassW;
633 wcex.hIconSm = LoadIconW(NULL, (LPCWSTR)IDI_APPLICATION);
635 RegisterClassExW(&wcex);
637 /* Read in window parameters if available */
638 if (pHHInfo->pHHWinType->fsValidMembers & HHWIN_PARAM_STYLES)
639 dwStyles = pHHInfo->pHHWinType->dwStyles;
641 dwStyles = WS_OVERLAPPEDWINDOW | WS_VISIBLE |
642 WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
644 if (pHHInfo->pHHWinType->fsValidMembers & HHWIN_PARAM_EXSTYLES)
645 dwExStyles = pHHInfo->pHHWinType->dwExStyles;
647 dwExStyles = WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_APPWINDOW |
648 WS_EX_WINDOWEDGE | WS_EX_RIGHTSCROLLBAR;
650 if (pHHInfo->pHHWinType->fsValidMembers & HHWIN_PARAM_RECT)
654 width = winPos.right - x;
655 height = winPos.bottom - y;
659 x = WINTYPE_DEFAULT_X;
660 y = WINTYPE_DEFAULT_Y;
661 width = WINTYPE_DEFAULT_WIDTH;
662 height = WINTYPE_DEFAULT_HEIGHT;
665 hWnd = CreateWindowExW(dwExStyles, windowClassW, pHHInfo->pHHWinType->pszCaption,
666 dwStyles, x, y, width, height, NULL, NULL, hInstance, NULL);
670 ShowWindow(hWnd, SW_SHOW);
673 /* store the pointer to the HH info struct */
674 SetWindowLongPtrW(hWnd, GWLP_USERDATA, (LONG_PTR)pHHInfo);
676 pHHInfo->pHHWinType->hwndHelp = hWnd;
680 static void HH_CreateFont(HHInfo *pHHInfo)
684 GetObjectW(GetStockObject(ANSI_VAR_FONT), sizeof(LOGFONTW), &lf);
685 lf.lfWeight = FW_NORMAL;
687 lf.lfUnderline = FALSE;
689 pHHInfo->hFont = CreateFontIndirectW(&lf);
692 static void HH_InitRequiredControls(DWORD dwControls)
694 INITCOMMONCONTROLSEX icex;
696 icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
697 icex.dwICC = dwControls;
698 InitCommonControlsEx(&icex);
701 /* Creates the whole package */
702 static BOOL HH_CreateViewer(HHInfo *pHHInfo)
704 HH_CreateFont(pHHInfo);
706 if (!HH_CreateHelpWindow(pHHInfo))
709 HH_InitRequiredControls(ICC_BAR_CLASSES);
711 if (!HH_AddToolbar(pHHInfo))
714 HH_RegisterChildWndClass(pHHInfo);
716 if (!HH_AddNavigationPane(pHHInfo))
719 HH_RegisterSizeBarClass(pHHInfo);
721 if (!HH_AddSizeBar(pHHInfo))
724 if (!HH_AddHTMLPane(pHHInfo))
730 static HHInfo *HH_OpenHH(HINSTANCE hInstance, LPWSTR szCmdLine)
732 HHInfo *pHHInfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(HHInfo));
734 pHHInfo->pHHWinType = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(HH_WINTYPEW));
735 pHHInfo->pCHMInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(CHMInfo));
736 pHHInfo->pWBInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(WBInfo));
737 pHHInfo->hInstance = hInstance;
738 pHHInfo->szCmdLine = szCmdLine;
743 static void HH_Close(HHInfo *pHHInfo)
748 /* Free allocated strings */
749 if (pHHInfo->pHHWinType)
751 HeapFree(GetProcessHeap(), 0, (LPWSTR)pHHInfo->pHHWinType->pszType);
752 HeapFree(GetProcessHeap(), 0, (LPWSTR)pHHInfo->pHHWinType->pszCaption);
753 HeapFree(GetProcessHeap(), 0, (LPWSTR)pHHInfo->pHHWinType->pszToc);
754 HeapFree(GetProcessHeap(), 0, (LPWSTR)pHHInfo->pHHWinType->pszType);
755 HeapFree(GetProcessHeap(), 0, (LPWSTR)pHHInfo->pHHWinType->pszIndex);
756 HeapFree(GetProcessHeap(), 0, (LPWSTR)pHHInfo->pHHWinType->pszFile);
757 HeapFree(GetProcessHeap(), 0, (LPWSTR)pHHInfo->pHHWinType->pszHome);
758 HeapFree(GetProcessHeap(), 0, (LPWSTR)pHHInfo->pHHWinType->pszJump1);
759 HeapFree(GetProcessHeap(), 0, (LPWSTR)pHHInfo->pHHWinType->pszJump2);
760 HeapFree(GetProcessHeap(), 0, (LPWSTR)pHHInfo->pHHWinType->pszUrlJump1);
761 HeapFree(GetProcessHeap(), 0, (LPWSTR)pHHInfo->pHHWinType->pszUrlJump2);
764 HeapFree(GetProcessHeap(), 0, pHHInfo->pHHWinType);
765 HeapFree(GetProcessHeap(), 0, pHHInfo->szCmdLine);
767 if (pHHInfo->pCHMInfo)
769 CHM_CloseCHM(pHHInfo->pCHMInfo);
770 HeapFree(GetProcessHeap(), 0, pHHInfo->pCHMInfo);
773 if (pHHInfo->pWBInfo)
775 WB_UnEmbedBrowser(pHHInfo->pWBInfo);
776 HeapFree(GetProcessHeap(), 0, pHHInfo->pWBInfo);
780 static void HH_OpenDefaultTopic(HHInfo *pHHInfo)
783 LPCWSTR defTopic = pHHInfo->pHHWinType->pszFile;
785 CHM_CreateITSUrl(pHHInfo->pCHMInfo, defTopic, url);
786 WB_Navigate(pHHInfo->pWBInfo, url);
789 static BOOL HH_OpenCHM(HHInfo *pHHInfo)
791 if (!CHM_OpenCHM(pHHInfo->pCHMInfo, pHHInfo->szCmdLine))
794 if (!CHM_LoadWinTypeFromCHM(pHHInfo->pCHMInfo, pHHInfo->pHHWinType))
800 /* FIXME: Check szCmdLine for bad arguments */
801 int WINAPI doWinMain(HINSTANCE hInstance, LPSTR szCmdLine)
806 if (OleInitialize(NULL) != S_OK)
809 pHHInfo = HH_OpenHH(hInstance, HH_ANSIToUnicode(szCmdLine));
810 if (!pHHInfo || !HH_OpenCHM(pHHInfo) || !HH_CreateViewer(pHHInfo))
816 HH_OpenDefaultTopic(pHHInfo);
818 while (GetMessageW(&msg, 0, 0, 0))
820 TranslateMessage(&msg);
821 DispatchMessageW(&msg);
825 HeapFree(GetProcessHeap(), 0, pHHInfo);