2 * Help Viewer Implementation
4 * Copyright 2005 James Hawkins
5 * Copyright 2007 Jacek Caban for CodeWeavers
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
28 #include "wine/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(htmlhelp
);
34 static LRESULT
Help_OnSize(HWND hWnd
);
36 /* Window type defaults */
38 #define WINTYPE_DEFAULT_X 280
39 #define WINTYPE_DEFAULT_Y 100
40 #define WINTYPE_DEFAULT_WIDTH 740
41 #define WINTYPE_DEFAULT_HEIGHT 640
42 #define WINTYPE_DEFAULT_NAVWIDTH 250
44 #define TAB_TOP_PADDING 8
45 #define TAB_RIGHT_PADDING 4
48 static const WCHAR szEmpty
[] = {0};
50 /* Loads a string from the resource file */
51 static LPWSTR
HH_LoadString(DWORD dwID
)
56 iSize
= LoadStringW(hhctrl_hinstance
, dwID
, NULL
, 0);
57 iSize
+= 2; /* some strings (tab text) needs double-null termination */
59 string
= hhctrl_alloc(iSize
* sizeof(WCHAR
));
60 LoadStringW(hhctrl_hinstance
, dwID
, string
, iSize
);
65 BOOL
NavigateToUrl(HHInfo
*info
, LPCWSTR surl
)
71 V_BSTR(&url
) = SysAllocString(surl
);
73 hres
= IWebBrowser2_Navigate2(info
->web_browser
, &url
, 0, 0, 0, 0);
77 return SUCCEEDED(hres
);
80 BOOL
NavigateToChm(HHInfo
*info
, LPCWSTR file
, LPCWSTR index
)
82 WCHAR buf
[INTERNET_MAX_URL_LENGTH
];
83 WCHAR full_path
[MAX_PATH
];
86 static const WCHAR url_format
[] =
87 {'m','k',':','@','M','S','I','T','S','t','o','r','e',':','%','s',':',':','/','%','s',0};
89 TRACE("%p %s %s\n", info
, debugstr_w(file
), debugstr_w(index
));
91 if (!info
->web_browser
)
94 if(!GetFullPathNameW(file
, sizeof(full_path
), full_path
, NULL
)) {
95 WARN("GetFullPathName failed: %u\n", GetLastError());
99 wsprintfW(buf
, url_format
, full_path
, index
);
102 if((ptr
= strchrW(buf
, '#')))
105 return NavigateToUrl(info
, buf
);
110 #define SIZEBAR_WIDTH 4
112 static const WCHAR szSizeBarClass
[] = {
113 'H','H',' ','S','i','z','e','B','a','r',0
116 /* Draw the SizeBar */
117 static void SB_OnPaint(HWND hWnd
)
123 hdc
= BeginPaint(hWnd
, &ps
);
125 GetClientRect(hWnd
, &rc
);
130 FrameRect(hdc
, &rc
, GetStockObject(GRAY_BRUSH
));
132 /* white highlight */
133 SelectObject(hdc
, GetStockObject(WHITE_PEN
));
134 MoveToEx(hdc
, rc
.right
, 1, NULL
);
136 LineTo(hdc
, 1, rc
.bottom
- 1);
139 MoveToEx(hdc
, 0, rc
.bottom
, NULL
);
140 LineTo(hdc
, rc
.right
, rc
.bottom
);
145 static void SB_OnLButtonDown(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
150 static void SB_OnLButtonUp(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
152 HHInfo
*pHHInfo
= (HHInfo
*)GetWindowLongPtrW(hWnd
, GWLP_USERDATA
);
155 pt
.x
= (short)LOWORD(lParam
);
156 pt
.y
= (short)HIWORD(lParam
);
158 /* update the window sizes */
159 pHHInfo
->WinType
.iNavWidth
+= pt
.x
;
165 static void SB_OnMouseMove(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
167 /* ignore WM_MOUSEMOVE if not dragging the SizeBar */
168 if (!(wParam
& MK_LBUTTON
))
172 static LRESULT CALLBACK
SizeBar_WndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
177 SB_OnLButtonDown(hWnd
, wParam
, lParam
);
180 SB_OnLButtonUp(hWnd
, wParam
, lParam
);
183 SB_OnMouseMove(hWnd
, wParam
, lParam
);
189 return DefWindowProcW(hWnd
, message
, wParam
, lParam
);
195 static void HH_RegisterSizeBarClass(HHInfo
*pHHInfo
)
199 wcex
.cbSize
= sizeof(WNDCLASSEXW
);
201 wcex
.lpfnWndProc
= SizeBar_WndProc
;
204 wcex
.hInstance
= hhctrl_hinstance
;
205 wcex
.hIcon
= LoadIconW(NULL
, (LPCWSTR
)IDI_APPLICATION
);
206 wcex
.hCursor
= LoadCursorW(NULL
, (LPCWSTR
)IDC_SIZEWE
);
207 wcex
.hbrBackground
= (HBRUSH
)(COLOR_MENU
+ 1);
208 wcex
.lpszMenuName
= NULL
;
209 wcex
.lpszClassName
= szSizeBarClass
;
210 wcex
.hIconSm
= LoadIconW(NULL
, (LPCWSTR
)IDI_APPLICATION
);
212 RegisterClassExW(&wcex
);
215 static void SB_GetSizeBarRect(HHInfo
*info
, RECT
*rc
)
217 RECT rectWND
, rectTB
, rectNP
;
219 GetClientRect(info
->WinType
.hwndHelp
, &rectWND
);
220 GetClientRect(info
->WinType
.hwndToolBar
, &rectTB
);
221 GetClientRect(info
->WinType
.hwndNavigation
, &rectNP
);
223 rc
->left
= rectNP
.right
;
224 rc
->top
= rectTB
.bottom
;
225 rc
->bottom
= rectWND
.bottom
- rectTB
.bottom
;
226 rc
->right
= SIZEBAR_WIDTH
;
229 static BOOL
HH_AddSizeBar(HHInfo
*pHHInfo
)
232 HWND hwndParent
= pHHInfo
->WinType
.hwndHelp
;
233 DWORD dwStyles
= WS_CHILDWINDOW
| WS_VISIBLE
| WS_OVERLAPPED
;
234 DWORD dwExStyles
= WS_EX_LEFT
| WS_EX_LTRREADING
| WS_EX_RIGHTSCROLLBAR
;
237 SB_GetSizeBarRect(pHHInfo
, &rc
);
239 hWnd
= CreateWindowExW(dwExStyles
, szSizeBarClass
, szEmpty
, dwStyles
,
240 rc
.left
, rc
.top
, rc
.right
, rc
.bottom
,
241 hwndParent
, NULL
, hhctrl_hinstance
, NULL
);
245 /* store the pointer to the HH info struct */
246 SetWindowLongPtrW(hWnd
, GWLP_USERDATA
, (LONG_PTR
)pHHInfo
);
248 pHHInfo
->hwndSizeBar
= hWnd
;
254 static const WCHAR szChildClass
[] = {
255 'H','H',' ','C','h','i','l','d',0
258 static LRESULT
Child_OnPaint(HWND hWnd
)
264 hdc
= BeginPaint(hWnd
, &ps
);
266 /* Only paint the Navigation pane, identified by the fact
267 * that it has a child window
269 if (GetWindow(hWnd
, GW_CHILD
))
271 GetClientRect(hWnd
, &rc
);
273 /* set the border color */
274 SelectObject(hdc
, GetStockObject(DC_PEN
));
275 SetDCPenColor(hdc
, GetSysColor(COLOR_BTNSHADOW
));
277 /* Draw the top border */
278 LineTo(hdc
, rc
.right
, 0);
280 SelectObject(hdc
, GetStockObject(WHITE_PEN
));
281 MoveToEx(hdc
, 0, 1, NULL
);
282 LineTo(hdc
, rc
.right
, 1);
290 static void ResizeTabChild(HHInfo
*info
, HWND hwnd
)
295 GetClientRect(info
->WinType
.hwndNavigation
, &rect
);
296 SendMessageW(info
->hwndTabCtrl
, TCM_GETITEMRECT
, 0, (LPARAM
)&tabrc
);
297 cnt
= SendMessageW(info
->hwndTabCtrl
, TCM_GETROWCOUNT
, 0, 0);
299 rect
.left
= TAB_MARGIN
;
300 rect
.top
= TAB_TOP_PADDING
+ cnt
*(tabrc
.bottom
-tabrc
.top
) + TAB_MARGIN
;
301 rect
.right
-= TAB_RIGHT_PADDING
+ TAB_MARGIN
;
302 rect
.bottom
-= TAB_MARGIN
;
304 SetWindowPos(hwnd
, NULL
, rect
.left
, rect
.top
, rect
.right
-rect
.left
,
305 rect
.bottom
-rect
.top
, SWP_NOZORDER
| SWP_NOACTIVATE
);
308 static LRESULT
Child_OnSize(HWND hwnd
)
310 HHInfo
*info
= (HHInfo
*)GetWindowLongPtrW(hwnd
, GWLP_USERDATA
);
313 if(!info
|| hwnd
!= info
->WinType
.hwndNavigation
)
316 GetClientRect(hwnd
, &rect
);
317 SetWindowPos(info
->hwndTabCtrl
, HWND_TOP
, 0, 0,
318 rect
.right
- TAB_RIGHT_PADDING
,
319 rect
.bottom
- TAB_TOP_PADDING
, SWP_NOMOVE
);
321 ResizeTabChild(info
, info
->tabs
[TAB_CONTENTS
].hwnd
);
325 static LRESULT
OnTabChange(HWND hwnd
)
327 HHInfo
*info
= (HHInfo
*)GetWindowLongPtrW(hwnd
, GWLP_USERDATA
);
334 if(info
->tabs
[info
->current_tab
].hwnd
)
335 ShowWindow(info
->tabs
[info
->current_tab
].hwnd
, SW_HIDE
);
337 info
->current_tab
= SendMessageW(info
->hwndTabCtrl
, TCM_GETCURSEL
, 0, 0);
339 if(info
->tabs
[info
->current_tab
].hwnd
)
340 ShowWindow(info
->tabs
[info
->current_tab
].hwnd
, SW_SHOW
);
345 static LRESULT
OnTopicChange(HWND hwnd
, ContentItem
*item
)
347 HHInfo
*info
= (HHInfo
*)GetWindowLongPtrW(hwnd
, GWLP_USERDATA
);
348 LPCWSTR chmfile
= NULL
;
349 ContentItem
*iter
= item
;
354 TRACE("name %s loal %s\n", debugstr_w(item
->name
), debugstr_w(item
->local
));
357 if(iter
->merge
.chm_file
) {
358 chmfile
= iter
->merge
.chm_file
;
364 NavigateToChm(info
, chmfile
, item
->local
);
368 static LRESULT CALLBACK
Child_WndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
373 return Child_OnPaint(hWnd
);
375 return Child_OnSize(hWnd
);
377 NMHDR
*nmhdr
= (NMHDR
*)lParam
;
378 switch(nmhdr
->code
) {
380 return OnTabChange(hWnd
);
381 case TVN_SELCHANGEDW
:
382 return OnTopicChange(hWnd
, (ContentItem
*)((NMTREEVIEWW
*)lParam
)->itemNew
.lParam
);
387 return DefWindowProcW(hWnd
, message
, wParam
, lParam
);
393 static void HH_RegisterChildWndClass(HHInfo
*pHHInfo
)
397 wcex
.cbSize
= sizeof(WNDCLASSEXW
);
399 wcex
.lpfnWndProc
= Child_WndProc
;
402 wcex
.hInstance
= hhctrl_hinstance
;
403 wcex
.hIcon
= LoadIconW(NULL
, (LPCWSTR
)IDI_APPLICATION
);
404 wcex
.hCursor
= LoadCursorW(NULL
, (LPCWSTR
)IDC_ARROW
);
405 wcex
.hbrBackground
= (HBRUSH
)(COLOR_BTNFACE
+ 1);
406 wcex
.lpszMenuName
= NULL
;
407 wcex
.lpszClassName
= szChildClass
;
408 wcex
.hIconSm
= LoadIconW(NULL
, (LPCWSTR
)IDI_APPLICATION
);
410 RegisterClassExW(&wcex
);
417 static void TB_OnClick(HWND hWnd
, DWORD dwID
)
419 HHInfo
*info
= (HHInfo
*)GetWindowLongPtrW(hWnd
, GWLP_USERDATA
);
424 DoPageAction(info
, WB_STOP
);
427 DoPageAction(info
, WB_REFRESH
);
430 DoPageAction(info
, WB_GOBACK
);
433 NavigateToChm(info
, info
->pCHMInfo
->szFile
, info
->WinType
.pszHome
);
436 DoPageAction(info
, WB_GOFORWARD
);
443 case IDTB_BROWSE_FWD
:
444 case IDTB_BROWSE_BACK
:
455 static void TB_AddButton(TBBUTTON
*pButtons
, DWORD dwIndex
, DWORD dwID
)
457 /* FIXME: Load the correct button bitmaps */
458 pButtons
[dwIndex
].iBitmap
= STD_PRINT
;
459 pButtons
[dwIndex
].idCommand
= dwID
;
460 pButtons
[dwIndex
].fsState
= TBSTATE_ENABLED
;
461 pButtons
[dwIndex
].fsStyle
= BTNS_BUTTON
;
462 pButtons
[dwIndex
].dwData
= 0;
463 pButtons
[dwIndex
].iString
= 0;
466 static void TB_AddButtonsFromFlags(TBBUTTON
*pButtons
, DWORD dwButtonFlags
, LPDWORD pdwNumButtons
)
470 if (dwButtonFlags
& HHWIN_BUTTON_EXPAND
)
471 TB_AddButton(pButtons
, (*pdwNumButtons
)++, IDTB_EXPAND
);
473 if (dwButtonFlags
& HHWIN_BUTTON_BACK
)
474 TB_AddButton(pButtons
, (*pdwNumButtons
)++, IDTB_BACK
);
476 if (dwButtonFlags
& HHWIN_BUTTON_FORWARD
)
477 TB_AddButton(pButtons
, (*pdwNumButtons
)++, IDTB_FORWARD
);
479 if (dwButtonFlags
& HHWIN_BUTTON_STOP
)
480 TB_AddButton(pButtons
, (*pdwNumButtons
)++, IDTB_STOP
);
482 if (dwButtonFlags
& HHWIN_BUTTON_REFRESH
)
483 TB_AddButton(pButtons
, (*pdwNumButtons
)++, IDTB_REFRESH
);
485 if (dwButtonFlags
& HHWIN_BUTTON_HOME
)
486 TB_AddButton(pButtons
, (*pdwNumButtons
)++, IDTB_HOME
);
488 if (dwButtonFlags
& HHWIN_BUTTON_SYNC
)
489 TB_AddButton(pButtons
, (*pdwNumButtons
)++, IDTB_SYNC
);
491 if (dwButtonFlags
& HHWIN_BUTTON_OPTIONS
)
492 TB_AddButton(pButtons
, (*pdwNumButtons
)++, IDTB_OPTIONS
);
494 if (dwButtonFlags
& HHWIN_BUTTON_PRINT
)
495 TB_AddButton(pButtons
, (*pdwNumButtons
)++, IDTB_PRINT
);
497 if (dwButtonFlags
& HHWIN_BUTTON_JUMP1
)
498 TB_AddButton(pButtons
, (*pdwNumButtons
)++, IDTB_JUMP1
);
500 if (dwButtonFlags
& HHWIN_BUTTON_JUMP2
)
501 TB_AddButton(pButtons
,(*pdwNumButtons
)++, IDTB_JUMP2
);
503 if (dwButtonFlags
& HHWIN_BUTTON_ZOOM
)
504 TB_AddButton(pButtons
, (*pdwNumButtons
)++, IDTB_ZOOM
);
506 if (dwButtonFlags
& HHWIN_BUTTON_TOC_NEXT
)
507 TB_AddButton(pButtons
, (*pdwNumButtons
)++, IDTB_TOC_NEXT
);
509 if (dwButtonFlags
& HHWIN_BUTTON_TOC_PREV
)
510 TB_AddButton(pButtons
, (*pdwNumButtons
)++, IDTB_TOC_PREV
);
513 static BOOL
HH_AddToolbar(HHInfo
*pHHInfo
)
516 HWND hwndParent
= pHHInfo
->WinType
.hwndHelp
;
518 TBBUTTON buttons
[IDTB_TOC_PREV
- IDTB_EXPAND
];
520 DWORD dwStyles
, dwExStyles
;
521 DWORD dwNumButtons
, dwIndex
;
523 if (pHHInfo
->WinType
.fsWinProperties
& HHWIN_PARAM_TB_FLAGS
)
524 toolbarFlags
= pHHInfo
->WinType
.fsToolBarFlags
;
526 toolbarFlags
= HHWIN_DEF_BUTTONS
;
528 TB_AddButtonsFromFlags(buttons
, toolbarFlags
, &dwNumButtons
);
530 dwStyles
= WS_CHILDWINDOW
| WS_VISIBLE
| TBSTYLE_FLAT
|
531 TBSTYLE_WRAPABLE
| TBSTYLE_TOOLTIPS
| CCS_NODIVIDER
;
532 dwExStyles
= WS_EX_LEFT
| WS_EX_LTRREADING
| WS_EX_RIGHTSCROLLBAR
;
534 hToolbar
= CreateWindowExW(dwExStyles
, TOOLBARCLASSNAMEW
, NULL
, dwStyles
,
535 0, 0, 0, 0, hwndParent
, NULL
,
536 hhctrl_hinstance
, NULL
);
540 SendMessageW(hToolbar
, TB_SETBITMAPSIZE
, 0, MAKELONG(ICON_SIZE
, ICON_SIZE
));
541 SendMessageW(hToolbar
, TB_BUTTONSTRUCTSIZE
, sizeof(TBBUTTON
), 0);
542 SendMessageW(hToolbar
, WM_SETFONT
, (WPARAM
)pHHInfo
->hFont
, TRUE
);
544 /* FIXME: Load correct icons for all buttons */
545 tbAB
.hInst
= HINST_COMMCTRL
;
546 tbAB
.nID
= IDB_STD_LARGE_COLOR
;
547 SendMessageW(hToolbar
, TB_ADDBITMAP
, 0, (LPARAM
)&tbAB
);
549 for (dwIndex
= 0; dwIndex
< dwNumButtons
; dwIndex
++)
551 LPWSTR szBuf
= HH_LoadString(buttons
[dwIndex
].idCommand
);
552 DWORD dwLen
= strlenW(szBuf
);
553 szBuf
[dwLen
+ 2] = 0; /* Double-null terminate */
555 buttons
[dwIndex
].iString
= (DWORD
)SendMessageW(hToolbar
, TB_ADDSTRINGW
, 0, (LPARAM
)szBuf
);
559 SendMessageW(hToolbar
, TB_ADDBUTTONSW
, dwNumButtons
, (LPARAM
)&buttons
);
560 SendMessageW(hToolbar
, TB_AUTOSIZE
, 0, 0);
561 ShowWindow(hToolbar
, SW_SHOW
);
563 pHHInfo
->WinType
.hwndToolBar
= hToolbar
;
567 /* Navigation Pane */
569 static void NP_GetNavigationRect(HHInfo
*pHHInfo
, RECT
*rc
)
571 HWND hwndParent
= pHHInfo
->WinType
.hwndHelp
;
572 HWND hwndToolbar
= pHHInfo
->WinType
.hwndToolBar
;
573 RECT rectWND
, rectTB
;
575 GetClientRect(hwndParent
, &rectWND
);
576 GetClientRect(hwndToolbar
, &rectTB
);
579 rc
->top
= rectTB
.bottom
;
580 rc
->bottom
= rectWND
.bottom
- rectTB
.bottom
;
582 if (!(pHHInfo
->WinType
.fsValidMembers
& HHWIN_PARAM_NAV_WIDTH
) &&
583 pHHInfo
->WinType
.iNavWidth
== 0)
585 pHHInfo
->WinType
.iNavWidth
= WINTYPE_DEFAULT_NAVWIDTH
;
588 rc
->right
= pHHInfo
->WinType
.iNavWidth
;
591 static DWORD
NP_CreateTab(HINSTANCE hInstance
, HWND hwndTabCtrl
, DWORD index
)
594 LPWSTR tabText
= HH_LoadString(index
);
597 tie
.mask
= TCIF_TEXT
;
598 tie
.pszText
= tabText
;
600 ret
= SendMessageW( hwndTabCtrl
, TCM_INSERTITEMW
, index
, (LPARAM
)&tie
);
602 hhctrl_free(tabText
);
606 static BOOL
HH_AddNavigationPane(HHInfo
*info
)
608 HWND hWnd
, hwndTabCtrl
;
609 HWND hwndParent
= info
->WinType
.hwndHelp
;
610 DWORD dwStyles
= WS_CHILDWINDOW
| WS_VISIBLE
;
611 DWORD dwExStyles
= WS_EX_LEFT
| WS_EX_LTRREADING
| WS_EX_RIGHTSCROLLBAR
;
614 NP_GetNavigationRect(info
, &rc
);
616 hWnd
= CreateWindowExW(dwExStyles
, szChildClass
, szEmpty
, dwStyles
,
617 rc
.left
, rc
.top
, rc
.right
, rc
.bottom
,
618 hwndParent
, NULL
, hhctrl_hinstance
, NULL
);
622 SetWindowLongPtrW(hWnd
, GWLP_USERDATA
, (LONG_PTR
)info
);
624 hwndTabCtrl
= CreateWindowExW(dwExStyles
, WC_TABCONTROLW
, szEmpty
, dwStyles
,
626 rc
.right
- TAB_RIGHT_PADDING
,
627 rc
.bottom
- TAB_TOP_PADDING
,
628 hWnd
, NULL
, hhctrl_hinstance
, NULL
);
632 if (*info
->WinType
.pszToc
)
633 info
->tabs
[TAB_CONTENTS
].id
= NP_CreateTab(hhctrl_hinstance
, hwndTabCtrl
, IDS_CONTENTS
);
635 if (*info
->WinType
.pszIndex
)
636 info
->tabs
[TAB_INDEX
].id
= NP_CreateTab(hhctrl_hinstance
, hwndTabCtrl
, IDS_INDEX
);
638 if (info
->WinType
.fsWinProperties
& HHWIN_PROP_TAB_SEARCH
)
639 info
->tabs
[TAB_SEARCH
].id
= NP_CreateTab(hhctrl_hinstance
, hwndTabCtrl
, IDS_SEARCH
);
641 if (info
->WinType
.fsWinProperties
& HHWIN_PROP_TAB_FAVORITES
)
642 info
->tabs
[TAB_FAVORITES
].id
= NP_CreateTab(hhctrl_hinstance
, hwndTabCtrl
, IDS_FAVORITES
);
644 SendMessageW(hwndTabCtrl
, WM_SETFONT
, (WPARAM
)info
->hFont
, TRUE
);
646 info
->hwndTabCtrl
= hwndTabCtrl
;
647 info
->WinType
.hwndNavigation
= hWnd
;
653 static void HP_GetHTMLRect(HHInfo
*info
, RECT
*rc
)
655 RECT rectTB
, rectWND
, rectNP
, rectSB
;
657 GetClientRect(info
->WinType
.hwndHelp
, &rectWND
);
658 GetClientRect(info
->WinType
.hwndToolBar
, &rectTB
);
659 GetClientRect(info
->WinType
.hwndNavigation
, &rectNP
);
660 GetClientRect(info
->hwndSizeBar
, &rectSB
);
662 rc
->left
= rectNP
.right
+ rectSB
.right
;
663 rc
->top
= rectTB
.bottom
;
664 rc
->right
= rectWND
.right
- rc
->left
;
665 rc
->bottom
= rectWND
.bottom
- rectTB
.bottom
;
668 static BOOL
HH_AddHTMLPane(HHInfo
*pHHInfo
)
671 HWND hwndParent
= pHHInfo
->WinType
.hwndHelp
;
672 DWORD dwStyles
= WS_CHILDWINDOW
| WS_VISIBLE
| WS_CLIPCHILDREN
;
673 DWORD dwExStyles
= WS_EX_LEFT
| WS_EX_LTRREADING
| WS_EX_RIGHTSCROLLBAR
| WS_EX_CLIENTEDGE
;
676 HP_GetHTMLRect(pHHInfo
, &rc
);
678 hWnd
= CreateWindowExW(dwExStyles
, szChildClass
, szEmpty
, dwStyles
,
679 rc
.left
, rc
.top
, rc
.right
, rc
.bottom
,
680 hwndParent
, NULL
, hhctrl_hinstance
, NULL
);
684 if (!InitWebBrowser(pHHInfo
, hWnd
))
687 /* store the pointer to the HH info struct */
688 SetWindowLongPtrW(hWnd
, GWLP_USERDATA
, (LONG_PTR
)pHHInfo
);
690 ShowWindow(hWnd
, SW_SHOW
);
693 pHHInfo
->WinType
.hwndHTML
= hWnd
;
697 static BOOL
AddContentTab(HHInfo
*info
)
699 info
->tabs
[TAB_CONTENTS
].hwnd
= CreateWindowExW(WS_EX_CLIENTEDGE
, WC_TREEVIEWW
,
700 szEmpty
, WS_CHILD
| WS_BORDER
| 0x25, 50, 50, 100, 100,
701 info
->WinType
.hwndNavigation
, NULL
, hhctrl_hinstance
, NULL
);
702 if(!info
->tabs
[TAB_CONTENTS
].hwnd
) {
703 ERR("Could not create treeview control\n");
707 ResizeTabChild(info
, info
->tabs
[TAB_CONTENTS
].hwnd
);
708 ShowWindow(info
->tabs
[TAB_CONTENTS
].hwnd
, SW_SHOW
);
715 static LRESULT
Help_OnSize(HWND hWnd
)
717 HHInfo
*pHHInfo
= (HHInfo
*)GetWindowLongPtrW(hWnd
, GWLP_USERDATA
);
724 NP_GetNavigationRect(pHHInfo
, &rc
);
725 SetWindowPos(pHHInfo
->WinType
.hwndNavigation
, HWND_TOP
, 0, 0,
726 rc
.right
, rc
.bottom
, SWP_NOMOVE
);
728 SB_GetSizeBarRect(pHHInfo
, &rc
);
729 SetWindowPos(pHHInfo
->hwndSizeBar
, HWND_TOP
, rc
.left
, rc
.top
,
730 rc
.right
, rc
.bottom
, SWP_SHOWWINDOW
);
732 HP_GetHTMLRect(pHHInfo
, &rc
);
733 SetWindowPos(pHHInfo
->WinType
.hwndHTML
, HWND_TOP
, rc
.left
, rc
.top
,
734 rc
.right
, rc
.bottom
, SWP_SHOWWINDOW
);
736 /* Resize browser window taking the frame size into account */
737 dwSize
= GetSystemMetrics(SM_CXFRAME
);
738 ResizeWebBrowser(pHHInfo
, rc
.right
- dwSize
, rc
.bottom
- dwSize
);
743 static LRESULT CALLBACK
Help_WndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
748 if (HIWORD(wParam
) == BN_CLICKED
)
749 TB_OnClick(hWnd
, LOWORD(wParam
));
752 return Help_OnSize(hWnd
);
754 ReleaseHelpViewer((HHInfo
*)GetWindowLongPtrW(hWnd
, GWLP_USERDATA
));
762 return DefWindowProcW(hWnd
, message
, wParam
, lParam
);
768 static BOOL
HH_CreateHelpWindow(HHInfo
*info
)
771 RECT winPos
= info
->WinType
.rcWindowPos
;
773 DWORD dwStyles
, dwExStyles
;
774 DWORD x
, y
, width
, height
;
776 static const WCHAR windowClassW
[] = {
777 'H','H',' ', 'P','a','r','e','n','t',0
780 wcex
.cbSize
= sizeof(WNDCLASSEXW
);
781 wcex
.style
= CS_HREDRAW
| CS_VREDRAW
;
782 wcex
.lpfnWndProc
= Help_WndProc
;
785 wcex
.hInstance
= hhctrl_hinstance
;
786 wcex
.hIcon
= LoadIconW(NULL
, (LPCWSTR
)IDI_APPLICATION
);
787 wcex
.hCursor
= LoadCursorW(NULL
, (LPCWSTR
)IDC_ARROW
);
788 wcex
.hbrBackground
= (HBRUSH
)(COLOR_MENU
+ 1);
789 wcex
.lpszMenuName
= NULL
;
790 wcex
.lpszClassName
= windowClassW
;
791 wcex
.hIconSm
= LoadIconW(NULL
, (LPCWSTR
)IDI_APPLICATION
);
793 RegisterClassExW(&wcex
);
795 /* Read in window parameters if available */
796 if (info
->WinType
.fsValidMembers
& HHWIN_PARAM_STYLES
)
797 dwStyles
= info
->WinType
.dwStyles
;
799 dwStyles
= WS_OVERLAPPEDWINDOW
| WS_VISIBLE
|
800 WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
;
802 if (info
->WinType
.fsValidMembers
& HHWIN_PARAM_EXSTYLES
)
803 dwExStyles
= info
->WinType
.dwExStyles
;
805 dwExStyles
= WS_EX_LEFT
| WS_EX_LTRREADING
| WS_EX_APPWINDOW
|
806 WS_EX_WINDOWEDGE
| WS_EX_RIGHTSCROLLBAR
;
808 if (info
->WinType
.fsValidMembers
& HHWIN_PARAM_RECT
)
812 width
= winPos
.right
- x
;
813 height
= winPos
.bottom
- y
;
817 x
= WINTYPE_DEFAULT_X
;
818 y
= WINTYPE_DEFAULT_Y
;
819 width
= WINTYPE_DEFAULT_WIDTH
;
820 height
= WINTYPE_DEFAULT_HEIGHT
;
823 hWnd
= CreateWindowExW(dwExStyles
, windowClassW
, info
->WinType
.pszCaption
,
824 dwStyles
, x
, y
, width
, height
, NULL
, NULL
, hhctrl_hinstance
, NULL
);
828 ShowWindow(hWnd
, SW_SHOW
);
831 /* store the pointer to the HH info struct */
832 SetWindowLongPtrW(hWnd
, GWLP_USERDATA
, (LONG_PTR
)info
);
834 info
->WinType
.hwndHelp
= hWnd
;
838 static void HH_CreateFont(HHInfo
*pHHInfo
)
842 GetObjectW(GetStockObject(ANSI_VAR_FONT
), sizeof(LOGFONTW
), &lf
);
843 lf
.lfWeight
= FW_NORMAL
;
845 lf
.lfUnderline
= FALSE
;
847 pHHInfo
->hFont
= CreateFontIndirectW(&lf
);
850 static void HH_InitRequiredControls(DWORD dwControls
)
852 INITCOMMONCONTROLSEX icex
;
854 icex
.dwSize
= sizeof(INITCOMMONCONTROLSEX
);
855 icex
.dwICC
= dwControls
;
856 InitCommonControlsEx(&icex
);
859 /* Creates the whole package */
860 static BOOL
CreateViewer(HHInfo
*pHHInfo
)
862 HH_CreateFont(pHHInfo
);
864 if (!HH_CreateHelpWindow(pHHInfo
))
867 HH_InitRequiredControls(ICC_BAR_CLASSES
);
869 if (!HH_AddToolbar(pHHInfo
))
872 HH_RegisterChildWndClass(pHHInfo
);
874 if (!HH_AddNavigationPane(pHHInfo
))
877 HH_RegisterSizeBarClass(pHHInfo
);
879 if (!HH_AddSizeBar(pHHInfo
))
882 if (!HH_AddHTMLPane(pHHInfo
))
885 if (!AddContentTab(pHHInfo
))
888 InitContent(pHHInfo
);
893 void ReleaseHelpViewer(HHInfo
*info
)
898 /* Free allocated strings */
899 hhctrl_free((LPWSTR
)info
->WinType
.pszType
);
900 hhctrl_free((LPWSTR
)info
->WinType
.pszCaption
);
901 hhctrl_free((LPWSTR
)info
->WinType
.pszToc
);
902 hhctrl_free((LPWSTR
)info
->WinType
.pszIndex
);
903 hhctrl_free((LPWSTR
)info
->WinType
.pszFile
);
904 hhctrl_free((LPWSTR
)info
->WinType
.pszHome
);
905 hhctrl_free((LPWSTR
)info
->WinType
.pszJump1
);
906 hhctrl_free((LPWSTR
)info
->WinType
.pszJump2
);
907 hhctrl_free((LPWSTR
)info
->WinType
.pszUrlJump1
);
908 hhctrl_free((LPWSTR
)info
->WinType
.pszUrlJump2
);
911 CloseCHM(info
->pCHMInfo
);
913 ReleaseWebBrowser(info
);
914 ReleaseContent(info
);
916 if(info
->WinType
.hwndHelp
)
917 DestroyWindow(info
->WinType
.hwndHelp
);
923 HHInfo
*CreateHelpViewer(LPCWSTR filename
)
925 HHInfo
*info
= hhctrl_alloc_zero(sizeof(HHInfo
));
929 info
->pCHMInfo
= OpenCHM(filename
);
930 if(!info
->pCHMInfo
) {
931 ReleaseHelpViewer(info
);
935 if (!LoadWinTypeFromCHM(info
->pCHMInfo
, &info
->WinType
)) {
936 ReleaseHelpViewer(info
);
940 if(!CreateViewer(info
)) {
941 ReleaseHelpViewer(info
);