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 htmlhelp_t htmlhelp; |
db6452be |
25 | #endif /* NO_HTMLHELP */ |
cb72236f |
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 | |
db6452be |
51 | #ifndef NO_HTMLHELP |
cb72236f |
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 | } |
1b2214cb |
65 | if (!htmlhelp) |
cb72236f |
66 | chm_path = NULL; |
67 | } |
db6452be |
68 | #endif /* NO_HTMLHELP */ |
cb72236f |
69 | } |
70 | |
71 | void shutdown_help(void) |
72 | { |
1b2214cb |
73 | /* Nothing to do currently. |
74 | * (If we were running HTML Help single-threaded, this is where we'd |
75 | * call HH_UNINITIALIZE.) */ |
cb72236f |
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 | */ |
db6452be |
86 | return (help_path |
87 | #ifndef NO_HTMLHELP |
88 | || chm_path |
89 | #endif /* NO_HTMLHELP */ |
90 | ); |
cb72236f |
91 | } |
92 | |
93 | void launch_help(HWND hwnd, const char *topic) |
94 | { |
95 | if (topic) { |
96 | int colonpos = strcspn(topic, ":"); |
97 | |
db6452be |
98 | #ifndef NO_HTMLHELP |
cb72236f |
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); |
db6452be |
106 | } else |
107 | #endif /* NO_HTMLHELP */ |
108 | if (help_path) { |
cb72236f |
109 | char *cmd = dupprintf("JI(`',`%.*s')", colonpos, topic); |
110 | WinHelp(hwnd, help_path, HELP_COMMAND, (DWORD)cmd); |
111 | sfree(cmd); |
112 | } |
113 | } else { |
db6452be |
114 | #ifndef NO_HTMLHELP |
cb72236f |
115 | if (chm_path) { |
116 | htmlhelp(hwnd, chm_path, HH_DISPLAY_TOPIC, 0); |
db6452be |
117 | } else |
118 | #endif /* NO_HTMLHELP */ |
119 | if (help_path) { |
cb72236f |
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) { |
db6452be |
130 | #ifndef NO_HTMLHELP |
cb72236f |
131 | if (chm_path) { |
132 | htmlhelp(NULL, NULL, HH_CLOSE_ALL, 0); |
db6452be |
133 | } else |
134 | #endif /* NO_HTMLHELP */ |
135 | if (help_path) { |
cb72236f |
136 | WinHelp(hwnd, help_path, HELP_QUIT, 0); |
137 | } |
138 | requested_help = FALSE; |
139 | } |
140 | } |