cb72236f |
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 | |
db6452be |
14 | #ifndef NO_HTMLHELP |
cb72236f |
15 | #include <htmlhelp.h> |
db6452be |
16 | #endif /* NO_HTMLHELP */ |
cb72236f |
17 | |
cb72236f |
18 | static int requested_help; |
db6452be |
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; |
cb72236f |
24 | static DWORD html_help_cookie; |
25 | static htmlhelp_t htmlhelp; |
db6452be |
26 | #endif /* NO_HTMLHELP */ |
cb72236f |
27 | |
28 | void init_help(void) |
29 | { |
30 | char b[2048], *p, *q, *r; |
31 | FILE *fp; |
32 | |
33 | GetModuleFileName(NULL, b, sizeof(b) - 1); |
34 | r = b; |
35 | p = strrchr(b, '\\'); |
36 | if (p && p >= r) r = p+1; |
37 | q = strrchr(b, ':'); |
38 | if (q && q >= r) r = q+1; |
39 | strcpy(r, PUTTY_HELP_FILE); |
40 | if ( (fp = fopen(b, "r")) != NULL) { |
41 | help_path = dupstr(b); |
42 | fclose(fp); |
43 | } else |
44 | help_path = NULL; |
45 | strcpy(r, PUTTY_HELP_CONTENTS); |
46 | if ( (fp = fopen(b, "r")) != NULL) { |
47 | help_has_contents = TRUE; |
48 | fclose(fp); |
49 | } else |
50 | help_has_contents = FALSE; |
51 | |
db6452be |
52 | #ifndef NO_HTMLHELP |
cb72236f |
53 | strcpy(r, PUTTY_CHM_FILE); |
54 | if ( (fp = fopen(b, "r")) != NULL) { |
55 | chm_path = dupstr(b); |
56 | fclose(fp); |
57 | } else |
58 | chm_path = NULL; |
59 | if (chm_path) { |
60 | HINSTANCE dllHH = LoadLibrary("hhctrl.ocx"); |
61 | if (dllHH) { |
62 | htmlhelp = (htmlhelp_t)GetProcAddress(dllHH, "HtmlHelpA"); |
63 | if (!htmlhelp) |
64 | FreeLibrary(dllHH); |
65 | } |
66 | if (htmlhelp) |
67 | htmlhelp(NULL, NULL, HH_INITIALIZE, (DWORD)&html_help_cookie); |
68 | else |
69 | chm_path = NULL; |
70 | } |
db6452be |
71 | #endif /* NO_HTMLHELP */ |
cb72236f |
72 | } |
73 | |
74 | void shutdown_help(void) |
75 | { |
db6452be |
76 | #ifndef NO_HTMLHELP |
cb72236f |
77 | if (chm_path) |
78 | htmlhelp(NULL, NULL, HH_UNINITIALIZE, html_help_cookie); |
db6452be |
79 | #endif /* NO_HTMLHELP */ |
cb72236f |
80 | } |
81 | |
82 | int has_help(void) |
83 | { |
84 | /* |
85 | * FIXME: it would be nice here to disregard help_path on |
86 | * platforms that didn't have WINHLP32. But that's probably |
87 | * unrealistic, since even Vista will have it if the user |
88 | * specifically downloads it. |
89 | */ |
db6452be |
90 | return (help_path |
91 | #ifndef NO_HTMLHELP |
92 | || chm_path |
93 | #endif /* NO_HTMLHELP */ |
94 | ); |
cb72236f |
95 | } |
96 | |
97 | void launch_help(HWND hwnd, const char *topic) |
98 | { |
99 | if (topic) { |
100 | int colonpos = strcspn(topic, ":"); |
101 | |
db6452be |
102 | #ifndef NO_HTMLHELP |
cb72236f |
103 | if (chm_path) { |
104 | char *fname; |
105 | assert(topic[colonpos] != '\0'); |
106 | fname = dupprintf("%s::/%s.html>main", chm_path, |
107 | topic + colonpos + 1); |
108 | htmlhelp(hwnd, fname, HH_DISPLAY_TOPIC, 0); |
109 | sfree(fname); |
db6452be |
110 | } else |
111 | #endif /* NO_HTMLHELP */ |
112 | if (help_path) { |
cb72236f |
113 | char *cmd = dupprintf("JI(`',`%.*s')", colonpos, topic); |
114 | WinHelp(hwnd, help_path, HELP_COMMAND, (DWORD)cmd); |
115 | sfree(cmd); |
116 | } |
117 | } else { |
db6452be |
118 | #ifndef NO_HTMLHELP |
cb72236f |
119 | if (chm_path) { |
120 | htmlhelp(hwnd, chm_path, HH_DISPLAY_TOPIC, 0); |
db6452be |
121 | } else |
122 | #endif /* NO_HTMLHELP */ |
123 | if (help_path) { |
cb72236f |
124 | WinHelp(hwnd, help_path, |
125 | help_has_contents ? HELP_FINDER : HELP_CONTENTS, 0); |
126 | } |
127 | } |
128 | requested_help = TRUE; |
129 | } |
130 | |
131 | void quit_help(HWND hwnd) |
132 | { |
133 | if (requested_help) { |
db6452be |
134 | #ifndef NO_HTMLHELP |
cb72236f |
135 | if (chm_path) { |
136 | htmlhelp(NULL, NULL, HH_CLOSE_ALL, 0); |
db6452be |
137 | } else |
138 | #endif /* NO_HTMLHELP */ |
139 | if (help_path) { |
cb72236f |
140 | WinHelp(hwnd, help_path, HELP_QUIT, 0); |
141 | } |
142 | requested_help = FALSE; |
143 | } |
144 | } |