From: simon Date: Sun, 17 Dec 2006 11:16:07 +0000 (+0000) Subject: Initial support for HTML Help. All the ad-hoc help-file finding code X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/commitdiff_plain/cb2708d3db03691c70ca702a35ba960c3e0cba98 Initial support for HTML Help. All the ad-hoc help-file finding code 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 --- diff --git a/Recipe b/Recipe index d2fe8d6b..2dcfb9e2 100644 --- 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 diff --git a/doc/Makefile b/doc/Makefile index 3bf40d14..5a463c85 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -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 index 00000000..fa6b6cde --- /dev/null +++ b/doc/chm.but @@ -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$ diff --git a/windows/winctrls.c b/windows/winctrls.c index 35f5f2d4..fd58584c 100644 --- a/windows/winctrls.c +++ b/windows/winctrls.c @@ -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; } diff --git a/windows/windlg.c b/windows/windlg.c index 9d986238..db1ef2f3 100644 --- a/windows/windlg.c +++ b/windows/windlg.c @@ -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); diff --git a/windows/window.c b/windows/window.c index 819f3d87..ed6914ce 100644 --- a/windows/window.c +++ b/windows/window.c @@ -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 index 00000000..f7b22881 --- /dev/null +++ b/windows/winhelp.c @@ -0,0 +1,123 @@ +/* + * winhelp.c: centralised functions to launch Windows help files, + * and to decide whether to use .HLP or .CHM help in any given + * situation. + */ + +#include +#include +#include +#include + +#include "putty.h" + +#include + +typedef HWND (CALLBACK *htmlhelp_t)(HWND, LPCSTR, UINT, DWORD); + +static char *help_path, *chm_path; +static int help_has_contents; +static int requested_help; +static DWORD html_help_cookie; +static htmlhelp_t htmlhelp; + +void init_help(void) +{ + 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; + + strcpy(r, PUTTY_CHM_FILE); + if ( (fp = fopen(b, "r")) != NULL) { + chm_path = dupstr(b); + fclose(fp); + } else + chm_path = NULL; + if (chm_path) { + HINSTANCE dllHH = LoadLibrary("hhctrl.ocx"); + if (dllHH) { + htmlhelp = (htmlhelp_t)GetProcAddress(dllHH, "HtmlHelpA"); + if (!htmlhelp) + FreeLibrary(dllHH); + } + if (htmlhelp) + htmlhelp(NULL, NULL, HH_INITIALIZE, (DWORD)&html_help_cookie); + else + chm_path = NULL; + } +} + +void shutdown_help(void) +{ + if (chm_path) + htmlhelp(NULL, NULL, HH_UNINITIALIZE, html_help_cookie); +} + +int has_help(void) +{ + /* + * FIXME: it would be nice here to disregard help_path on + * platforms that didn't have WINHLP32. But that's probably + * unrealistic, since even Vista will have it if the user + * specifically downloads it. + */ + return (help_path || chm_path); +} + +void launch_help(HWND hwnd, const char *topic) +{ + if (topic) { + int colonpos = strcspn(topic, ":"); + + if (chm_path) { + char *fname; + assert(topic[colonpos] != '\0'); + fname = dupprintf("%s::/%s.html>main", chm_path, + topic + colonpos + 1); + htmlhelp(hwnd, fname, HH_DISPLAY_TOPIC, 0); + sfree(fname); + } else if (help_path) { + char *cmd = dupprintf("JI(`',`%.*s')", colonpos, topic); + WinHelp(hwnd, help_path, HELP_COMMAND, (DWORD)cmd); + sfree(cmd); + } + } else { + if (chm_path) { + htmlhelp(hwnd, chm_path, HH_DISPLAY_TOPIC, 0); + } else if (help_path) { + WinHelp(hwnd, help_path, + help_has_contents ? HELP_FINDER : HELP_CONTENTS, 0); + } + } + requested_help = TRUE; +} + +void quit_help(HWND hwnd) +{ + if (requested_help) { + if (chm_path) { + htmlhelp(NULL, NULL, HH_CLOSE_ALL, 0); + } else if (help_path) { + WinHelp(hwnd, help_path, HELP_QUIT, 0); + } + requested_help = FALSE; + } +} diff --git a/windows/winhelp.h b/windows/winhelp.h index c9d05b03..5d63e5e5 100644 --- a/windows/winhelp.h +++ b/windows/winhelp.h @@ -12,131 +12,148 @@ #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. */ @@ -144,13 +161,13 @@ #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 diff --git a/windows/winpgen.c b/windows/winpgen.c index d767b233..550cdfce 100644 --- a/windows/winpgen.c +++ b/windows/winpgen.c @@ -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 */ } diff --git a/windows/winpgnt.c b/windows/winpgnt.c index d4b445ba..cfc74c96 100644 --- a/windows/winpgnt.c +++ b/windows/winpgnt.c @@ -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 */ } diff --git a/windows/winstuff.h b/windows/winstuff.h index 4436972a..2d8ac956 100644 --- a/windows/winstuff.h +++ b/windows/winstuff.h @@ -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 diff --git a/windows/winutils.c b/windows/winutils.c index 8e518f07..40f1f4a7 100644 --- a/windows/winutils.c +++ b/windows/winutils.c @@ -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); }