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