--- /dev/null
+/*\r
+ * winhelp.c: centralised functions to launch Windows help files,\r
+ * and to decide whether to use .HLP or .CHM help in any given\r
+ * situation.\r
+ */\r
+\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#include <assert.h>\r
+\r
+#include "putty.h"\r
+\r
+#include <htmlhelp.h>\r
+\r
+typedef HWND (CALLBACK *htmlhelp_t)(HWND, LPCSTR, UINT, DWORD);\r
+\r
+static char *help_path, *chm_path;\r
+static int help_has_contents;\r
+static int requested_help;\r
+static DWORD html_help_cookie;\r
+static htmlhelp_t htmlhelp;\r
+\r
+void init_help(void)\r
+{\r
+ char b[2048], *p, *q, *r;\r
+ FILE *fp;\r
+\r
+ GetModuleFileName(NULL, b, sizeof(b) - 1);\r
+ r = b;\r
+ p = strrchr(b, '\\');\r
+ if (p && p >= r) r = p+1;\r
+ q = strrchr(b, ':');\r
+ if (q && q >= r) r = q+1;\r
+ strcpy(r, PUTTY_HELP_FILE);\r
+ if ( (fp = fopen(b, "r")) != NULL) {\r
+ help_path = dupstr(b);\r
+ fclose(fp);\r
+ } else\r
+ help_path = NULL;\r
+ strcpy(r, PUTTY_HELP_CONTENTS);\r
+ if ( (fp = fopen(b, "r")) != NULL) {\r
+ help_has_contents = TRUE;\r
+ fclose(fp);\r
+ } else\r
+ help_has_contents = FALSE;\r
+\r
+ strcpy(r, PUTTY_CHM_FILE);\r
+ if ( (fp = fopen(b, "r")) != NULL) {\r
+ chm_path = dupstr(b);\r
+ fclose(fp);\r
+ } else\r
+ chm_path = NULL;\r
+ if (chm_path) {\r
+ HINSTANCE dllHH = LoadLibrary("hhctrl.ocx");\r
+ if (dllHH) {\r
+ htmlhelp = (htmlhelp_t)GetProcAddress(dllHH, "HtmlHelpA");\r
+ if (!htmlhelp)\r
+ FreeLibrary(dllHH);\r
+ }\r
+ if (htmlhelp)\r
+ htmlhelp(NULL, NULL, HH_INITIALIZE, (DWORD)&html_help_cookie);\r
+ else\r
+ chm_path = NULL;\r
+ }\r
+}\r
+\r
+void shutdown_help(void)\r
+{\r
+ if (chm_path)\r
+ htmlhelp(NULL, NULL, HH_UNINITIALIZE, html_help_cookie);\r
+}\r
+\r
+int has_help(void)\r
+{\r
+ /*\r
+ * FIXME: it would be nice here to disregard help_path on\r
+ * platforms that didn't have WINHLP32. But that's probably\r
+ * unrealistic, since even Vista will have it if the user\r
+ * specifically downloads it.\r
+ */\r
+ return (help_path || chm_path);\r
+}\r
+\r
+void launch_help(HWND hwnd, const char *topic)\r
+{\r
+ if (topic) {\r
+ int colonpos = strcspn(topic, ":");\r
+\r
+ if (chm_path) {\r
+ char *fname;\r
+ assert(topic[colonpos] != '\0');\r
+ fname = dupprintf("%s::/%s.html>main", chm_path,\r
+ topic + colonpos + 1);\r
+ htmlhelp(hwnd, fname, HH_DISPLAY_TOPIC, 0);\r
+ sfree(fname);\r
+ } else if (help_path) {\r
+ char *cmd = dupprintf("JI(`',`%.*s')", colonpos, topic);\r
+ WinHelp(hwnd, help_path, HELP_COMMAND, (DWORD)cmd);\r
+ sfree(cmd);\r
+ }\r
+ } else {\r
+ if (chm_path) {\r
+ htmlhelp(hwnd, chm_path, HH_DISPLAY_TOPIC, 0);\r
+ } else if (help_path) {\r
+ WinHelp(hwnd, help_path,\r
+ help_has_contents ? HELP_FINDER : HELP_CONTENTS, 0);\r
+ }\r
+ }\r
+ requested_help = TRUE;\r
+}\r
+\r
+void quit_help(HWND hwnd)\r
+{\r
+ if (requested_help) {\r
+ if (chm_path) {\r
+ htmlhelp(NULL, NULL, HH_CLOSE_ALL, 0);\r
+ } else if (help_path) {\r
+ WinHelp(hwnd, help_path, HELP_QUIT, 0);\r
+ }\r
+ requested_help = FALSE;\r
+ }\r
+}\r