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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 #include "wine/debug.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(htmlhelp
);
33 static void Help_OnSize(HWND hWnd
);
35 /* Window type defaults */
37 #define WINTYPE_DEFAULT_X 280
38 #define WINTYPE_DEFAULT_Y 100
39 #define WINTYPE_DEFAULT_WIDTH 740
40 #define WINTYPE_DEFAULT_HEIGHT 640
41 #define WINTYPE_DEFAULT_NAVWIDTH 250
43 static const WCHAR szEmpty
[] = {0};
45 /* Loads a string from the resource file */
46 static LPWSTR
HH_LoadString(DWORD dwID
)
51 iSize
= LoadStringW(hhctrl_hinstance
, dwID
, NULL
, 0);
52 iSize
+= 2; /* some strings (tab text) needs double-null termination */
54 string
= hhctrl_alloc(iSize
* sizeof(WCHAR
));
55 LoadStringW(hhctrl_hinstance
, dwID
, string
, iSize
);
60 static BOOL
NavigateToChm(HHInfo
*info
, LPCWSTR file
, LPCWSTR index
)
62 WCHAR buf
[INTERNET_MAX_URL_LENGTH
];
63 WCHAR full_path
[MAX_PATH
];
66 static const WCHAR url_format
[] =
67 {'m','k',':','@','M','S','I','T','S','t','o','r','e',':','%','s',':',':','/','%','s',0};
69 if (!info
->web_browser
)
72 if(!GetFullPathNameW(file
, sizeof(full_path
), full_path
, NULL
)) {
73 WARN("GetFullPathName failed: %u\n", GetLastError());
77 wsprintfW(buf
, url_format
, full_path
, index
);
80 V_BSTR(&url
) = SysAllocString(buf
);
82 IWebBrowser2_Navigate2(info
->web_browser
, &url
, 0, 0, 0, 0);
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 static void SB_OnLButtonDown(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
130 static void SB_OnLButtonUp(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
132 HHInfo
*pHHInfo
= (HHInfo
*)GetWindowLongPtrW(hWnd
, GWLP_USERDATA
);
135 pt
.x
= (short)LOWORD(lParam
);
136 pt
.y
= (short)HIWORD(lParam
);
138 /* update the window sizes */
139 pHHInfo
->WinType
.iNavWidth
+= pt
.x
;
145 static void SB_OnMouseMove(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
147 /* ignore WM_MOUSEMOVE if not dragging the SizeBar */
148 if (!(wParam
& MK_LBUTTON
))
152 static LRESULT CALLBACK
SizeBar_WndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
157 SB_OnLButtonDown(hWnd
, wParam
, lParam
);
160 SB_OnLButtonUp(hWnd
, wParam
, lParam
);
163 SB_OnMouseMove(hWnd
, wParam
, lParam
);
169 return DefWindowProcW(hWnd
, message
, wParam
, lParam
);
175 static void HH_RegisterSizeBarClass(HHInfo
*pHHInfo
)
179 wcex
.cbSize
= sizeof(WNDCLASSEXW
);
181 wcex
.lpfnWndProc
= (WNDPROC
)SizeBar_WndProc
;
184 wcex
.hInstance
= hhctrl_hinstance
;
185 wcex
.hIcon
= LoadIconW(NULL
, (LPCWSTR
)IDI_APPLICATION
);
186 wcex
.hCursor
= LoadCursorW(NULL
, (LPCWSTR
)IDC_SIZEWE
);
187 wcex
.hbrBackground
= (HBRUSH
)(COLOR_MENU
+ 1);
188 wcex
.lpszMenuName
= NULL
;
189 wcex
.lpszClassName
= szSizeBarClass
;
190 wcex
.hIconSm
= LoadIconW(NULL
, (LPCWSTR
)IDI_APPLICATION
);
192 RegisterClassExW(&wcex
);
195 static void SB_GetSizeBarRect(HHInfo
*info
, RECT
*rc
)
197 RECT rectWND
, rectTB
, rectNP
;
199 GetClientRect(info
->WinType
.hwndHelp
, &rectWND
);
200 GetClientRect(info
->WinType
.hwndToolBar
, &rectTB
);
201 GetClientRect(info
->WinType
.hwndNavigation
, &rectNP
);
203 rc
->left
= rectNP
.right
;
204 rc
->top
= rectTB
.bottom
;
205 rc
->bottom
= rectWND
.bottom
- rectTB
.bottom
;
206 rc
->right
= SIZEBAR_WIDTH
;
209 static BOOL
HH_AddSizeBar(HHInfo
*pHHInfo
)
212 HWND hwndParent
= pHHInfo
->WinType
.hwndHelp
;
213 DWORD dwStyles
= WS_CHILDWINDOW
| WS_VISIBLE
| WS_OVERLAPPED
;
214 DWORD dwExStyles
= WS_EX_LEFT
| WS_EX_LTRREADING
| WS_EX_RIGHTSCROLLBAR
;
217 SB_GetSizeBarRect(pHHInfo
, &rc
);
219 hWnd
= CreateWindowExW(dwExStyles
, szSizeBarClass
, szEmpty
, dwStyles
,
220 rc
.left
, rc
.top
, rc
.right
, rc
.bottom
,
221 hwndParent
, NULL
, hhctrl_hinstance
, NULL
);
225 /* store the pointer to the HH info struct */
226 SetWindowLongPtrW(hWnd
, GWLP_USERDATA
, (LONG_PTR
)pHHInfo
);
228 pHHInfo
->hwndSizeBar
= hWnd
;
234 static const WCHAR szChildClass
[] = {
235 'H','H',' ','C','h','i','l','d',0
238 static void Child_OnPaint(HWND hWnd
)
244 hdc
= BeginPaint(hWnd
, &ps
);
246 /* Only paint the Navigation pane, identified by the fact
247 * that it has a child window
249 if (GetWindow(hWnd
, GW_CHILD
))
251 GetClientRect(hWnd
, &rc
);
253 /* set the border color */
254 SelectObject(hdc
, GetStockObject(DC_PEN
));
255 SetDCPenColor(hdc
, GetSysColor(COLOR_BTNSHADOW
));
257 /* Draw the top border */
258 LineTo(hdc
, rc
.right
, 0);
260 SelectObject(hdc
, GetStockObject(WHITE_PEN
));
261 MoveToEx(hdc
, 0, 1, NULL
);
262 LineTo(hdc
, rc
.right
, 1);
268 static LRESULT CALLBACK
Child_WndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
276 return DefWindowProcW(hWnd
, message
, wParam
, lParam
);
282 static void HH_RegisterChildWndClass(HHInfo
*pHHInfo
)
286 wcex
.cbSize
= sizeof(WNDCLASSEXW
);
288 wcex
.lpfnWndProc
= (WNDPROC
)Child_WndProc
;
291 wcex
.hInstance
= hhctrl_hinstance
;
292 wcex
.hIcon
= LoadIconW(NULL
, (LPCWSTR
)IDI_APPLICATION
);
293 wcex
.hCursor
= LoadCursorW(NULL
, (LPCWSTR
)IDC_ARROW
);
294 wcex
.hbrBackground
= (HBRUSH
)(COLOR_BTNFACE
+ 1);
295 wcex
.lpszMenuName
= NULL
;
296 wcex
.lpszClassName
= szChildClass
;
297 wcex
.hIconSm
= LoadIconW(NULL
, (LPCWSTR
)IDI_APPLICATION
);
299 RegisterClassExW(&wcex
);
306 static void TB_OnClick(HWND hWnd
, DWORD dwID
)
308 HHInfo
*info
= (HHInfo
*)GetWindowLongPtrW(hWnd
, GWLP_USERDATA
);
313 DoPageAction(info
, WB_STOP
);
316 DoPageAction(info
, WB_REFRESH
);
319 DoPageAction(info
, WB_GOBACK
);
322 NavigateToChm(info
, info
->pCHMInfo
->szFile
, info
->WinType
.pszHome
);
325 DoPageAction(info
, WB_GOFORWARD
);
332 case IDTB_BROWSE_FWD
:
333 case IDTB_BROWSE_BACK
:
344 static void TB_AddButton(TBBUTTON
*pButtons
, DWORD dwIndex
, DWORD dwID
)
346 /* FIXME: Load the correct button bitmaps */
347 pButtons
[dwIndex
].iBitmap
= STD_PRINT
;
348 pButtons
[dwIndex
].idCommand
= dwID
;
349 pButtons
[dwIndex
].fsState
= TBSTATE_ENABLED
;
350 pButtons
[dwIndex
].fsStyle
= BTNS_BUTTON
;
351 pButtons
[dwIndex
].dwData
= 0;
352 pButtons
[dwIndex
].iString
= 0;
355 static void TB_AddButtonsFromFlags(TBBUTTON
*pButtons
, DWORD dwButtonFlags
, LPDWORD pdwNumButtons
)
359 if (dwButtonFlags
& HHWIN_BUTTON_EXPAND
)
360 TB_AddButton(pButtons
, (*pdwNumButtons
)++, IDTB_EXPAND
);
362 if (dwButtonFlags
& HHWIN_BUTTON_BACK
)
363 TB_AddButton(pButtons
, (*pdwNumButtons
)++, IDTB_BACK
);
365 if (dwButtonFlags
& HHWIN_BUTTON_FORWARD
)
366 TB_AddButton(pButtons
, (*pdwNumButtons
)++, IDTB_FORWARD
);
368 if (dwButtonFlags
& HHWIN_BUTTON_STOP
)
369 TB_AddButton(pButtons
, (*pdwNumButtons
)++, IDTB_STOP
);
371 if (dwButtonFlags
& HHWIN_BUTTON_REFRESH
)
372 TB_AddButton(pButtons
, (*pdwNumButtons
)++, IDTB_REFRESH
);
374 if (dwButtonFlags
& HHWIN_BUTTON_HOME
)
375 TB_AddButton(pButtons
, (*pdwNumButtons
)++, IDTB_HOME
);
377 if (dwButtonFlags
& HHWIN_BUTTON_SYNC
)
378 TB_AddButton(pButtons
, (*pdwNumButtons
)++, IDTB_SYNC
);
380 if (dwButtonFlags
& HHWIN_BUTTON_OPTIONS
)
381 TB_AddButton(pButtons
, (*pdwNumButtons
)++, IDTB_OPTIONS
);
383 if (dwButtonFlags
& HHWIN_BUTTON_PRINT
)
384 TB_AddButton(pButtons
, (*pdwNumButtons
)++, IDTB_PRINT
);
386 if (dwButtonFlags
& HHWIN_BUTTON_JUMP1
)
387 TB_AddButton(pButtons
, (*pdwNumButtons
)++, IDTB_JUMP1
);
389 if (dwButtonFlags
& HHWIN_BUTTON_JUMP2
)
390 TB_AddButton(pButtons
,(*pdwNumButtons
)++, IDTB_JUMP2
);
392 if (dwButtonFlags
& HHWIN_BUTTON_ZOOM
)
393 TB_AddButton(pButtons
, (*pdwNumButtons
)++, IDTB_ZOOM
);
395 if (dwButtonFlags
& HHWIN_BUTTON_TOC_NEXT
)
396 TB_AddButton(pButtons
, (*pdwNumButtons
)++, IDTB_TOC_NEXT
);
398 if (dwButtonFlags
& HHWIN_BUTTON_TOC_PREV
)
399 TB_AddButton(pButtons
, (*pdwNumButtons
)++, IDTB_TOC_PREV
);
402 static BOOL
HH_AddToolbar(HHInfo
*pHHInfo
)
405 HWND hwndParent
= pHHInfo
->WinType
.hwndHelp
;
407 TBBUTTON buttons
[IDTB_TOC_PREV
- IDTB_EXPAND
];
409 DWORD dwStyles
, dwExStyles
;
410 DWORD dwNumButtons
, dwIndex
;
412 if (pHHInfo
->WinType
.fsWinProperties
& HHWIN_PARAM_TB_FLAGS
)
413 toolbarFlags
= pHHInfo
->WinType
.fsToolBarFlags
;
415 toolbarFlags
= HHWIN_DEF_BUTTONS
;
417 TB_AddButtonsFromFlags(buttons
, toolbarFlags
, &dwNumButtons
);
419 dwStyles
= WS_CHILDWINDOW
| WS_VISIBLE
| TBSTYLE_FLAT
|
420 TBSTYLE_WRAPABLE
| TBSTYLE_TOOLTIPS
| CCS_NODIVIDER
;
421 dwExStyles
= WS_EX_LEFT
| WS_EX_LTRREADING
| WS_EX_RIGHTSCROLLBAR
;
423 hToolbar
= CreateWindowExW(dwExStyles
, TOOLBARCLASSNAMEW
, NULL
, dwStyles
,
424 0, 0, 0, 0, hwndParent
, NULL
,
425 hhctrl_hinstance
, NULL
);
429 SendMessageW(hToolbar
, TB_SETBITMAPSIZE
, 0, MAKELONG(ICON_SIZE
, ICON_SIZE
));
430 SendMessageW(hToolbar
, TB_BUTTONSTRUCTSIZE
, sizeof(TBBUTTON
), 0);
431 SendMessageW(hToolbar
, WM_SETFONT
, (WPARAM
)pHHInfo
->hFont
, TRUE
);
433 /* FIXME: Load correct icons for all buttons */
434 tbAB
.hInst
= HINST_COMMCTRL
;
435 tbAB
.nID
= IDB_STD_LARGE_COLOR
;
436 SendMessageW(hToolbar
, TB_ADDBITMAP
, 0, (LPARAM
)&tbAB
);
438 for (dwIndex
= 0; dwIndex
< dwNumButtons
; dwIndex
++)
440 LPWSTR szBuf
= HH_LoadString(buttons
[dwIndex
].idCommand
);
441 DWORD dwLen
= strlenW(szBuf
);
442 szBuf
[dwLen
+ 2] = 0; /* Double-null terminate */
444 buttons
[dwIndex
].iString
= (DWORD
)SendMessageW(hToolbar
, TB_ADDSTRINGW
, 0, (LPARAM
)szBuf
);
448 SendMessageW(hToolbar
, TB_ADDBUTTONSW
, dwNumButtons
, (LPARAM
)&buttons
);
449 SendMessageW(hToolbar
, TB_AUTOSIZE
, 0, 0);
450 ShowWindow(hToolbar
, SW_SHOW
);
452 pHHInfo
->WinType
.hwndToolBar
= hToolbar
;
456 /* Navigation Pane */
458 #define TAB_TOP_PADDING 8
459 #define TAB_RIGHT_PADDING 4
461 static void NP_GetNavigationRect(HHInfo
*pHHInfo
, RECT
*rc
)
463 HWND hwndParent
= pHHInfo
->WinType
.hwndHelp
;
464 HWND hwndToolbar
= pHHInfo
->WinType
.hwndToolBar
;
465 RECT rectWND
, rectTB
;
467 GetClientRect(hwndParent
, &rectWND
);
468 GetClientRect(hwndToolbar
, &rectTB
);
471 rc
->top
= rectTB
.bottom
;
472 rc
->bottom
= rectWND
.bottom
- rectTB
.bottom
;
474 if (!(pHHInfo
->WinType
.fsValidMembers
& HHWIN_PARAM_NAV_WIDTH
) &&
475 pHHInfo
->WinType
.iNavWidth
== 0)
477 pHHInfo
->WinType
.iNavWidth
= WINTYPE_DEFAULT_NAVWIDTH
;
480 rc
->right
= pHHInfo
->WinType
.iNavWidth
;
483 static void NP_CreateTab(HINSTANCE hInstance
, HWND hwndTabCtrl
, DWORD dwStrID
, DWORD dwIndex
)
486 LPWSTR tabText
= HH_LoadString(dwStrID
);
488 tie
.mask
= TCIF_TEXT
;
489 tie
.pszText
= tabText
;
491 SendMessageW( hwndTabCtrl
, TCM_INSERTITEMW
, dwIndex
, (LPARAM
)&tie
);
492 hhctrl_free(tabText
);
495 static BOOL
HH_AddNavigationPane(HHInfo
*info
)
497 HWND hWnd
, hwndTabCtrl
;
498 HWND hwndParent
= info
->WinType
.hwndHelp
;
499 DWORD dwStyles
= WS_CHILDWINDOW
| WS_VISIBLE
;
500 DWORD dwExStyles
= WS_EX_LEFT
| WS_EX_LTRREADING
| WS_EX_RIGHTSCROLLBAR
;
504 NP_GetNavigationRect(info
, &rc
);
506 hWnd
= CreateWindowExW(dwExStyles
, szChildClass
, szEmpty
, dwStyles
,
507 rc
.left
, rc
.top
, rc
.right
, rc
.bottom
,
508 hwndParent
, NULL
, hhctrl_hinstance
, NULL
);
512 hwndTabCtrl
= CreateWindowExW(dwExStyles
, WC_TABCONTROLW
, szEmpty
, dwStyles
,
514 rc
.right
- TAB_RIGHT_PADDING
,
515 rc
.bottom
- TAB_TOP_PADDING
,
516 hWnd
, NULL
, hhctrl_hinstance
, NULL
);
520 if (*info
->WinType
.pszToc
)
521 NP_CreateTab(hhctrl_hinstance
, hwndTabCtrl
, IDS_CONTENTS
, dwIndex
++);
523 if (*info
->WinType
.pszIndex
)
524 NP_CreateTab(hhctrl_hinstance
, hwndTabCtrl
, IDS_INDEX
, dwIndex
++);
526 if (info
->WinType
.fsWinProperties
& HHWIN_PROP_TAB_SEARCH
)
527 NP_CreateTab(hhctrl_hinstance
, hwndTabCtrl
, IDS_SEARCH
, dwIndex
++);
529 if (info
->WinType
.fsWinProperties
& HHWIN_PROP_TAB_FAVORITES
)
530 NP_CreateTab(hhctrl_hinstance
, hwndTabCtrl
, IDS_FAVORITES
, dwIndex
++);
532 SendMessageW(hwndTabCtrl
, WM_SETFONT
, (WPARAM
)info
->hFont
, TRUE
);
534 info
->hwndTabCtrl
= hwndTabCtrl
;
535 info
->WinType
.hwndNavigation
= hWnd
;
541 static void HP_GetHTMLRect(HHInfo
*info
, RECT
*rc
)
543 RECT rectTB
, rectWND
, rectNP
, rectSB
;
545 GetClientRect(info
->WinType
.hwndHelp
, &rectWND
);
546 GetClientRect(info
->WinType
.hwndToolBar
, &rectTB
);
547 GetClientRect(info
->WinType
.hwndNavigation
, &rectNP
);
548 GetClientRect(info
->hwndSizeBar
, &rectSB
);
550 rc
->left
= rectNP
.right
+ rectSB
.right
;
551 rc
->top
= rectTB
.bottom
;
552 rc
->right
= rectWND
.right
- rc
->left
;
553 rc
->bottom
= rectWND
.bottom
- rectTB
.bottom
;
556 static BOOL
HH_AddHTMLPane(HHInfo
*pHHInfo
)
559 HWND hwndParent
= pHHInfo
->WinType
.hwndHelp
;
560 DWORD dwStyles
= WS_CHILDWINDOW
| WS_VISIBLE
| WS_CLIPCHILDREN
;
561 DWORD dwExStyles
= WS_EX_LEFT
| WS_EX_LTRREADING
| WS_EX_RIGHTSCROLLBAR
| WS_EX_CLIENTEDGE
;
564 HP_GetHTMLRect(pHHInfo
, &rc
);
566 hWnd
= CreateWindowExW(dwExStyles
, szChildClass
, szEmpty
, dwStyles
,
567 rc
.left
, rc
.top
, rc
.right
, rc
.bottom
,
568 hwndParent
, NULL
, hhctrl_hinstance
, NULL
);
572 if (!InitWebBrowser(pHHInfo
, hWnd
))
575 /* store the pointer to the HH info struct */
576 SetWindowLongPtrW(hWnd
, GWLP_USERDATA
, (LONG_PTR
)pHHInfo
);
578 ShowWindow(hWnd
, SW_SHOW
);
581 pHHInfo
->WinType
.hwndHTML
= hWnd
;
587 static void Help_OnSize(HWND hWnd
)
589 HHInfo
*pHHInfo
= (HHInfo
*)GetWindowLongPtrW(hWnd
, GWLP_USERDATA
);
596 NP_GetNavigationRect(pHHInfo
, &rc
);
597 SetWindowPos(pHHInfo
->WinType
.hwndNavigation
, HWND_TOP
, 0, 0,
598 rc
.right
, rc
.bottom
, SWP_NOMOVE
);
600 GetClientRect(pHHInfo
->WinType
.hwndNavigation
, &rc
);
601 SetWindowPos(pHHInfo
->hwndTabCtrl
, HWND_TOP
, 0, 0,
602 rc
.right
- TAB_RIGHT_PADDING
,
603 rc
.bottom
- TAB_TOP_PADDING
, SWP_NOMOVE
);
605 SB_GetSizeBarRect(pHHInfo
, &rc
);
606 SetWindowPos(pHHInfo
->hwndSizeBar
, HWND_TOP
, rc
.left
, rc
.top
,
607 rc
.right
, rc
.bottom
, SWP_SHOWWINDOW
);
609 HP_GetHTMLRect(pHHInfo
, &rc
);
610 SetWindowPos(pHHInfo
->WinType
.hwndHTML
, HWND_TOP
, rc
.left
, rc
.top
,
611 rc
.right
, rc
.bottom
, SWP_SHOWWINDOW
);
613 /* Resize browser window taking the frame size into account */
614 dwSize
= GetSystemMetrics(SM_CXFRAME
);
615 ResizeWebBrowser(pHHInfo
, rc
.right
- dwSize
, rc
.bottom
- dwSize
);
618 static LRESULT CALLBACK
Help_WndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
626 if (HIWORD(wParam
) == BN_CLICKED
)
627 TB_OnClick(hWnd
, LOWORD(wParam
));
633 hdc
= BeginPaint(hWnd
, &ps
);
641 return DefWindowProcW(hWnd
, message
, wParam
, lParam
);
647 static BOOL
HH_CreateHelpWindow(HHInfo
*info
)
650 RECT winPos
= info
->WinType
.rcWindowPos
;
652 DWORD dwStyles
, dwExStyles
;
653 DWORD x
, y
, width
, height
;
655 static const WCHAR windowClassW
[] = {
656 'H','H',' ', 'P','a','r','e','n','t',0
659 wcex
.cbSize
= sizeof(WNDCLASSEXW
);
660 wcex
.style
= CS_HREDRAW
| CS_VREDRAW
;
661 wcex
.lpfnWndProc
= (WNDPROC
)Help_WndProc
;
664 wcex
.hInstance
= hhctrl_hinstance
;
665 wcex
.hIcon
= LoadIconW(NULL
, (LPCWSTR
)IDI_APPLICATION
);
666 wcex
.hCursor
= LoadCursorW(NULL
, (LPCWSTR
)IDC_ARROW
);
667 wcex
.hbrBackground
= (HBRUSH
)(COLOR_MENU
+ 1);
668 wcex
.lpszMenuName
= NULL
;
669 wcex
.lpszClassName
= windowClassW
;
670 wcex
.hIconSm
= LoadIconW(NULL
, (LPCWSTR
)IDI_APPLICATION
);
672 RegisterClassExW(&wcex
);
674 /* Read in window parameters if available */
675 if (info
->WinType
.fsValidMembers
& HHWIN_PARAM_STYLES
)
676 dwStyles
= info
->WinType
.dwStyles
;
678 dwStyles
= WS_OVERLAPPEDWINDOW
| WS_VISIBLE
|
679 WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
;
681 if (info
->WinType
.fsValidMembers
& HHWIN_PARAM_EXSTYLES
)
682 dwExStyles
= info
->WinType
.dwExStyles
;
684 dwExStyles
= WS_EX_LEFT
| WS_EX_LTRREADING
| WS_EX_APPWINDOW
|
685 WS_EX_WINDOWEDGE
| WS_EX_RIGHTSCROLLBAR
;
687 if (info
->WinType
.fsValidMembers
& HHWIN_PARAM_RECT
)
691 width
= winPos
.right
- x
;
692 height
= winPos
.bottom
- y
;
696 x
= WINTYPE_DEFAULT_X
;
697 y
= WINTYPE_DEFAULT_Y
;
698 width
= WINTYPE_DEFAULT_WIDTH
;
699 height
= WINTYPE_DEFAULT_HEIGHT
;
702 hWnd
= CreateWindowExW(dwExStyles
, windowClassW
, info
->WinType
.pszCaption
,
703 dwStyles
, x
, y
, width
, height
, NULL
, NULL
, hhctrl_hinstance
, NULL
);
707 ShowWindow(hWnd
, SW_SHOW
);
710 /* store the pointer to the HH info struct */
711 SetWindowLongPtrW(hWnd
, GWLP_USERDATA
, (LONG_PTR
)info
);
713 info
->WinType
.hwndHelp
= hWnd
;
717 static void HH_CreateFont(HHInfo
*pHHInfo
)
721 GetObjectW(GetStockObject(ANSI_VAR_FONT
), sizeof(LOGFONTW
), &lf
);
722 lf
.lfWeight
= FW_NORMAL
;
724 lf
.lfUnderline
= FALSE
;
726 pHHInfo
->hFont
= CreateFontIndirectW(&lf
);
729 static void HH_InitRequiredControls(DWORD dwControls
)
731 INITCOMMONCONTROLSEX icex
;
733 icex
.dwSize
= sizeof(INITCOMMONCONTROLSEX
);
734 icex
.dwICC
= dwControls
;
735 InitCommonControlsEx(&icex
);
738 /* Creates the whole package */
739 static BOOL
CreateViewer(HHInfo
*pHHInfo
)
741 HH_CreateFont(pHHInfo
);
743 if (!HH_CreateHelpWindow(pHHInfo
))
746 HH_InitRequiredControls(ICC_BAR_CLASSES
);
748 if (!HH_AddToolbar(pHHInfo
))
751 HH_RegisterChildWndClass(pHHInfo
);
753 if (!HH_AddNavigationPane(pHHInfo
))
756 HH_RegisterSizeBarClass(pHHInfo
);
758 if (!HH_AddSizeBar(pHHInfo
))
761 if (!HH_AddHTMLPane(pHHInfo
))
767 static void ReleaseHelpViewer(HHInfo
*info
)
772 /* Free allocated strings */
773 hhctrl_free((LPWSTR
)info
->WinType
.pszType
);
774 hhctrl_free((LPWSTR
)info
->WinType
.pszCaption
);
775 hhctrl_free((LPWSTR
)info
->WinType
.pszToc
);
776 hhctrl_free((LPWSTR
)info
->WinType
.pszIndex
);
777 hhctrl_free((LPWSTR
)info
->WinType
.pszFile
);
778 hhctrl_free((LPWSTR
)info
->WinType
.pszHome
);
779 hhctrl_free((LPWSTR
)info
->WinType
.pszJump1
);
780 hhctrl_free((LPWSTR
)info
->WinType
.pszJump2
);
781 hhctrl_free((LPWSTR
)info
->WinType
.pszUrlJump1
);
782 hhctrl_free((LPWSTR
)info
->WinType
.pszUrlJump2
);
785 CloseCHM(info
->pCHMInfo
);
787 ReleaseWebBrowser(info
);
793 static HHInfo
*CreateHelpViewer(LPCWSTR filename
)
795 HHInfo
*info
= hhctrl_alloc_zero(sizeof(HHInfo
));
799 info
->pCHMInfo
= OpenCHM(filename
);
800 if(!info
->pCHMInfo
) {
801 ReleaseHelpViewer(info
);
805 if (!LoadWinTypeFromCHM(info
->pCHMInfo
, &info
->WinType
)) {
806 ReleaseHelpViewer(info
);
810 if(!CreateViewer(info
)) {
811 ReleaseHelpViewer(info
);
818 /* FIXME: Check szCmdLine for bad arguments */
819 int WINAPI
doWinMain(HINSTANCE hInstance
, LPSTR szCmdLine
)
823 LPWSTR filename
= strdupAtoW(szCmdLine
);
825 info
= CreateHelpViewer(filename
);
826 hhctrl_free(filename
);
830 NavigateToChm(info
, info
->pCHMInfo
->szFile
, info
->WinType
.pszFile
);
832 while (GetMessageW(&msg
, 0, 0, 0))
834 TranslateMessage(&msg
);
835 DispatchMessageW(&msg
);
838 ReleaseHelpViewer(info
);