How to Define Hooks for Context Sensitive Help

MAK If you're writing your own Context Sensitive Help system, the first thing you'll have to decide is how to hook into it. Okay, maybe the second or third thing, if the first or second are what format you plan store your documentation in and how you plan to display the stored docs to the user. Nevertheless, the following simple framework may give you some ideas. This isn't a help system in its self, just one of probably many ways you can go about handling the hooks (tying in a particular GUI element with a particular document section).

 namespace eval Help {
     # A list of toplevel windows that have had their
     # F1 key bound already.

     array set boundTops ""

     # Window path to help context associations

     array set hooks ""
 }

 # Hook - Configure the help context for the specified widget path.

 proc Help::Hook { hWnd data } {
     variable boundTops
     variable hooks

     # Make sure the F1 key is bound to invoke help
     # via the top-level window.

     set hWndTop [winfo toplevel $hWnd]
     if {![info exist boundTops($hWndTop)]} {
         set boundTops($hWndTop) 1
         bind $hWndTop <F1> +[namespace code [list Invoke %W]]
     }
     set hooks($hWnd) $data
     bind $hWnd <Destroy> +[namespace code [list Unhook $hWnd %W]]
 }

 # Unhook - Clean up hook data when window is destroyed

 proc Help::Unhook { hWnd hWndDestroyed } {
     variable boundTops
     variable hooks

     if {$hWnd == $hWndDestroyed} {
          if {[winfo toplevel $hWnd] == $hWnd} {
              array unset boundTops $hWnd
          }
          array unset hooks $hWnd.*
          array unset hooks $hWnd
     }
 }

 # Invoke - Called when the user requests help

 proc Help::Invoke { hWnd } {
     variable hooks

     # Scan up the tree for the nearest hooked context

     while {![info exist hooks($hWnd)]} {
         if {[winfo toplevel $hWnd] == $hWnd]} {
             break
         }
         set hWnd [winfo parent $hWnd]
     }

     if {[info exist hooks($hWnd)]} {
         # Your job: launch your help system, jumping to the
         # context specified by the value in hooks($hWnd)
     }
 }

This simple framework takes care of binding the F1 key, if necessary, to the toplevel window so that help is available no matter what item currently has the focus. It stores some programmer-specified data (which may be, for example, a URL) to be associated with the widget path. When the user presses the F1 key, it will scan up the widget path for the closest parent window having a registered help context, and then launch whatever you add for the actual help system with the given context (for example, a web browser).


LV For the novice, the term context sensitive help generally means that the user of an application can request help about a specific widget of a specific part of an application.


LV I would like to suggest that as a user, I'd love to be able to tell applications which key to use as help. For instance, if I have a key labeled Help on my keyboard, that's the key I want to use to ask for help from an Application. Users may have already assigned macros or some other functionality to many function keys, so please consider using the Tk option functionality to obtain the name of the function key to use for help.


Category Tutorial