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"
33 /* Window type defaults */
35 #define WINTYPE_DEFAULT_X 280
36 #define WINTYPE_DEFAULT_Y 100
37 #define WINTYPE_DEFAULT_WIDTH 740
38 #define WINTYPE_DEFAULT_HEIGHT 640
40 typedef struct tagHHInfo
42 HH_WINTYPEW *pHHWinType;
49 extern HINSTANCE hhctrl_hinstance;
51 static LPWSTR HH_ANSIToUnicode(LPCSTR ansi)
56 count = MultiByteToWideChar(CP_ACP, 0, ansi, -1, NULL, 0);
57 unicode = HeapAlloc(GetProcessHeap(), 0, count * sizeof(WCHAR));
58 MultiByteToWideChar(CP_ACP, 0, ansi, -1, unicode, count);
63 /* Loads a string from the resource file */
64 static LPWSTR HH_LoadString(DWORD dwID)
69 iSize = LoadStringW(hhctrl_hinstance, dwID, NULL, 0);
70 iSize += 2; /* some strings (tab text) needs double-null termination */
72 string = HeapAlloc(GetProcessHeap(), 0, iSize * sizeof(WCHAR));
73 LoadStringW(hhctrl_hinstance, dwID, string, iSize);
82 static void TB_AddButton(TBBUTTON *pButtons, DWORD dwIndex, DWORD dwID)
84 /* FIXME: Load the correct button bitmaps */
85 pButtons[dwIndex].iBitmap = STD_PRINT;
86 pButtons[dwIndex].idCommand = dwID;
87 pButtons[dwIndex].fsState = TBSTATE_ENABLED;
88 pButtons[dwIndex].fsStyle = BTNS_BUTTON;
89 pButtons[dwIndex].dwData = 0;
90 pButtons[dwIndex].iString = 0;
93 static void TB_AddButtonsFromFlags(TBBUTTON *pButtons, DWORD dwButtonFlags, LPDWORD pdwNumButtons)
97 if (dwButtonFlags & HHWIN_BUTTON_EXPAND)
98 TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_EXPAND);
100 if (dwButtonFlags & HHWIN_BUTTON_BACK)
101 TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_BACK);
103 if (dwButtonFlags & HHWIN_BUTTON_FORWARD)
104 TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_FORWARD);
106 if (dwButtonFlags & HHWIN_BUTTON_STOP)
107 TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_STOP);
109 if (dwButtonFlags & HHWIN_BUTTON_REFRESH)
110 TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_REFRESH);
112 if (dwButtonFlags & HHWIN_BUTTON_HOME)
113 TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_HOME);
115 if (dwButtonFlags & HHWIN_BUTTON_SYNC)
116 TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_SYNC);
118 if (dwButtonFlags & HHWIN_BUTTON_OPTIONS)
119 TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_OPTIONS);
121 if (dwButtonFlags & HHWIN_BUTTON_PRINT)
122 TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_PRINT);
124 if (dwButtonFlags & HHWIN_BUTTON_JUMP1)
125 TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_JUMP1);
127 if (dwButtonFlags & HHWIN_BUTTON_JUMP2)
128 TB_AddButton(pButtons,(*pdwNumButtons)++, IDTB_JUMP2);
130 if (dwButtonFlags & HHWIN_BUTTON_ZOOM)
131 TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_ZOOM);
133 if (dwButtonFlags & HHWIN_BUTTON_TOC_NEXT)
134 TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_TOC_NEXT);
136 if (dwButtonFlags & HHWIN_BUTTON_TOC_PREV)
137 TB_AddButton(pButtons, (*pdwNumButtons)++, IDTB_TOC_PREV);
140 static BOOL HH_AddToolbar(HHInfo *pHHInfo)
143 HWND hwndParent = pHHInfo->pHHWinType->hwndHelp;
144 DWORD toolbarFlags = pHHInfo->pHHWinType->fsToolBarFlags;
145 TBBUTTON buttons[IDTB_TOC_PREV - IDTB_EXPAND];
147 DWORD dwStyles, dwExStyles;
148 DWORD dwNumButtons, dwIndex;
150 /* FIXME: Remove the following line once we read the CHM file */
151 toolbarFlags = HHWIN_BUTTON_EXPAND | HHWIN_BUTTON_BACK | HHWIN_BUTTON_STOP |
152 HHWIN_BUTTON_REFRESH | HHWIN_BUTTON_HOME | HHWIN_BUTTON_PRINT;
153 TB_AddButtonsFromFlags(buttons, toolbarFlags, &dwNumButtons);
154 pHHInfo->dwNumTBButtons = dwNumButtons;
156 dwStyles = WS_CHILDWINDOW | WS_VISIBLE | TBSTYLE_FLAT |
157 TBSTYLE_WRAPABLE | TBSTYLE_TOOLTIPS | CCS_NODIVIDER;
158 dwExStyles = WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR;
160 hToolbar = CreateWindowExW(dwExStyles, TOOLBARCLASSNAMEW, NULL, dwStyles,
161 0, 0, 0, 0, hwndParent, NULL,
162 pHHInfo->hInstance, NULL);
166 SendMessageW(hToolbar, TB_SETBITMAPSIZE, 0, MAKELONG(ICON_SIZE, ICON_SIZE));
167 SendMessageW(hToolbar, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
168 SendMessageW(hToolbar, WM_SETFONT, (WPARAM)pHHInfo->hFont, TRUE);
170 /* FIXME: Load correct icons for all buttons */
171 tbAB.hInst = HINST_COMMCTRL;
172 tbAB.nID = IDB_STD_LARGE_COLOR;
173 SendMessageW(hToolbar, TB_ADDBITMAP, 0, (LPARAM)&tbAB);
175 for (dwIndex = 0; dwIndex < dwNumButtons; dwIndex++)
177 LPWSTR szBuf = HH_LoadString(buttons[dwIndex].idCommand);
178 DWORD dwLen = strlenW(szBuf);
179 szBuf[dwLen + 2] = 0; /* Double-null terminate */
181 buttons[dwIndex].iString = (DWORD)SendMessageW(hToolbar, TB_ADDSTRINGW, 0, (LPARAM)szBuf);
182 HeapFree(GetProcessHeap(), 0, szBuf);
185 SendMessageW(hToolbar, TB_ADDBUTTONSW, dwNumButtons, (LPARAM)&buttons);
186 SendMessageW(hToolbar, TB_AUTOSIZE, 0, 0);
187 ShowWindow(hToolbar, SW_SHOW);
189 pHHInfo->pHHWinType->hwndToolBar = hToolbar;
193 /* Navigation Pane */
195 static BOOL HH_AddNavigationPane(HHInfo *pHHInfo)
202 static BOOL HH_AddHTMLPane(HHInfo *pHHInfo)
209 LRESULT CALLBACK Help_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
218 hdc = BeginPaint(hWnd, &ps);
226 return DefWindowProcW(hWnd, message, wParam, lParam);
232 static BOOL HH_CreateHelpWindow(HHInfo *pHHInfo)
235 HINSTANCE hInstance = pHHInfo->hInstance;
237 DWORD dwStyles, dwExStyles;
238 DWORD x, y, width, height;
240 static const WCHAR windowClassW[] = {
241 'H','H',' ', 'P','a','r','e','n','t',0
244 static const WCHAR windowTitleW[] = {
245 'H','T','M','L',' ','H','e','l','p',0
248 wcex.cbSize = sizeof(WNDCLASSEXW);
249 wcex.style = CS_HREDRAW | CS_VREDRAW;
250 wcex.lpfnWndProc = (WNDPROC)Help_WndProc;
253 wcex.hInstance = hInstance;
254 wcex.hIcon = LoadIconW(NULL, (LPCWSTR)IDI_APPLICATION);
255 wcex.hCursor = LoadCursorW(NULL, (LPCWSTR)IDC_ARROW);
256 wcex.hbrBackground = (HBRUSH)(COLOR_BACKGROUND + 1);
257 wcex.lpszMenuName = NULL;
258 wcex.lpszClassName = windowClassW;
259 wcex.hIconSm = LoadIconW(NULL, (LPCWSTR)IDI_APPLICATION);
261 RegisterClassExW(&wcex);
263 dwStyles = WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
264 dwExStyles = WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR |
265 WS_EX_WINDOWEDGE | WS_EX_APPWINDOW;
267 /* these will be loaded from the CHM file in the future if they're provided */
268 x = WINTYPE_DEFAULT_X;
269 y = WINTYPE_DEFAULT_Y;
270 width = WINTYPE_DEFAULT_WIDTH;
271 height = WINTYPE_DEFAULT_HEIGHT;
273 hWnd = CreateWindowExW(dwExStyles, windowClassW, windowTitleW, dwStyles,
274 x, y, width, height, NULL, NULL, hInstance, NULL);
278 ShowWindow(hWnd, SW_SHOW);
281 /* store the pointer to the HH info struct */
282 SetWindowLongPtrW(hWnd, GWLP_USERDATA, (LONG_PTR)pHHInfo);
284 pHHInfo->pHHWinType->hwndHelp = hWnd;
288 static void HH_CreateFont(HHInfo *pHHInfo)
292 GetObjectW(GetStockObject(ANSI_VAR_FONT), sizeof(LOGFONTW), &lf);
293 lf.lfWeight = FW_NORMAL;
295 lf.lfUnderline = FALSE;
297 pHHInfo->hFont = CreateFontIndirectW(&lf);
300 static void HH_InitRequiredControls(DWORD dwControls)
302 INITCOMMONCONTROLSEX icex;
304 icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
305 icex.dwICC = dwControls;
306 InitCommonControlsEx(&icex);
309 /* Creates the whole package */
310 static BOOL HH_CreateViewer(HHInfo *pHHInfo)
312 HH_CreateFont(pHHInfo);
314 if (!HH_CreateHelpWindow(pHHInfo))
317 HH_InitRequiredControls(ICC_BAR_CLASSES);
319 if (!HH_AddToolbar(pHHInfo))
322 if (!HH_AddNavigationPane(pHHInfo))
325 if (!HH_AddHTMLPane(pHHInfo))
331 static HHInfo *HH_OpenHH(HINSTANCE hInstance, LPCWSTR szCmdLine)
333 HHInfo *pHHInfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(HHInfo));
335 pHHInfo->pHHWinType = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(HH_WINTYPEW));
336 pHHInfo->hInstance = hInstance;
337 pHHInfo->szCmdLine = szCmdLine;
342 static void HH_Close(HHInfo *pHHInfo)
347 HeapFree(GetProcessHeap(), 0, pHHInfo->pHHWinType);
350 /* FIXME: Check szCmdLine for bad arguments */
351 int WINAPI doWinMain(HINSTANCE hInstance, LPSTR szCmdLine)
356 if (OleInitialize(NULL) != S_OK)
359 pHHInfo = HH_OpenHH(hInstance, HH_ANSIToUnicode(szCmdLine));
360 if (!pHHInfo || !HH_CreateViewer(pHHInfo))
366 while (GetMessageW(&msg, 0, 0, 0))
368 TranslateMessage(&msg);
369 DispatchMessageW(&msg);
373 HeapFree(GetProcessHeap(), 0, pHHInfo);