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 |
16 | typedef HWND (CALLBACK *htmlhelp_t)(HWND, LPCSTR, UINT, DWORD);\r |
17 | \r |
18 | static char *help_path, *chm_path;\r |
19 | static int help_has_contents;\r |
20 | static int requested_help;\r |
21 | static DWORD html_help_cookie;\r |
22 | static htmlhelp_t htmlhelp;\r |
23 | \r |
24 | void 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 |
68 | void 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 |
74 | int 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 |
85 | void 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 |
113 | void 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 |