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