]> asedeno.scripts.mit.edu Git - PuTTY.git/blob - windows/winhelp.c
Initial support for HTML Help. All the ad-hoc help-file finding code
[PuTTY.git] / windows / winhelp.c
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