home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 16 Announce / 16-Announce.zip / SEMINAR2.ZIP / SEMINAR2.DOC
Text File  |  1991-11-27  |  17KB  |  364 lines

  1.                        Using the OS/2 Help Manager
  2.                        ---------------------------
  3.  
  4.                                Written by:
  5.                       Larry Salomon, Jr. (aka 'Q')
  6.                        OS/2 Applications and Tools
  7.                      IBM T.J. Watson Research Center
  8.                           Yorktown Heights, NY
  9.  
  10.                          (LARRYS@YKTVMV.BITNET)
  11.                          (larrys@watson.ibm.com)
  12.                      (larrys@ibmman.watson.ibm.com)
  13.                      (larrys@ibmman2.watson.ibm.com)
  14.  
  15. This seminar may be distributed in any form, providing that no
  16. modifications are made to the text, unless done so by the author.
  17.  
  18. This, and other seminars, can be received via anonymous ftp from the
  19. following sites:
  20.  
  21.         Site                    IP Address      Directory
  22.         ----                    ----------      ---------
  23.         cs.unc.edu              129.109.136.138 /pub/os2.seminars
  24.         network.ucsd.edu        128.54.16.3     /pub/os2.seminars
  25.  
  26. Abstract:  the OS/2 Help Manager provides a very useful function to
  27. applications - online help.  This seminar will attempt to demonstrate how
  28. to enable your applications to use the Help Manager.
  29.  
  30. Disclaimer:  I do not claim to know everything about this subject.  I
  31. simply know enough about this subject to warrant the writing of this
  32. seminar with the intent of making it easier on those who want to know
  33. more.
  34.  
  35. Audience:  this seminar is directed at C programmers with good PM
  36. programming experience.  Function prototypes will be taken from the OS/2
  37. 1.3 toolkit.
  38.  
  39. Contact:  any questions, comments, etc. can be sent directly to me at one
  40. of the addresses listed above (in the order of preference and highest
  41. rate of successful delivery).
  42.  
  43.                   So You Want to Use the Help Manager?
  44.                   ------------------------------------
  45.  
  46. One of the many very useful features provided by OS/2 is the Help
  47. Manager.  Using it, an application can provide field and context
  48. sensitive help online for the user to get out of those "sticky
  49. situations" that they always seem to find themselves in.
  50.  
  51. However, enabling your application to use the Help Manager is not a
  52. five-minute task, by any means.  Ironically, the only documentation (that
  53. I have ever found) on doing this is in the Programming Guide, which comes
  54. with the Technical Reference documentation.
  55.  
  56. In your application, there are three sections that need to be modified or
  57. created before "you are in business":
  58.  
  59.         Code
  60.         Resource definitions
  61.         Help panel definitions
  62.  
  63. Before I discuss these further, it should be noted that help is usually
  64. associated with frame windows.  Dialogs that are displayed as a result of
  65. some user action on the frame normally use the help instance associated
  66. with the frame that owns the dialog.
  67.  
  68.                                   Code
  69.                                   ----
  70.  
  71. The coding aspect of providing online help can be further split into two
  72. parts:  initialization/termination and message handling.  Initialization
  73. can be done at any time, and consists of a HELPINIT structure and the
  74. WinCreateHelpInstance/WinAssociateHelpInstance APIs.
  75.  
  76.         typedef struct {
  77.            USHORT cb;
  78.            ULONG ulReturnCode;
  79.            PSZ pszTutorialName;
  80.            PHELPTABLE phtHelpTable;
  81.            HMODULE hmodHelpTableModule;
  82.            HMODULE hmodAccelActionBarModule;
  83.            USHORT idAccelTable;
  84.            USHORT idActionBar;
  85.            PSZ pszHelpWindowTitle;
  86.            USHORT usShowPanelId;
  87.            PSZ pszHelpLibraryName;
  88.         } HELPINIT;
  89.  
  90. cb                       - the size of the HELPINIT structure
  91. ulReturnCode             - initialized by WinCreateHelpInstance to
  92.                            indicate any errors that have occured but did
  93.                            not prevent creation of the instantiation.
  94. pszTutorialName          - points to a string containing the default
  95.                            tutorial name. This should be NULL if your
  96.                            application does not have a tutorial.
  97. phtHelpTable             - points to the help table.  If (and we will do
  98.                            it this way) the help table is defined in a
  99.                            resource file, the high word should be 0xFFFF
  100.                            and the low word should contain the resource
  101.                            id.
  102. hmodHelpTableModule      - the module handle of the DLL to be used when
  103.                            retrieving resources or NULL if the .EXE file
  104.                            contains the resources.
  105. hmodAccelActionBarModule - the module handle of the DLL to be when
  106.                            loading the accelerator table and action bar
  107.                            to be used by the Help Manager or NULL if the
  108.                            .EXE file contains the resources.
  109. idAccelTable             - the resource id of the custom accelerator
  110.                            table or 0 if none exists.
  111. idActionBar              - the resource id of the custom action bar or 0
  112.                            if none exists.
  113. pszHelpWindowTitle       - points to a string to be used as the title for
  114.                            the online help window.
  115. usShowPanelId            - describes whether or not panel ids are to be
  116.                            shown. This can be CMIC_HIDE_PANEL_ID,
  117.                            CMIC_SHOW_PANEL_ID, or CMIC_TOGGLE_PANEL_ID,
  118.                            which do not show the panel id, show the panel
  119.                            id, or toggle the showing of the panel id,
  120.                            respectively.
  121. pszHelpLibraryName       - points to a string containing the name of the
  122.                            file containing the panel definitions.
  123.  
  124. After initializing the HELPINIT structure, you call the
  125. WinCreateHelpInstance API.
  126.  
  127. HWND APIENTRY WinCreateHelpInstance(HAB hab,
  128.                                     PHELPINIT phinitHMInitStructure);
  129.  
  130. This returns the window handle of the Help Manager instance, to which you
  131. can send messages.  Even though this might not be NULL, indicating
  132. success, you should still check the ulReturnCode field of the HELPINIT
  133. structure for any warnings that are returned.
  134.  
  135. After the frame window is created, you call the WinAssociateHelpInstance
  136. API.  The need for this is described later.
  137.  
  138. BOOL APIENTRY WinAssociateHelpInstance(HWND hwndHelpInstance,
  139.                                        HWND hwndApp);
  140.  
  141. Finally, after the frame is destroyed, you call the
  142. WinDestroyHelpInstance API.
  143.  
  144. BOOL APIENTRY WinDestroyHelpInstance(HWND hwndHelpInstance);
  145.  
  146. Message handling is simple, since it is done in the standard way.
  147. Although there are many messages defined, the few that you will typically
  148. use are listed below.
  149.  
  150. The following messages are sent to the Help Manager and take no
  151. parameters, unless otherwise specified:
  152.  
  153. HM_DISPLAY_HELP          - tells the Help Manager to display a help
  154.                            panel.  PVOIDFROMMP(mp1) should point to a
  155.                            panel name or contain a panel id.
  156.                            SHORT1FROMMP(mp2) describes what mp1 contains:
  157.                               HM_RESOURCEID - SHORT1FROMMP(mp1) is the
  158.                                               panel id
  159.                               HM_PANELNAME  - PVOIDFROMMP(mp1) points to
  160.                                               the panel name
  161. HM_EXT_HELP              - tells the Help Manager to display the extended
  162.                            help panel for the window
  163. HM_HELP_CONTENTS         - tells the Help Manager to display the table of
  164.                            contents
  165. HM_HELP_INDEX            - tells the Help Manager to display the index
  166. HM_KEYS_HELP             - tells the Help Manager to display the keys
  167.                            help panel for the window
  168.  
  169. The following messages are sent by the Help Manager:
  170.  
  171. HM_ERROR                 - indicates an error occurred when viewing help.
  172.                            LONGFROMMP(mp1) indicates the HMERR_* constant
  173.                            describing the error.
  174. HM_HELPSUBITEM_NOT_FOUND - indicates that a panel was not found when help
  175.                            was requested.  SHORT1FROMMP(mp1) indicates a
  176.                            HLPM_* constant describing where help was
  177.                            requested from (a frame, menu, or a window);
  178.                            SHORT1FROMMP(mp2) indicates the id of the
  179.                            active frame or dialog; SHORT2FROMMP(mp2)
  180.                            indicates the id of the window with the focus,
  181.                            or the menuitem selected when F1 was pressed.
  182.                            If FALSE is returned, the Help Manager
  183.                            displays the extended help panel, else no
  184.                            action is taken.
  185. HM_QUERY_KEYS_HELP       - asks the application for the id of the keys
  186.                            help panel.  The application should return the
  187.                            id.
  188.  
  189. Additionally, WM_HELP is sent to the window whenever F1 is pressed.  This
  190. should normally be passed on to the default procedure for processing.  A
  191. caveat to this is when a pushbutton is used on a dialog.  When selected
  192. by the user, the panel corresponding to the pushbutton will be displayed,
  193. which is usually an undesirable result.  The workaround is to intercept
  194. the WM_HELP message and display the appropriate panel when the button is
  195. pushed.  The WM_HELP parameters are exactly like those of WM_COMMAND:
  196.  
  197.         case WM_HELP:
  198.            if (SHORT1FROMMP(mp1)==ID_HELP) {
  199.               WinSendMsg(hwndHelpMgr,HM_EXT_HELP,0L,0L);
  200.            } else {
  201.               return WinDefDlgProc(hwnd,usMsg,mp1,mp2);
  202.            } /* endif */
  203.            break;
  204.  
  205.                           Resource Definitions
  206.                           --------------------
  207.  
  208. The resources that need to be defined are one or more trees of tables
  209. describing the relationships between help panels and windows in an
  210. application.  There are two types of tables:  HELPTABLEs and
  211. HELPSUBTABLEs; the former contains HELPITEMs while the latter contains
  212. HELPSUBITEMs.
  213.  
  214. HELPITEMs are comprised of three elements, in the following order:  the
  215. main window id, the associated HELPSUBTABLE id, and the extended help
  216. panel id.
  217.  
  218. HELPSUBITEMs are comprised of two elements, in the following order:  the
  219. child window id and the help panel id.  A child window can be either a
  220. control or a menuitem.
  221.  
  222. An example of this structure is shown below:
  223.  
  224. HELPTABLE WND_IMAGE
  225. {
  226.    HELPITEM WND_IMAGE, SUBHLP_IMAGE, EXTHLP_IMAGE
  227.    HELPITEM DLG_INFO, SUBHLP_INFO, EXTHLP_INFO
  228. }
  229.  
  230. HELPSUBTABLE SUBHLP_IMAGE
  231. {
  232.    HELPSUBITEM M_FILE, HLP_M_FILE
  233.    HELPSUBITEM M_FILE, HLP_M_FILE
  234.    HELPSUBITEM MI_OPEN, HLP_MI_OPEN
  235.    HELPSUBITEM MI_SAVE, HLP_MI_SAVE
  236.    HELPSUBITEM MI_CLOSE, HLP_MI_CLOSE
  237.    HELPSUBITEM M_EDIT, HLP_M_EDIT
  238.    HELPSUBITEM MI_CUT, HLP_MI_CUT
  239.    HELPSUBITEM MI_COPY, HLP_MI_COPY
  240.    HELPSUBITEM MI_PASTE, HLP_MI_PASTE
  241.    HELPSUBITEM MI_DELETE, HLP_MI_DELETE
  242.    HELPSUBITEM M_IMAGE, HLP_M_IMAGE
  243.    HELPSUBITEM MI_PRINT, HLP_MI_PRINT
  244.    HELPSUBITEM MI_INFO, HLP_MI_INFO
  245.    HELPSUBITEM M_HELP, HLP_M_HELP
  246.    HELPSUBITEM MI_HELPFORHELP, HLP_MI_HELPFORHELP
  247.    HELPSUBITEM MI_EXTHELP, HLP_MI_EXTHELP
  248.    HELPSUBITEM MI_KEYSHELP, HLP_MI_KEYSHELP
  249.    HELPSUBITEM MI_HELPINDEX, HLP_MI_HELPINDEX
  250. }
  251.  
  252. HELPSUBTABLE SUBHLP_INFO
  253. {
  254.    HELPSUBITEM PB_CANCEL, HLP_PB_CANCEL
  255.    HELPSUBITEM PB_HELP, HLP_PB_HELP
  256. }
  257.  
  258.                          Help Panel Definitions
  259.                          ----------------------
  260.  
  261. Help panels are defined via a GML language that is compiled using the
  262. "Information Presentation Facility Compiler" (IPFC).  The tags, described
  263. in the Programming Guide, allow you to display text, display graphics,
  264. create hyperlinks, display footnotes, and a variety of other things.
  265. Because the language is fairly complex, a rigorous treatment is beyond
  266. the scope of this discussion.  A brief description of a .IPF file is in
  267. order, however.
  268.  
  269. The GML language is based upon "tags" - usually a beginning tag and an
  270. ending tag - which describe something.  In a not-so-abstract way, this
  271. means that you use tags to create everything from panels to bitmap
  272. inclusions, and everything in between.  Tags begin with a colon and end
  273. with a period; additionally, they can have attributes associated with
  274. them.
  275.  
  276. An .IPF file begins and ends with a :userdoc. and :euserdoc. tag.  Panels
  277. are created using the :h1. and :h2. tags ('h' is for "heading"), the
  278. difference between the two being that (by default) :h1. panels are
  279. visible in the table of contents, while :h2. panels are not.  Headers
  280. can have a resource id attribute and a name attribute.  For example:
  281.  
  282. :h1 res=256 id='MYPANEL'.A Heading
  283. :p.This is a help panel
  284.  
  285. ...creates a help panel with resource id=256 and having the name
  286. "MYPANEL".  The title of the panel comes immediately after the ending
  287. period.
  288.  
  289. Paragraphs are started with the :p. tag, and have no ending tag.
  290. Finally, emphasis is done via the :hpn. tag, where 'n' is an emphasis
  291. level from 1-9.  Experiment with this value to see what it produces.  The
  292. emphasis tag has an ending tag :ehpn. where n matches the value on the
  293. beginning tag.
  294.  
  295. If it isn't already clear, the resource ids of the panels should match
  296. those in the HELPSUBTABLEs.  This introduces a limitation of the IPFC
  297. compiler - there is no way to specify constants for the resource ids.
  298. You could use the C preprocessor, but you could encounter problems.  For
  299. example:
  300.  
  301. :h1 res=EXTHELP_MAIN.Extended help for MyApp.
  302.  
  303. When the Microsoft C preprocessor substitutes 256 for "EXTHELP_MAIN", it
  304. sees a ".E" immediately following and expects a floating point number in
  305. exponential notation ("256.Ex").  When it sees an 'x' instead of a '+' or
  306. '-', it flags it as an error (a workaround to this is to give the panel a
  307. dummy name.  Thus, you get ":h1 res=EXTHELP_MAIN id='DUMMY1'.Extended
  308. help for MyApp").
  309.  
  310. A nice application to write would be a IPFC preprocessor that scans the
  311. IPF file substituting values for the constants representing them that are
  312. defined in a C #include file.  But I digress...
  313.  
  314.                             "But Why Daddy?"
  315.                             ----------------
  316.  
  317. The need for the WinAssociateHelpInstance call is not obvious, so why do
  318. we need to call it?  The answer to this lies in the manner in which the
  319. Help Manager determines which panel to display when F1 is pressed.
  320.  
  321. When F1 is pressed, the Help Manager checks to see if the active window
  322. is associated with a particular Help Manager instance.  If not, the
  323. parent chain is referenced until the first window with an associated help
  324. manager instance is found (stopping at the window who's parent is the
  325. desktop).  If no window in the parent chain is found, the owner chain is
  326. likewise searched and an HM_ERROR is sent to the active window if no
  327. window was found there either.
  328.  
  329. If an associated window is found, its help subtable is determined and the
  330. id of the window/control with the focus is looked up in the subtable.  If
  331. no match is found, a HM_HELPSUBITEM_NOT_FOUND is sent to the application
  332. and is acted on accordingly, or else the panel for the window/control is
  333. displayed.
  334.  
  335. To sum up, you should call WinAssociateHelpInstance whenever:  1) you
  336. create the main frame window or 2) whenever you display a dialog box due
  337. to a user action.  For dialog boxes, you should disassociate the help
  338. instance in the dialog procedure's processing of the WM_DESTROY message,
  339. by calling WinAssociateHelpInstance with the frame window that owns the
  340. dialog.
  341.  
  342.                                  Summary
  343.                                  -------
  344.  
  345. In summary, the following things need to be done:
  346.  
  347.         Create a help instance
  348.         Associate the help instance after creating the main window
  349.         In the window procedure
  350.                 Trap the WM_COMMANDS for the "Help for help...",
  351.                 "Extended help...", "Keys help...", and "Help index..."
  352.                 and send the appropriate HM_* message to display the
  353.                 requested panel
  354.         For every dialog
  355.                 Associate the help instance with the dialog in WM_INITDLG
  356.                 Disassociate the help instance in WM_DESTROY
  357.                 Trap WM_HELP for buttons with BS_HELP style.
  358.         Create the HELPTABLEs and HELPSUBTABLEs in the .RC file
  359.         Create the help panels.
  360.  
  361. The code you will write is rather common, and will usually not need to be
  362. modified when using it is various applications, so you can simply copy
  363. the code when writing new applications.
  364.