Popup windows from HTML Help

The previous topic calling HTML Help described how to call HtmlHelp to show a normal HTML topic. Here is how to use HtmlHelp to show a popup or contexthelp-window.

The declaration for the HtmlHelp function is now slightly different: pszFile is now declared as a LONG parameter because we will have to pass it the NULL value. This is the new declaration:

&GLOBAL-DEFINE HH_DISPLAY_TEXT_POPUP 14
 
PROCEDURE HtmlHelpA EXTERNAL "hhctrl.ocx" PERSISTENT :
   DEFINE INPUT PARAMETER  hwndCaller AS LONG.
   DEFINE INPUT PARAMETER  pszFile    AS LONG.
   DEFINE INPUT PARAMETER  uCommand   AS LONG.
   DEFINE INPUT PARAMETER  dwData     AS LONG.
   DEFINE RETURN PARAMETER hwndHelp   AS LONG.
END PROCEDURE.

There are at least two different ways to create a popup. The first way does not need a CHM file: you can simply pass the string you want to show. The second way uses a CHM file which contains a list of strings.
Procedure HHPopupString in the following example creates a popup containing a specified string, positioned near a specified Progress widget.

{windows.i}
 
RUN HHPopupString (FILL-IN-1:HANDLE,
                   "This is the text that will be shown in the popup window").
 
PROCEDURE HHPopupString :
 
  DEFINE INPUT PARAMETER phWidget AS WIDGET-HANDLE NO-UNDO.
  DEFINE INPUT PARAMETER pText    AS CHARACTER          NO-UNDO.
 
  DEFINE VARIABLE FontSpec AS CHARACTER.
  DEFINE VARIABLE HH_POPUP AS MEMPTR.
  DEFINE VARIABLE lpText   AS MEMPTR.
  DEFINE VARIABLE lpFont   AS MEMPTR.
  DEFINE VARIABLE lpPoint  AS MEMPTR.
  DEFINE VARIABLE retval   AS INTEGER NO-UNDO.
 
  SET-SIZE (lpText)    = LENGTH(pText) + 1.
  PUT-STRING(lpText,1) = pText.
 
  /* specify a font, format "facename[, point size[, charset[ BOLD ITALIC UNDERLINE]]]" */
  FontSpec = 'MS Sans Serif,10,,BOLD'.
  FontSpec = 'MS Sans Serif,10,,'.
  SET-SIZE (lpFont) = LENGTH(FontSpec) + 1.
  PUT-STRING(lpFont,1) = FontSpec.
 
  /* screen coordinates. There is something weird about this */
  /* I currently have only one disply monitor... should test 
     this calculation with a secondary monitor using negative coords */
  SET-SIZE (lpPoint) = 8.
  PUT-LONG (lpPoint,1) = INTEGER(phWidget:WIDTH-PIXELS / 2).
  PUT-LONG (lpPoint,5) = INTEGER(phWidget:HEIGHT-PIXELS / 2).
  RUN ClientToScreen IN hpApi(phWidget:HWND,
                              GET-POINTER-VALUE(lpPoint),
                              OUTPUT retval).
 
  /* fill the HH_POPUP structure */  
  SET-SIZE (HH_POPUP)     = 52.
  PUT-LONG (HH_POPUP, 1)  = GET-SIZE(HH_POPUP).
  PUT-LONG (HH_POPUP, 5)  = 0.  /* or hInstance for a DLL that contains string resource */
  PUT-LONG (HH_POPUP, 9)  = 0.  /* or number of string resource in the DLL              */
  PUT-LONG (HH_POPUP,13)  = GET-POINTER-VALUE(lpText).
  PUT-LONG (HH_POPUP,17)  = GET-LONG(lpPoint,1). /* X-coordinate of center */
  PUT-LONG (HH_POPUP,21)  = GET-LONG(lpPoint,5). /* Y-coordinate of top    */
  PUT-LONG (HH_POPUP,25)  =  1. /* default textcolor or RGB-VALUE(Red,Green,Blue) */
  PUT-LONG (HH_POPUP,29)  = -1. /* default bgcolor   or RGB-VALUE(Red,Green,Blue) */
  PUT-LONG (HH_POPUP,33)  = -1. /* default left margin */
  PUT-LONG (HH_POPUP,37)  = -1. /* default top margin */
  PUT-LONG (HH_POPUP,41)  = -1. /* default right margin */
  PUT-LONG (HH_POPUP,45)  = -1. /* default bottom margin */
  PUT-LONG (HH_POPUP,49)  = 0.  /* or get-pointer-value(lpFont). */
 
  RUN HtmlHelpA ( phWidget:HWND, 
                  0, 
                  {&HH_DISPLAY_TEXT_POPUP}, 
                  GET-POINTER-VALUE(HH_POPUP),
                  OUTPUT RetVal).
 
  /* free memory */
  SET-SIZE (lpText)   = 0.
  SET-SIZE (lpFont)   = 0.
  SET-SIZE (lpPoint)  = 0.
  SET-SIZE (HH_POPUP) = 0.
 
END PROCEDURE.

As you can see in you can manipulate colors, fonts, margins and coordinates but I only used values that represent the system defaults.
The next example uses a CHM file to retrieve the string. A single CHM file can contain many strings, each string has a ContextId number.

{windows.i}
 
RUN HHPopupContext (FILL-IN-1:HANDLE,
                    "apisite.chm",
                    2).
 
/* or:
   RUN HHPopupContext (FILL-IN-1:HANDLE,
                       "apisite.chm::/cshelp.txt",
                       2).
*/
 
PROCEDURE HHPopupContext :
 
  DEFINE INPUT PARAMETER phWidget   AS WIDGET-HANDLE NO-UNDO.
  DEFINE INPUT PARAMETER pFilename  AS CHARACTER          NO-UNDO.
  DEFINE INPUT PARAMETER pContextId AS INTEGER       NO-UNDO.
 
  DEFINE VARIABLE FontSpec   AS CHARACTER.
  DEFINE VARIABLE HH_POPUP   AS MEMPTR.
  DEFINE VARIABLE lpFileName AS MEMPTR.
  DEFINE VARIABLE lpFont     AS MEMPTR.
  DEFINE VARIABLE lpPoint    AS MEMPTR.
  DEFINE VARIABLE retval     AS INTEGER NO-UNDO.
 
  SET-SIZE (lpFileName)    = LENGTH(pFileName) + 1.
  PUT-STRING(lpFileName,1) = pFileName.
 
  /* specify a font, format "facename[, point size[, charset[ BOLD ITALIC UNDERLINE]]]" */
  FontSpec = 'MS Sans Serif,10,,BOLD'.
  FontSpec = 'MS Sans Serif,10,,'.
  SET-SIZE (lpFont) = LENGTH(FontSpec) + 1.
  PUT-STRING(lpFont,1) = FontSpec.
 
  /* screen coordinates. There is something weird about this. */
  /* I really wish I had two video adaptors to test negative screen coordinates */
  SET-SIZE (lpPoint) = 8.
  PUT-LONG (lpPoint,1) = INTEGER(phWidget:WIDTH-PIXELS / 2).
  PUT-LONG (lpPoint,5) = INTEGER(phWidget:HEIGHT-PIXELS / 2).
  RUN ClientToScreen IN hpApi(phWidget:HWND,
                              GET-POINTER-VALUE(lpPoint),
                              OUTPUT retval).
 
  /* fill the HH_POPUP structure */  
  SET-SIZE (HH_POPUP)     = 52.
  PUT-LONG (HH_POPUP, 1)  = GET-SIZE(HH_POPUP).
  PUT-LONG (HH_POPUP, 5)  = 0.
  PUT-LONG (HH_POPUP, 9)  = pContextId.
  PUT-LONG (HH_POPUP,13)  = 0.
  PUT-LONG (HH_POPUP,17)  = GET-LONG(lpPoint,1). /* X-coordinate of center */
  PUT-LONG (HH_POPUP,21)  = GET-LONG(lpPoint,5). /* Y-coordinate of top    */
  PUT-LONG (HH_POPUP,25)  =  1. /* default textcolor or RGB-VALUE(Red,Green,Blue) */
  PUT-LONG (HH_POPUP,29)  = -1. /* default bgcolor   or RGB-VALUE(Red,Green,Blue) */
  PUT-LONG (HH_POPUP,33)  = -1. /* default left margin */
  PUT-LONG (HH_POPUP,37)  = -1. /* default top margin */
  PUT-LONG (HH_POPUP,41)  = -1. /* default right margin */
  PUT-LONG (HH_POPUP,45)  = -1. /* default bottom margin */
  PUT-LONG (HH_POPUP,49)  = 0.  /* or get-pointer-value(lpFont). */
 
  RUN HtmlHelpA ( phWidget:HWND, 
                  GET-POINTER-VALUE(lpFileName), 
                  {&HH_DISPLAY_TEXT_POPUP}, 
                  GET-POINTER-VALUE(HH_POPUP),
                  OUTPUT RetVal).
 
  /* free memory */
  SET-SIZE (lpFileName) = 0.
  SET-SIZE (lpFont)   = 0.
  SET-SIZE (lpPoint)  = 0.
  SET-SIZE (HH_POPUP) = 0.
 
END PROCEDURE.

To build a CHM that contains popup strings you have to write a TXT file. The default name for this TXT file is "cshelp.txt" and it should by default be located in the CHM root. If it has a different name or a different location you have to specify it along with the name of the CHM file, as shown in the commented RUN statement above. You can also create several text files in the same CHM project in order to organize a large amount of strings. Finally the text file has to be added to the [TEXT POPUPS] section in the project file.
This file (cshelp.txt) can contain many strings and is formatted like this little example :

.topic 1
This is the first example of a popup topic. It can be called
using HTMLHelp with the HH_DISPLAY_TEXT_POPUP option. see page 
hhpopup.html
 
.topic 2
well this is just another example. Great isn't it?