Initial support for HTML Help. All the ad-hoc help-file finding code
authorsimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Sun, 17 Dec 2006 11:16:07 +0000 (11:16 +0000)
committersimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Sun, 17 Dec 2006 11:16:07 +0000 (11:16 +0000)
and various calls to WinHelp() have been centralised into a new file
winhelp.c, which in turn has been modified to detect a .CHM file as
well as .HLP and select between them as appropriate. It explicitly
tries to load HHCTRL.OCX and use GetProcAddress, meaning that it
_should_ still work correctly on pre-HTML-Help platforms, falling
gracefully back to WinHelp, but although I tested this by
temporarily renaming my own HHCTRL.OCX I haven't yet been able to
test it on a real HTML-Help-free platform.

Also in this checkin: a new .but file and docs makefile changes to
make it convenient to build the sources for a .CHM. As yet, owing to
limitations of Halibut's CHM support, I'm not able to write a .CHM
directly, more's the pity.

git-svn-id: svn://svn.tartarus.org/sgt/putty@7000 cda61777-01e9-0310-a592-d414129be87e

12 files changed:
Recipe
doc/Makefile
doc/chm.but [new file with mode: 0644]
windows/winctrls.c
windows/windlg.c
windows/window.c
windows/winhelp.c [new file with mode: 0644]
windows/winhelp.h
windows/winpgen.c
windows/winpgnt.c
windows/winstuff.h
windows/winutils.c

diff --git a/Recipe b/Recipe
index d2fe8d6..2dcfb9e 100644 (file)
--- a/Recipe
+++ b/Recipe
@@ -220,7 +220,7 @@ TERMINAL = terminal wcwidth ldiscucs logging tree234 minibidi
 
 # GUI front end and terminal emulator (putty, puttytel).
 GUITERM  = TERMINAL window windlg winctrls sizetip winucs winprint
-         + winutils wincfg sercfg
+         + winutils wincfg sercfg winhelp
 
 # Same thing on Unix.
 UXTERM   = TERMINAL uxcfg sercfg uxucs uxprint timing
@@ -255,7 +255,7 @@ CHARSET  = sbcsdat slookup sbcs utf8 toucs fromucs xenc mimeenc macenc localenc
 
 # Standard libraries.
 LIBS     = advapi32.lib user32.lib gdi32.lib comctl32.lib comdlg32.lib
-         + shell32.lib winmm.lib imm32.lib winspool.lib
+         + shell32.lib winmm.lib imm32.lib winspool.lib htmlhelp.lib
 
 # Network backend sets. This also brings in the relevant attachment
 # to proxy.c depending on whether we're crypto-avoidant or not.
@@ -287,12 +287,12 @@ psftp    : [C] psftp winsftp wincons WINSSH BE_SSH SFTP wildcard WINMISC
 
 pageant  : [G] winpgnt sshrsa sshpubk sshdes sshbn sshmd5 version tree234
          + misc sshaes sshsha winpgntc sshdss sshsh512 winutils winmisc
-         + pageant.res LIBS
+         + winhelp pageant.res LIBS
 
 puttygen : [G] winpgen sshrsag sshdssg sshprime sshdes sshbn sshmd5 version
          + sshrand winnoise sshsha winstore misc winctrls sshrsa sshdss winmisc
          + sshpubk sshaes sshsh512 import winutils puttygen.res tree234
-        + notiming LIBS wintime
+        + notiming winhelp LIBS wintime
 
 pterm    : [X] GTKTERM uxmisc misc ldisc settings uxpty uxsel BE_NONE uxstore
          + uxsignal CHARSET cmdline uxpterm version time
index 3bf40d1..5a463c8 100644 (file)
@@ -49,6 +49,10 @@ index.html: $(INPUTS)
 putty.info: $(INPUTS)
        $(HALIBUT) --info $(INPUTS)
 
+chm: putty.hhp
+putty.hhp: $(INPUTS) chm.but
+       $(HALIBUT) --html $(INPUTS) chm.but
+
 MKMAN = $(HALIBUT) --man=$@ mancfg.but $<
 MANPAGES = putty.1 puttygen.1 plink.1 pscp.1 psftp.1 puttytel.1 pterm.1
 man: $(MANPAGES)
@@ -62,4 +66,4 @@ puttytel.1: man-ptel.but mancfg.but; $(MKMAN)
 pterm.1: man-pter.but mancfg.but; $(MKMAN)
 
 clean:
-       rm -f *.html *.txt *.hlp *.cnt *.1 *.info vstr.but
+       rm -f *.html *.txt *.hlp *.cnt *.1 *.info vstr.but *.hh[pck] *.chm
diff --git a/doc/chm.but b/doc/chm.but
new file mode 100644 (file)
index 0000000..fa6b6cd
--- /dev/null
@@ -0,0 +1,19 @@
+\# File containing the magic HTML configuration directives to create
+\# an MS HTML Help project. We put this on the end of the PuTTY
+\# docs build command line to build the HHP and friends.
+
+\cfg{html-leaf-level}{infinite}
+\cfg{html-leaf-contains-contents}{false}
+\cfg{html-suppress-navlinks}{true}
+\cfg{html-suppress-address}{true}
+
+\cfg{html-contents-filename}{index.html}
+\cfg{html-template-filename}{%k.html}
+\cfg{html-template-fragment}{%k}
+
+\cfg{html-mshtmlhelp-chm}{putty.chm}
+\cfg{html-mshtmlhelp-project}{putty.hhp}
+\cfg{html-mshtmlhelp-contents}{putty.hhc}
+\cfg{html-mshtmlhelp-index}{putty.hhk}
+
+\versionid $Id$
index 35f5f2d..fd58584 100644 (file)
@@ -2005,7 +2005,7 @@ int winctrl_handle_command(struct dlgparam *dp, UINT msg,
 
 /*
  * This function can be called to produce context help on a
- * control. Returns TRUE if it has actually launched WinHelp.
+ * control. Returns TRUE if it has actually launched some help.
  */
 int winctrl_context_help(struct dlgparam *dp, HWND hwnd, int id)
 {
@@ -2032,9 +2032,7 @@ int winctrl_context_help(struct dlgparam *dp, HWND hwnd, int id)
     if (!c->ctrl || !c->ctrl->generic.helpctx.p)
        return 0;                      /* no help available for this ctrl */
 
-    cmd = dupprintf("JI(`',`%s')", c->ctrl->generic.helpctx.p);
-    WinHelp(hwnd, help_path, HELP_COMMAND, (DWORD)cmd);
-    sfree(cmd);
+    launch_help(hwnd, c->ctrl->generic.helpctx.p);
     return 1;
 }
 
index 9d98623..db1ef2f 100644 (file)
@@ -380,7 +380,7 @@ static int CALLBACK GenericMainDlgProc(HWND hwnd, UINT msg,
        create_controls(hwnd, "");     /* Open and Cancel buttons etc */
        SetWindowText(hwnd, dp.wintitle);
        SetWindowLongPtr(hwnd, GWLP_USERDATA, 0);
-        if (help_path)
+        if (has_help())
             SetWindowLongPtr(hwnd, GWL_EXSTYLE,
                             GetWindowLongPtr(hwnd, GWL_EXSTYLE) |
                             WS_EX_CONTEXTHELP);
@@ -389,7 +389,6 @@ static int CALLBACK GenericMainDlgProc(HWND hwnd, UINT msg,
             if (item)
                 DestroyWindow(item);
         }
-        requested_help = FALSE;
        SendMessage(hwnd, WM_SETICON, (WPARAM) ICON_BIG,
                    (LPARAM) LoadIcon(hinst, MAKEINTRESOURCE(IDI_CFGICON)));
        /*
@@ -586,19 +585,12 @@ static int CALLBACK GenericMainDlgProc(HWND hwnd, UINT msg,
            ret = 0;
        return ret;
       case WM_HELP:
-        if (help_path) {
-           if (winctrl_context_help(&dp, hwnd,
-                                    ((LPHELPINFO)lParam)->iCtrlId))
-                requested_help = TRUE;
-           else
-                MessageBeep(0);
-        }
+       if (!winctrl_context_help(&dp, hwnd,
+                                ((LPHELPINFO)lParam)->iCtrlId))
+           MessageBeep(0);
         break;
       case WM_CLOSE:
-        if (requested_help) {
-            WinHelp(hwnd, help_path, HELP_QUIT, 0);
-            requested_help = FALSE;
-        }
+       quit_help(hwnd);
        SaneEndDialog(hwnd, 0);
        return 0;
 
@@ -622,12 +614,7 @@ void modal_about_box(HWND hwnd)
 
 void show_help(HWND hwnd)
 {
-    if (help_path) {
-       WinHelp(hwnd, help_path,
-               help_has_contents ? HELP_FINDER : HELP_CONTENTS,
-               0);
-       requested_help = TRUE;
-    }
+    launch_help(hwnd, NULL);
 }
 
 void defuse_showwindow(void)
@@ -653,7 +640,7 @@ int do_config(void)
 
     ctrlbox = ctrl_new_box();
     setup_config_box(ctrlbox, FALSE, 0, 0);
-    win_setup_config_box(ctrlbox, &dp.hwnd, (help_path != NULL), FALSE, 0);
+    win_setup_config_box(ctrlbox, &dp.hwnd, has_help(), FALSE, 0);
     dp_init(&dp);
     winctrl_init(&ctrls_base);
     winctrl_init(&ctrls_panel);
@@ -685,7 +672,7 @@ int do_reconfig(HWND hwnd, int protcfginfo)
 
     ctrlbox = ctrl_new_box();
     setup_config_box(ctrlbox, TRUE, cfg.protocol, protcfginfo);
-    win_setup_config_box(ctrlbox, &dp.hwnd, (help_path != NULL), TRUE,
+    win_setup_config_box(ctrlbox, &dp.hwnd, has_help(), TRUE,
                          cfg.protocol);
     dp_init(&dp);
     winctrl_init(&ctrls_base);
index 819f3d8..ed6914c 100644 (file)
@@ -345,31 +345,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
         osVersion.dwPlatformId != VER_PLATFORM_WIN32_NT))
        wm_mousewheel = RegisterWindowMessage("MSWHEEL_ROLLMSG");
 
-    /*
-     * See if we can find our Help file.
-     */
-    {
-        char b[2048], *p, *q, *r;
-        FILE *fp;
-        GetModuleFileName(NULL, b, sizeof(b) - 1);
-        r = b;
-        p = strrchr(b, '\\');
-        if (p && p >= r) r = p+1;
-        q = strrchr(b, ':');
-        if (q && q >= r) r = q+1;
-        strcpy(r, PUTTY_HELP_FILE);
-        if ( (fp = fopen(b, "r")) != NULL) {
-            help_path = dupstr(b);
-            fclose(fp);
-        } else
-            help_path = NULL;
-        strcpy(r, PUTTY_HELP_CONTENTS);
-        if ( (fp = fopen(b, "r")) != NULL) {
-            help_has_contents = TRUE;
-            fclose(fp);
-        } else
-            help_has_contents = FALSE;
-    }
+    init_help();
 
     /*
      * Process the command line.
@@ -787,7 +763,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
            AppendMenu(m, (cfg.resize_action == RESIZE_DISABLED) ?
                       MF_GRAYED : MF_ENABLED, IDM_FULLSCREEN, "&Full Screen");
            AppendMenu(m, MF_SEPARATOR, 0, 0);
-           if (help_path)
+           if (has_help())
                AppendMenu(m, MF_ENABLED, IDM_HELP, "&Help");
            str = dupprintf("&About %s", appname);
            AppendMenu(m, MF_ENABLED, IDM_ABOUT, str);
@@ -884,6 +860,7 @@ void cleanup_exit(int code)
        crypto_wrapup();
 #endif
     }
+    shutdown_help();
 
     exit(code);
 }
@@ -2276,8 +2253,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
            showabout(hwnd);
            break;
          case IDM_HELP:
-           WinHelp(hwnd, help_path,
-                    help_has_contents ? HELP_FINDER : HELP_CONTENTS, 0);
+           launch_help(hwnd, NULL);
            break;
          case SC_MOUSEMENU:
            /*
diff --git a/windows/winhelp.c b/windows/winhelp.c
new file mode 100644 (file)
index 0000000..f7b2288
--- /dev/null
@@ -0,0 +1,123 @@
+/*\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
index c9d05b0..5d63e5e 100644 (file)
 
 #define WINHELP_CTX_no_help NULL
 
-#define WINHELP_CTX_session_hostname "session.hostname"
-#define WINHELP_CTX_session_saved "session.saved"
-#define WINHELP_CTX_session_coe "session.coe"
-#define WINHELP_CTX_logging_main "logging.main"
-#define WINHELP_CTX_logging_filename "logging.filename"
-#define WINHELP_CTX_logging_exists "logging.exists"
-#define WINHELP_CTX_logging_flush "logging.flush"
-#define WINHELP_CTX_logging_ssh_omit_password "logging.ssh.omitpassword"
-#define WINHELP_CTX_logging_ssh_omit_data "logging.ssh.omitdata"
-#define WINHELP_CTX_keyboard_backspace "keyboard.backspace"
-#define WINHELP_CTX_keyboard_homeend "keyboard.homeend"
-#define WINHELP_CTX_keyboard_funkeys "keyboard.funkeys"
-#define WINHELP_CTX_keyboard_appkeypad "keyboard.appkeypad"
-#define WINHELP_CTX_keyboard_appcursor "keyboard.appcursor"
-#define WINHELP_CTX_keyboard_nethack "keyboard.nethack"
-#define WINHELP_CTX_keyboard_compose "keyboard.compose"
-#define WINHELP_CTX_keyboard_ctrlalt "keyboard.ctrlalt"
-#define WINHELP_CTX_features_application "features.application"
-#define WINHELP_CTX_features_mouse "features.mouse"
-#define WINHELP_CTX_features_resize "features.resize"
-#define WINHELP_CTX_features_altscreen "features.altscreen"
-#define WINHELP_CTX_features_retitle "features.retitle"
-#define WINHELP_CTX_features_qtitle "features.qtitle"
-#define WINHELP_CTX_features_dbackspace "features.dbackspace"
-#define WINHELP_CTX_features_charset "features.charset"
-#define WINHELP_CTX_features_arabicshaping "features.arabicshaping"
-#define WINHELP_CTX_features_bidi "features.bidi"
-#define WINHELP_CTX_terminal_autowrap "terminal.autowrap"
-#define WINHELP_CTX_terminal_decom "terminal.decom"
-#define WINHELP_CTX_terminal_lfhascr "terminal.lfhascr"
-#define WINHELP_CTX_terminal_bce "terminal.bce"
-#define WINHELP_CTX_terminal_blink "terminal.blink"
-#define WINHELP_CTX_terminal_answerback "terminal.answerback"
-#define WINHELP_CTX_terminal_localecho "terminal.localecho"
-#define WINHELP_CTX_terminal_localedit "terminal.localedit"
-#define WINHELP_CTX_terminal_printing "terminal.printing"
-#define WINHELP_CTX_bell_style "bell.style"
-#define WINHELP_CTX_bell_taskbar "bell.taskbar"
-#define WINHELP_CTX_bell_overload "bell.overload"
-#define WINHELP_CTX_window_size "window.size"
-#define WINHELP_CTX_window_resize "window.resize"
-#define WINHELP_CTX_window_scrollback "window.scrollback"
-#define WINHELP_CTX_window_erased "window.erased"
-#define WINHELP_CTX_behaviour_closewarn "behaviour.closewarn"
-#define WINHELP_CTX_behaviour_altf4 "behaviour.altf4"
-#define WINHELP_CTX_behaviour_altspace "behaviour.altspace"
-#define WINHELP_CTX_behaviour_altonly "behaviour.altonly"
-#define WINHELP_CTX_behaviour_alwaysontop "behaviour.alwaysontop"
-#define WINHELP_CTX_behaviour_altenter "behaviour.altenter"
-#define WINHELP_CTX_appearance_cursor "appearance.cursor"
-#define WINHELP_CTX_appearance_font "appearance.font"
-#define WINHELP_CTX_appearance_title "appearance.title"
-#define WINHELP_CTX_appearance_hidemouse "appearance.hidemouse"
-#define WINHELP_CTX_appearance_border "appearance.border"
-#define WINHELP_CTX_connection_termtype "connection.termtype"
-#define WINHELP_CTX_connection_termspeed "connection.termspeed"
-#define WINHELP_CTX_connection_username "connection.username"
-#define WINHELP_CTX_connection_keepalive "connection.keepalive"
-#define WINHELP_CTX_connection_nodelay "connection.nodelay"
-#define WINHELP_CTX_connection_ipversion "connection.ipversion"
-#define WINHELP_CTX_connection_tcpkeepalive "connection.tcpkeepalive"
-#define WINHELP_CTX_proxy_type "proxy.type"
-#define WINHELP_CTX_proxy_main "proxy.main"
-#define WINHELP_CTX_proxy_exclude "proxy.exclude"
-#define WINHELP_CTX_proxy_dns "proxy.dns"
-#define WINHELP_CTX_proxy_auth "proxy.auth"
-#define WINHELP_CTX_proxy_command "proxy.command"
-#define WINHELP_CTX_proxy_socksver "proxy.socksver"
-#define WINHELP_CTX_telnet_environ "telnet.environ"
-#define WINHELP_CTX_telnet_oldenviron "telnet.oldenviron"
-#define WINHELP_CTX_telnet_passive "telnet.passive"
-#define WINHELP_CTX_telnet_specialkeys "telnet.specialkeys"
-#define WINHELP_CTX_telnet_newline "telnet.newline"
-#define WINHELP_CTX_rlogin_localuser "rlogin.localuser"
-#define WINHELP_CTX_ssh_nopty "ssh.nopty"
-#define WINHELP_CTX_ssh_ttymodes "ssh.ttymodes"
-#define WINHELP_CTX_ssh_noshell "ssh.noshell"
-#define WINHELP_CTX_ssh_ciphers "ssh.ciphers"
-#define WINHELP_CTX_ssh_protocol "ssh.protocol"
-#define WINHELP_CTX_ssh_command "ssh.command"
-#define WINHELP_CTX_ssh_compress "ssh.compress"
-#define WINHELP_CTX_ssh_kexlist "ssh.kex.order"
-#define WINHELP_CTX_ssh_kex_repeat "ssh.kex.repeat"
-#define WINHELP_CTX_ssh_auth_bypass "ssh.auth.bypass"
-#define WINHELP_CTX_ssh_auth_privkey "ssh.auth.privkey"
-#define WINHELP_CTX_ssh_auth_agentfwd "ssh.auth.agentfwd"
-#define WINHELP_CTX_ssh_auth_changeuser "ssh.auth.changeuser"
-#define WINHELP_CTX_ssh_auth_pageant "ssh.auth.pageant"
-#define WINHELP_CTX_ssh_auth_tis "ssh.auth.tis"
-#define WINHELP_CTX_ssh_auth_ki "ssh.auth.ki"
-#define WINHELP_CTX_selection_buttons "selection.buttons"
-#define WINHELP_CTX_selection_shiftdrag "selection.shiftdrag"
-#define WINHELP_CTX_selection_rect "selection.rect"
-#define WINHELP_CTX_selection_charclasses "selection.charclasses"
-#define WINHELP_CTX_selection_linedraw "selection.linedraw"
-#define WINHELP_CTX_selection_rtf "selection.rtf"
-#define WINHELP_CTX_colours_ansi "colours.ansi"
-#define WINHELP_CTX_colours_xterm256 "colours.xterm256"
-#define WINHELP_CTX_colours_bold "colours.bold"
-#define WINHELP_CTX_colours_system "colours.system"
-#define WINHELP_CTX_colours_logpal "colours.logpal"
-#define WINHELP_CTX_colours_config "colours.config"
-#define WINHELP_CTX_translation_codepage "translation.codepage"
-#define WINHELP_CTX_translation_cjk_ambig_wide "translation.cjkambigwide"
-#define WINHELP_CTX_translation_cyrillic "translation.cyrillic"
-#define WINHELP_CTX_translation_linedraw "translation.linedraw"
-#define WINHELP_CTX_ssh_tunnels_x11 "ssh.tunnels.x11"
-#define WINHELP_CTX_ssh_tunnels_x11auth "ssh.tunnels.x11auth"
-#define WINHELP_CTX_ssh_tunnels_portfwd "ssh.tunnels.portfwd"
-#define WINHELP_CTX_ssh_tunnels_portfwd_localhost "ssh.tunnels.portfwd.localhost"
-#define WINHELP_CTX_ssh_tunnels_portfwd_ipversion "ssh.tunnels.portfwd.ipversion"
-#define WINHELP_CTX_ssh_bugs_ignore1 "ssh.bugs.ignore1"
-#define WINHELP_CTX_ssh_bugs_plainpw1 "ssh.bugs.plainpw1"
-#define WINHELP_CTX_ssh_bugs_rsa1 "ssh.bugs.rsa1"
-#define WINHELP_CTX_ssh_bugs_hmac2 "ssh.bugs.hmac2"
-#define WINHELP_CTX_ssh_bugs_derivekey2 "ssh.bugs.derivekey2"
-#define WINHELP_CTX_ssh_bugs_rsapad2 "ssh.bugs.rsapad2"
-#define WINHELP_CTX_ssh_bugs_pksessid2 "ssh.bugs.pksessid2"
-#define WINHELP_CTX_ssh_bugs_rekey2 "ssh.bugs.rekey2"
-#define WINHELP_CTX_serial_line "serial.line"
-#define WINHELP_CTX_serial_speed "serial.speed"
-#define WINHELP_CTX_serial_databits "serial.databits"
-#define WINHELP_CTX_serial_stopbits "serial.stopbits"
-#define WINHELP_CTX_serial_parity "serial.parity"
-#define WINHELP_CTX_serial_flow "serial.flow"
+#define WINHELP_CTX_session_hostname "session.hostname:config-hostname"
+#define WINHELP_CTX_session_saved "session.saved:config-saving"
+#define WINHELP_CTX_session_coe "session.coe:config-closeonexit"
+#define WINHELP_CTX_logging_main "logging.main:config-logging"
+#define WINHELP_CTX_logging_filename "logging.filename:config-logfilename"
+#define WINHELP_CTX_logging_exists "logging.exists:config-logfileexists"
+#define WINHELP_CTX_logging_flush "logging.flush:config-logflush"
+#define WINHELP_CTX_logging_ssh_omit_password "logging.ssh.omitpassword:config-logssh"
+#define WINHELP_CTX_logging_ssh_omit_data "logging.ssh.omitdata:config-logssh"
+#define WINHELP_CTX_keyboard_backspace "keyboard.backspace:config-backspace"
+#define WINHELP_CTX_keyboard_homeend "keyboard.homeend:config-homeend"
+#define WINHELP_CTX_keyboard_funkeys "keyboard.funkeys:config-funkeys"
+#define WINHELP_CTX_keyboard_appkeypad "keyboard.appkeypad:config-appkeypad"
+#define WINHELP_CTX_keyboard_appcursor "keyboard.appcursor:config-appcursor"
+#define WINHELP_CTX_keyboard_nethack "keyboard.nethack:config-nethack"
+#define WINHELP_CTX_keyboard_compose "keyboard.compose:config-compose"
+#define WINHELP_CTX_keyboard_ctrlalt "keyboard.ctrlalt:config-ctrlalt"
+#define WINHELP_CTX_features_application "features.application:config-features-application"
+#define WINHELP_CTX_features_mouse "features.mouse:config-features-mouse"
+#define WINHELP_CTX_features_resize "features.resize:config-features-resize"
+#define WINHELP_CTX_features_altscreen "features.altscreen:config-features-altscreen"
+#define WINHELP_CTX_features_retitle "features.retitle:config-features-retitle"
+#define WINHELP_CTX_features_qtitle "features.qtitle:config-features-qtitle"
+#define WINHELP_CTX_features_dbackspace "features.dbackspace:config-features-dbackspace"
+#define WINHELP_CTX_features_charset "features.charset:config-features-charset"
+#define WINHELP_CTX_features_arabicshaping "features.arabicshaping:config-features-shaping"
+#define WINHELP_CTX_features_bidi "features.bidi:config-features-bidi"
+#define WINHELP_CTX_terminal_autowrap "terminal.autowrap:config-autowrap"
+#define WINHELP_CTX_terminal_decom "terminal.decom:config-decom"
+#define WINHELP_CTX_terminal_lfhascr "terminal.lfhascr:config-crlf"
+#define WINHELP_CTX_terminal_bce "terminal.bce:config-erase"
+#define WINHELP_CTX_terminal_blink "terminal.blink:config-blink"
+#define WINHELP_CTX_terminal_answerback "terminal.answerback:config-answerback"
+#define WINHELP_CTX_terminal_localecho "terminal.localecho:config-localecho"
+#define WINHELP_CTX_terminal_localedit "terminal.localedit:config-localedit"
+#define WINHELP_CTX_terminal_printing "terminal.printing:config-printing"
+#define WINHELP_CTX_bell_style "bell.style:config-bellstyle"
+#define WINHELP_CTX_bell_taskbar "bell.taskbar:config-belltaskbar"
+#define WINHELP_CTX_bell_overload "bell.overload:config-bellovl"
+#define WINHELP_CTX_window_size "window.size:config-winsize"
+#define WINHELP_CTX_window_resize "window.resize:config-winsizelock"
+#define WINHELP_CTX_window_scrollback "window.scrollback:config-scrollback"
+#define WINHELP_CTX_window_erased "window.erased:config-erasetoscrollback"
+#define WINHELP_CTX_behaviour_closewarn "behaviour.closewarn:config-warnonclose"
+#define WINHELP_CTX_behaviour_altf4 "behaviour.altf4:config-altf4"
+#define WINHELP_CTX_behaviour_altspace "behaviour.altspace:config-altspace"
+#define WINHELP_CTX_behaviour_altonly "behaviour.altonly:config-altonly"
+#define WINHELP_CTX_behaviour_alwaysontop "behaviour.alwaysontop:config-alwaysontop"
+#define WINHELP_CTX_behaviour_altenter "behaviour.altenter:config-fullscreen"
+#define WINHELP_CTX_appearance_cursor "appearance.cursor:config-cursor"
+#define WINHELP_CTX_appearance_font "appearance.font:config-font"
+#define WINHELP_CTX_appearance_title "appearance.title:config-title"
+#define WINHELP_CTX_appearance_hidemouse "appearance.hidemouse:config-mouseptr"
+#define WINHELP_CTX_appearance_border "appearance.border:config-winborder"
+#define WINHELP_CTX_connection_termtype "connection.termtype:config-termtype"
+#define WINHELP_CTX_connection_termspeed "connection.termspeed:config-termspeed"
+#define WINHELP_CTX_connection_username "connection.username:config-username"
+#define WINHELP_CTX_connection_keepalive "connection.keepalive:config-keepalive"
+#define WINHELP_CTX_connection_nodelay "connection.nodelay:config-nodelay"
+#define WINHELP_CTX_connection_ipversion "connection.ipversion:config-address-family"
+#define WINHELP_CTX_connection_tcpkeepalive "connection.tcpkeepalive:config-tcp-keepalives"
+#define WINHELP_CTX_proxy_type "proxy.type:config-proxy-type"
+#define WINHELP_CTX_proxy_main "proxy.main:config-proxy"
+#define WINHELP_CTX_proxy_exclude "proxy.exclude:config-proxy-exclude"
+#define WINHELP_CTX_proxy_dns "proxy.dns:config-proxy-dns"
+#define WINHELP_CTX_proxy_auth "proxy.auth:config-proxy-auth"
+#define WINHELP_CTX_proxy_command "proxy.command:config-proxy-command"
+#define WINHELP_CTX_telnet_environ "telnet.environ:config-environ"
+#define WINHELP_CTX_telnet_oldenviron "telnet.oldenviron:config-oldenviron"
+#define WINHELP_CTX_telnet_passive "telnet.passive:config-ptelnet"
+#define WINHELP_CTX_telnet_specialkeys "telnet.specialkeys:config-telnetkey"
+#define WINHELP_CTX_telnet_newline "telnet.newline:config-telnetnl"
+#define WINHELP_CTX_rlogin_localuser "rlogin.localuser:config-rlogin-localuser"
+#define WINHELP_CTX_ssh_nopty "ssh.nopty:config-ssh-pty"
+#define WINHELP_CTX_ssh_ttymodes "ssh.ttymodes:config-ttymodes"
+#define WINHELP_CTX_ssh_noshell "ssh.noshell:config-ssh-noshell"
+#define WINHELP_CTX_ssh_ciphers "ssh.ciphers:config-ssh-encryption"
+#define WINHELP_CTX_ssh_protocol "ssh.protocol:config-ssh-prot"
+#define WINHELP_CTX_ssh_command "ssh.command:config-command"
+#define WINHELP_CTX_ssh_compress "ssh.compress:config-ssh-comp"
+#define WINHELP_CTX_ssh_kexlist "ssh.kex.order:config-ssh-kex-order"
+#define WINHELP_CTX_ssh_kex_repeat "ssh.kex.repeat:config-ssh-kex-rekey"
+#define WINHELP_CTX_ssh_auth_bypass "ssh.auth.bypass:config-ssh-noauth"
+#define WINHELP_CTX_ssh_auth_privkey "ssh.auth.privkey:config-ssh-privkey"
+#define WINHELP_CTX_ssh_auth_agentfwd "ssh.auth.agentfwd:config-ssh-agentfwd"
+#define WINHELP_CTX_ssh_auth_changeuser "ssh.auth.changeuser:config-ssh-changeuser"
+#define WINHELP_CTX_ssh_auth_pageant "ssh.auth.pageant:config-ssh-tryagent"
+#define WINHELP_CTX_ssh_auth_tis "ssh.auth.tis:config-ssh-tis"
+#define WINHELP_CTX_ssh_auth_ki "ssh.auth.ki:config-ssh-ki"
+#define WINHELP_CTX_selection_buttons "selection.buttons:config-mouse"
+#define WINHELP_CTX_selection_shiftdrag "selection.shiftdrag:config-mouseshift"
+#define WINHELP_CTX_selection_rect "selection.rect:config-rectselect"
+#define WINHELP_CTX_selection_charclasses "selection.charclasses:config-charclasses"
+#define WINHELP_CTX_selection_linedraw "selection.linedraw:config-linedrawpaste"
+#define WINHELP_CTX_selection_rtf "selection.rtf:config-rtfpaste"
+#define WINHELP_CTX_colours_ansi "colours.ansi:config-ansicolour"
+#define WINHELP_CTX_colours_xterm256 "colours.xterm256:config-xtermcolour"
+#define WINHELP_CTX_colours_bold "colours.bold:config-boldcolour"
+#define WINHELP_CTX_colours_system "colours.system:config-syscolour"
+#define WINHELP_CTX_colours_logpal "colours.logpal:config-logpalette"
+#define WINHELP_CTX_colours_config "colours.config:config-colourcfg"
+#define WINHELP_CTX_translation_codepage "translation.codepage:config-charset"
+#define WINHELP_CTX_translation_cjk_ambig_wide "translation.cjkambigwide:config-cjk-ambig-wide"
+#define WINHELP_CTX_translation_cyrillic "translation.cyrillic:config-cyr"
+#define WINHELP_CTX_translation_linedraw "translation.linedraw:config-linedraw"
+#define WINHELP_CTX_ssh_tunnels_x11 "ssh.tunnels.x11:config-ssh-x11"
+#define WINHELP_CTX_ssh_tunnels_x11auth "ssh.tunnels.x11auth:config-ssh-x11auth"
+#define WINHELP_CTX_ssh_tunnels_portfwd "ssh.tunnels.portfwd:config-ssh-portfwd"
+#define WINHELP_CTX_ssh_tunnels_portfwd_localhost "ssh.tunnels.portfwd.localhost:config-ssh-portfwd-localhost"
+#define WINHELP_CTX_ssh_tunnels_portfwd_ipversion "ssh.tunnels.portfwd.ipversion:config-ssh-portfwd-address-family"
+#define WINHELP_CTX_ssh_bugs_ignore1 "ssh.bugs.ignore1:config-ssh-bug-ignore1"
+#define WINHELP_CTX_ssh_bugs_plainpw1 "ssh.bugs.plainpw1:config-ssh-bug-plainpw1"
+#define WINHELP_CTX_ssh_bugs_rsa1 "ssh.bugs.rsa1:config-ssh-bug-rsa1"
+#define WINHELP_CTX_ssh_bugs_hmac2 "ssh.bugs.hmac2:config-ssh-bug-hmac2"
+#define WINHELP_CTX_ssh_bugs_derivekey2 "ssh.bugs.derivekey2:config-ssh-bug-derivekey2"
+#define WINHELP_CTX_ssh_bugs_rsapad2 "ssh.bugs.rsapad2:config-ssh-bug-sig"
+#define WINHELP_CTX_ssh_bugs_pksessid2 "ssh.bugs.pksessid2:config-ssh-bug-pksessid2"
+#define WINHELP_CTX_ssh_bugs_rekey2 "ssh.bugs.rekey2:config-ssh-bug-rekey"
+#define WINHELP_CTX_serial_line "serial.line:config-serial-line"
+#define WINHELP_CTX_serial_speed "serial.speed:config-serial-speed"
+#define WINHELP_CTX_serial_databits "serial.databits:config-serial-databits"
+#define WINHELP_CTX_serial_stopbits "serial.stopbits:config-serial-stopbits"
+#define WINHELP_CTX_serial_parity "serial.parity:config-serial-parity"
+#define WINHELP_CTX_serial_flow "serial.flow:config-serial-flow"
+
+#define WINHELP_CTX_pageant_general "pageant.general:pageant"
+#define WINHELP_CTX_pageant_keylist "pageant.keylist:pageant-mainwin-keylist"
+#define WINHELP_CTX_pageant_addkey "pageant.addkey:pageant-mainwin-addkey"
+#define WINHELP_CTX_pageant_remkey "pageant.remkey:pageant-mainwin-remkey"
+#define WINHELP_CTX_pgpfingerprints "pgpfingerprints:pgpkeys"
+#define WINHELP_CTX_puttygen_general "puttygen.general:pubkey-puttygen"
+#define WINHELP_CTX_puttygen_keytype "puttygen.keytype:puttygen-keytype"
+#define WINHELP_CTX_puttygen_bits "puttygen.bits:puttygen-strength"
+#define WINHELP_CTX_puttygen_generate "puttygen.generate:puttygen-generate"
+#define WINHELP_CTX_puttygen_fingerprint "puttygen.fingerprint:puttygen-fingerprint"
+#define WINHELP_CTX_puttygen_comment "puttygen.comment:puttygen-comment"
+#define WINHELP_CTX_puttygen_passphrase "puttygen.passphrase:puttygen-passphrase"
+#define WINHELP_CTX_puttygen_savepriv "puttygen.savepriv:puttygen-savepriv"
+#define WINHELP_CTX_puttygen_savepub "puttygen.savepub:puttygen-savepub"
+#define WINHELP_CTX_puttygen_pastekey "puttygen.pastekey:puttygen-pastekey"
+#define WINHELP_CTX_puttygen_load "puttygen.load:puttygen-load"
+#define WINHELP_CTX_puttygen_conversions "puttygen.conversions:puttygen-conversions"
 
 /* These are used in Windows-specific bits of the frontend.
  * We (ab)use "help context identifiers" (dwContextId) to identify them. */
 #define HELPCTXID(x) WINHELP_CTXID_ ## x
 
 #define WINHELP_CTXID_no_help 0
-#define WINHELP_CTX_errors_hostkey_absent "errors.hostkey.absent"
+#define WINHELP_CTX_errors_hostkey_absent "errors.hostkey.absent:errors-hostkey-absent"
 #define WINHELP_CTXID_errors_hostkey_absent 1
-#define WINHELP_CTX_errors_hostkey_changed "errors.hostkey.changed"
+#define WINHELP_CTX_errors_hostkey_changed "errors.hostkey.changed:errors-hostkey-wrong"
 #define WINHELP_CTXID_errors_hostkey_changed 2
-#define WINHELP_CTX_errors_cantloadkey "errors.cantloadkey"
+#define WINHELP_CTX_errors_cantloadkey "errors.cantloadkey:errors-cant-load-key"
 #define WINHELP_CTXID_errors_cantloadkey 3
-#define WINHELP_CTX_option_cleanup "options.cleanup"
+#define WINHELP_CTX_option_cleanup "options.cleanup:using-cleanup"
 #define WINHELP_CTXID_option_cleanup 4
-#define WINHELP_CTX_pgp_fingerprints "pgpfingerprints"
+#define WINHELP_CTX_pgp_fingerprints "pgpfingerprints:pgpkeys"
 #define WINHELP_CTXID_pgp_fingerprints 5
index d767b23..550cdfc 100644 (file)
@@ -800,7 +800,7 @@ static int CALLBACK MainDlgProc(HWND hwnd, UINT msg,
 
     switch (msg) {
       case WM_INITDIALOG:
-        if (help_path)
+        if (has_help())
             SetWindowLongPtr(hwnd, GWL_EXSTYLE,
                             GetWindowLongPtr(hwnd, GWL_EXSTYLE) |
                             WS_EX_CONTEXTHELP);
@@ -810,7 +810,6 @@ static int CALLBACK MainDlgProc(HWND hwnd, UINT msg,
              * if the help file isn't present.
              */
         }
-        requested_help = FALSE;
        SendMessage(hwnd, WM_SETICON, (WPARAM) ICON_BIG,
                    (LPARAM) LoadIcon(hinst, MAKEINTRESOURCE(200)));
 
@@ -856,7 +855,7 @@ static int CALLBACK MainDlgProc(HWND hwnd, UINT msg,
 
            menu1 = CreateMenu();
            AppendMenu(menu1, MF_ENABLED, IDC_ABOUT, "&About");
-           if (help_path)
+           if (has_help())
                AppendMenu(menu1, MF_ENABLED, IDC_GIVEHELP, "&Help");
            AppendMenu(menu, MF_POPUP | MF_ENABLED, (UINT) menu1, "&Help");
 
@@ -1036,11 +1035,7 @@ static int CALLBACK MainDlgProc(HWND hwnd, UINT msg,
          case IDC_GIVEHELP:
             if (HIWORD(wParam) == BN_CLICKED ||
                 HIWORD(wParam) == BN_DOUBLECLICKED) {
-                if (help_path) {
-                    WinHelp(hwnd, help_path, HELP_COMMAND,
-                            (DWORD)"JI(`',`puttygen.general')");
-                    requested_help = TRUE;
-                }
+               launch_help(hwnd, WINHELP_CTX_puttygen_general);
             }
            return 0;
          case IDC_GENERATE:
@@ -1331,7 +1326,7 @@ static int CALLBACK MainDlgProc(HWND hwnd, UINT msg,
        ui_set_state(hwnd, state, 2);
        break;
       case WM_HELP:
-        if (help_path) {
+        {
             int id = ((LPHELPINFO)lParam)->iCtrlId;
             char *topic = NULL;
             switch (id) {
@@ -1339,47 +1334,44 @@ static int CALLBACK MainDlgProc(HWND hwnd, UINT msg,
               case IDC_PROGRESS:
               case IDC_GENSTATIC:
               case IDC_GENERATE:
-                topic = "puttygen.generate"; break;
+                topic = WINHELP_CTX_puttygen_generate; break;
               case IDC_PKSTATIC:
               case IDC_KEYDISPLAY:
-                topic = "puttygen.pastekey"; break;
+                topic = WINHELP_CTX_puttygen_pastekey; break;
               case IDC_FPSTATIC:
               case IDC_FINGERPRINT:
-                topic = "puttygen.fingerprint"; break;
+                topic = WINHELP_CTX_puttygen_fingerprint; break;
               case IDC_COMMENTSTATIC:
               case IDC_COMMENTEDIT:
-                topic = "puttygen.comment"; break;
+                topic = WINHELP_CTX_puttygen_comment; break;
               case IDC_PASSPHRASE1STATIC:
               case IDC_PASSPHRASE1EDIT:
               case IDC_PASSPHRASE2STATIC:
               case IDC_PASSPHRASE2EDIT:
-                topic = "puttygen.passphrase"; break;
+                topic = WINHELP_CTX_puttygen_passphrase; break;
               case IDC_LOADSTATIC:
               case IDC_LOAD:
-                topic = "puttygen.load"; break;
+                topic = WINHELP_CTX_puttygen_load; break;
               case IDC_SAVESTATIC:
               case IDC_SAVE:
-                topic = "puttygen.savepriv"; break;
+                topic = WINHELP_CTX_puttygen_savepriv; break;
               case IDC_SAVEPUB:
-                topic = "puttygen.savepub"; break;
+                topic = WINHELP_CTX_puttygen_savepub; break;
               case IDC_TYPESTATIC:
               case IDC_KEYSSH1:
               case IDC_KEYSSH2RSA:
               case IDC_KEYSSH2DSA:
-                topic = "puttygen.keytype"; break;
+                topic = WINHELP_CTX_puttygen_keytype; break;
               case IDC_BITSSTATIC:
               case IDC_BITS:
-                topic = "puttygen.bits"; break;
+                topic = WINHELP_CTX_puttygen_bits; break;
               case IDC_IMPORT:
               case IDC_EXPORT_OPENSSH:
               case IDC_EXPORT_SSHCOM:
-                topic = "puttygen.conversions"; break;
+                topic = WINHELP_CTX_puttygen_conversions; break;
             }
             if (topic) {
-               char *cmd = dupprintf("JI(`',`%s')", topic);
-                WinHelp(hwnd, help_path, HELP_COMMAND, (DWORD)cmd);
-               sfree(cmd);
-                requested_help = TRUE;
+                launch_help(hwnd, topic);
             } else {
                 MessageBeep(0);
             }
@@ -1388,22 +1380,24 @@ static int CALLBACK MainDlgProc(HWND hwnd, UINT msg,
       case WM_CLOSE:
        state = (struct MainDlgState *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
        sfree(state);
-        if (requested_help) {
-            WinHelp(hwnd, help_path, HELP_QUIT, 0);
-            requested_help = FALSE;
-        }
+       quit_help(hwnd);
        EndDialog(hwnd, 1);
        return 0;
     }
     return 0;
 }
 
-void cleanup_exit(int code) { exit(code); }
+void cleanup_exit(int code)
+{
+    shutdown_help();
+    exit(code);
+}
 
 int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
 {
     int argc;
     char **argv;
+    int ret;
 
     InitCommonControls();
     hinst = inst;
@@ -1412,22 +1406,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
     /*
      * See if we can find our Help file.
      */
-    {
-        char b[2048], *p, *q, *r;
-        FILE *fp;
-        GetModuleFileName(NULL, b, sizeof(b) - 1);
-        r = b;
-        p = strrchr(b, '\\');
-        if (p && p >= r) r = p+1;
-        q = strrchr(b, ':');
-        if (q && q >= r) r = q+1;
-        strcpy(r, PUTTY_HELP_FILE);
-        if ( (fp = fopen(b, "r")) != NULL) {
-            help_path = dupstr(b);
-            fclose(fp);
-        } else
-            help_path = NULL;
-    }
+    init_help();
 
     split_into_argv(cmdline, &argc, &argv, NULL);
 
@@ -1445,6 +1424,8 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
     }
 
     random_ref();
-    return DialogBox(hinst, MAKEINTRESOURCE(201), NULL,
-                    MainDlgProc) != IDOK;
+    ret = DialogBox(hinst, MAKEINTRESOURCE(201), NULL, MainDlgProc) != IDOK;
+
+    cleanup_exit(ret);
+    return ret;                               /* just in case optimiser complains */
 }
index d4b445b..cfc74c9 100644 (file)
@@ -1470,7 +1470,7 @@ static int CALLBACK KeyListProc(HWND hwnd, UINT msg,
                           rd.right - rd.left, rd.bottom - rd.top, TRUE);
        }
 
-        if (help_path)
+        if (has_help())
             SetWindowLongPtr(hwnd, GWL_EXSTYLE,
                             GetWindowLongPtr(hwnd, GWL_EXSTYLE) |
                             WS_EX_CONTEXTHELP);
@@ -1479,7 +1479,6 @@ static int CALLBACK KeyListProc(HWND hwnd, UINT msg,
             if (item)
                 DestroyWindow(item);
         }
-        requested_help = FALSE;
 
        keylist = hwnd;
        {
@@ -1572,29 +1571,22 @@ static int CALLBACK KeyListProc(HWND hwnd, UINT msg,
          case 103:                    /* help */
             if (HIWORD(wParam) == BN_CLICKED ||
                 HIWORD(wParam) == BN_DOUBLECLICKED) {
-                if (help_path) {
-                    WinHelp(hwnd, help_path, HELP_COMMAND,
-                            (DWORD)"JI(`',`pageant.general')");
-                    requested_help = TRUE;
-                }
+               launch_help(hwnd, WINHELP_CTX_pageant_general);
             }
            return 0;
        }
        return 0;
       case WM_HELP:
-        if (help_path) {
+        {
             int id = ((LPHELPINFO)lParam)->iCtrlId;
             char *topic = NULL;
             switch (id) {
-              case 100: topic = "pageant.keylist"; break;
-              case 101: topic = "pageant.addkey"; break;
-              case 102: topic = "pageant.remkey"; break;
+              case 100: topic = WINHELP_CTX_pageant_keylist; break;
+              case 101: topic = WINHELP_CTX_pageant_addkey; break;
+              case 102: topic = WINHELP_CTX_pageant_remkey; break;
             }
             if (topic) {
-               char *cmd = dupprintf("JI(`',`%s')", topic);
-                WinHelp(hwnd, help_path, HELP_COMMAND, (DWORD)cmd);
-               sfree(cmd);
-                requested_help = TRUE;
+               launch_help(hwnd, topic);
             } else {
                 MessageBeep(0);
             }
@@ -1788,11 +1780,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
            }
            break;
          case IDM_HELP:
-            if (help_path) {
-                WinHelp(hwnd, help_path, HELP_COMMAND,
-                        (DWORD)"JI(`',`pageant.general')");
-                requested_help = TRUE;
-            }
+           launch_help(hwnd, WINHELP_CTX_pageant_general);
            break;
          default:
            {
@@ -1819,10 +1807,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
        }
        break;
       case WM_DESTROY:
-        if (requested_help) {
-            WinHelp(hwnd, help_path, HELP_QUIT, 0);
-            requested_help = FALSE;
-        }
+       quit_help(hwnd);
        PostQuitMessage(0);
        return 0;
       case WM_COPYDATA:
@@ -1948,7 +1933,11 @@ void agent_schedule_callback(void (*callback)(void *, void *, int),
     assert(!"We shouldn't get here");
 }
 
-void cleanup_exit(int code) { exit(code); }
+void cleanup_exit(int code)
+{
+    shutdown_help();
+    exit(code);
+}
 
 int flags = FLAG_SYNCAGENT;
 
@@ -2006,22 +1995,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
     /*
      * See if we can find our Help file.
      */
-    {
-        char b[2048], *p, *q, *r;
-        FILE *fp;
-        GetModuleFileName(NULL, b, sizeof(b) - 1);
-        r = b;
-        p = strrchr(b, '\\');
-        if (p && p >= r) r = p+1;
-        q = strrchr(b, ':');
-        if (q && q >= r) r = q+1;
-        strcpy(r, PUTTY_HELP_FILE);
-        if ( (fp = fopen(b, "r")) != NULL) {
-            help_path = dupstr(b);
-            fclose(fp);
-        } else
-            help_path = NULL;
-    }
+    init_help();
 
     /*
      * Look for the PuTTY binary (we will enable the saved session
@@ -2161,7 +2135,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
           "&View Keys");
     AppendMenu(systray_menu, MF_ENABLED, IDM_ADDKEY, "Add &Key");
     AppendMenu(systray_menu, MF_SEPARATOR, 0, 0);
-    if (help_path)
+    if (has_help())
        AppendMenu(systray_menu, MF_ENABLED, IDM_HELP, "&Help");
     AppendMenu(systray_menu, MF_ENABLED, IDM_ABOUT, "&About");
     AppendMenu(systray_menu, MF_SEPARATOR, 0, 0);
@@ -2201,5 +2175,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
 
     if (advapi)
        FreeLibrary(advapi);
-    return msg.wParam;
+
+    cleanup_exit(msg.wParam);
+    return msg.wParam;                /* just in case optimiser complains */
 }
index 4436972..2d8ac95 100644 (file)
@@ -97,6 +97,7 @@ typedef struct terminal_tag Terminal;
 #define PUTTY_REG_GPARENT_CHILD "SimonTatham"
 
 #define PUTTY_HELP_FILE "putty.hlp"
+#define PUTTY_CHM_FILE "putty.chm"
 #define PUTTY_HELP_CONTENTS "putty.cnt"
 
 #define GETTICKCOUNT GetTickCount
@@ -120,11 +121,13 @@ GLOBAL HWND logbox;
 GLOBAL HINSTANCE hinst;
 
 /*
- * Details of the help file.
+ * Help file stuff in winhelp.c.
  */
-GLOBAL char *help_path;
-GLOBAL int help_has_contents;
-GLOBAL int requested_help;
+void init_help(void);
+void shutdown_help(void);
+int has_help(void);
+void launch_help(HWND hwnd, const char *topic);
+void quit_help(HWND hwnd);
 
 /*
  * The terminal and logging context are notionally local to the
index 8e518f0..40f1f4a 100644 (file)
@@ -94,28 +94,20 @@ void filereq_free(filereq *state)
 /* Callback function to launch context help. */
 static VOID CALLBACK message_box_help_callback(LPHELPINFO lpHelpInfo)
 {
-    if (help_path) {
-       char *context = NULL;
+    char *context = NULL;
 #define CHECK_CTX(name) \
-       do { \
-           if (lpHelpInfo->dwContextId == WINHELP_CTXID_ ## name) \
-               context = WINHELP_CTX_ ## name; \
-       } while (0)
-       CHECK_CTX(errors_hostkey_absent);
-       CHECK_CTX(errors_hostkey_changed);
-       CHECK_CTX(errors_cantloadkey);
-       CHECK_CTX(option_cleanup);
-       CHECK_CTX(pgp_fingerprints);
+    do { \
+       if (lpHelpInfo->dwContextId == WINHELP_CTXID_ ## name) \
+           context = WINHELP_CTX_ ## name; \
+    } while (0)
+    CHECK_CTX(errors_hostkey_absent);
+    CHECK_CTX(errors_hostkey_changed);
+    CHECK_CTX(errors_cantloadkey);
+    CHECK_CTX(option_cleanup);
+    CHECK_CTX(pgp_fingerprints);
 #undef CHECK_CTX
-       if (context) {
-           /* We avoid using malloc, in case we're in a situation where
-            * it would be awkward to do so. */
-           char cmd[WINHELP_CTX_MAXLEN+10];
-           sprintf(cmd, "JI(`',`%.*s')", WINHELP_CTX_MAXLEN, context);
-           WinHelp(hwnd, help_path, HELP_COMMAND, (DWORD)cmd);
-           requested_help = TRUE;
-       }
-    }
+    if (context)
+       launch_help(hwnd, context);
 }
 
 int message_box(LPCTSTR text, LPCTSTR caption, DWORD style, DWORD helpctxid)
@@ -136,7 +128,7 @@ int message_box(LPCTSTR text, LPCTSTR caption, DWORD style, DWORD helpctxid)
     mbox.lpszCaption = caption;
     mbox.dwContextHelpId = helpctxid;
     mbox.dwStyle = style;
-    if (helpctxid != 0 && help_path) mbox.dwStyle |= MB_HELP;
+    if (helpctxid != 0 && has_help()) mbox.dwStyle |= MB_HELP;
     return MessageBoxIndirect(&mbox);
 }