Initial support for HTML Help. All the ad-hoc help-file finding code
[u/mdw/putty] / windows / winhelp.c
CommitLineData
cb2708d3 1/*\r
2 * winhelp.c: centralised functions to launch Windows help files,\r
3 * and to decide whether to use .HLP or .CHM help in any given\r
4 * situation.\r
5 */\r
6\r
7#include <stdio.h>\r
8#include <stdlib.h>\r
9#include <string.h>\r
10#include <assert.h>\r
11\r
12#include "putty.h"\r
13\r
14#include <htmlhelp.h>\r
15\r
16typedef HWND (CALLBACK *htmlhelp_t)(HWND, LPCSTR, UINT, DWORD);\r
17\r
18static char *help_path, *chm_path;\r
19static int help_has_contents;\r
20static int requested_help;\r
21static DWORD html_help_cookie;\r
22static htmlhelp_t htmlhelp;\r
23\r
24void init_help(void)\r
25{\r
26 char b[2048], *p, *q, *r;\r
27 FILE *fp;\r
28\r
29 GetModuleFileName(NULL, b, sizeof(b) - 1);\r
30 r = b;\r
31 p = strrchr(b, '\\');\r
32 if (p && p >= r) r = p+1;\r
33 q = strrchr(b, ':');\r
34 if (q && q >= r) r = q+1;\r
35 strcpy(r, PUTTY_HELP_FILE);\r
36 if ( (fp = fopen(b, "r")) != NULL) {\r
37 help_path = dupstr(b);\r
38 fclose(fp);\r
39 } else\r
40 help_path = NULL;\r
41 strcpy(r, PUTTY_HELP_CONTENTS);\r
42 if ( (fp = fopen(b, "r")) != NULL) {\r
43 help_has_contents = TRUE;\r
44 fclose(fp);\r
45 } else\r
46 help_has_contents = FALSE;\r
47\r
48 strcpy(r, PUTTY_CHM_FILE);\r
49 if ( (fp = fopen(b, "r")) != NULL) {\r
50 chm_path = dupstr(b);\r
51 fclose(fp);\r
52 } else\r
53 chm_path = NULL;\r
54 if (chm_path) {\r
55 HINSTANCE dllHH = LoadLibrary("hhctrl.ocx");\r
56 if (dllHH) {\r
57 htmlhelp = (htmlhelp_t)GetProcAddress(dllHH, "HtmlHelpA");\r
58 if (!htmlhelp)\r
59 FreeLibrary(dllHH);\r
60 }\r
61 if (htmlhelp)\r
62 htmlhelp(NULL, NULL, HH_INITIALIZE, (DWORD)&html_help_cookie);\r
63 else\r
64 chm_path = NULL;\r
65 }\r
66}\r
67\r
68void shutdown_help(void)\r
69{\r
70 if (chm_path)\r
71 htmlhelp(NULL, NULL, HH_UNINITIALIZE, html_help_cookie);\r
72}\r
73\r
74int has_help(void)\r
75{\r
76 /*\r
77 * FIXME: it would be nice here to disregard help_path on\r
78 * platforms that didn't have WINHLP32. But that's probably\r
79 * unrealistic, since even Vista will have it if the user\r
80 * specifically downloads it.\r
81 */\r
82 return (help_path || chm_path);\r
83}\r
84\r
85void launch_help(HWND hwnd, const char *topic)\r
86{\r
87 if (topic) {\r
88 int colonpos = strcspn(topic, ":");\r
89\r
90 if (chm_path) {\r
91 char *fname;\r
92 assert(topic[colonpos] != '\0');\r
93 fname = dupprintf("%s::/%s.html>main", chm_path,\r
94 topic + colonpos + 1);\r
95 htmlhelp(hwnd, fname, HH_DISPLAY_TOPIC, 0);\r
96 sfree(fname);\r
97 } else if (help_path) {\r
98 char *cmd = dupprintf("JI(`',`%.*s')", colonpos, topic);\r
99 WinHelp(hwnd, help_path, HELP_COMMAND, (DWORD)cmd);\r
100 sfree(cmd);\r
101 }\r
102 } else {\r
103 if (chm_path) {\r
104 htmlhelp(hwnd, chm_path, HH_DISPLAY_TOPIC, 0);\r
105 } else if (help_path) {\r
106 WinHelp(hwnd, help_path,\r
107 help_has_contents ? HELP_FINDER : HELP_CONTENTS, 0);\r
108 }\r
109 }\r
110 requested_help = TRUE;\r
111}\r
112\r
113void quit_help(HWND hwnd)\r
114{\r
115 if (requested_help) {\r
116 if (chm_path) {\r
117 htmlhelp(NULL, NULL, HH_CLOSE_ALL, 0);\r
118 } else if (help_path) {\r
119 WinHelp(hwnd, help_path, HELP_QUIT, 0);\r
120 }\r
121 requested_help = FALSE;\r
122 }\r
123}\r