### Hello World Version 5: Adding Canvases, a List Box, Native System Functions, and Help

Version 5 of the Hello World application shows you how to add the following:

- Split canvases for showing multiple control windows in the client window
- List box for selecting text for a static text window
- Help window to provide users with information about the frame window
- 2D-graphics and drawing canvases

The main window for version 5 of the Hello World application looks like this:

#### Listing the Hello World Version 5 Files

The following files contain the code used to create version 5:

File | Type of Code
--- | ---
ahellow5.cpp | Source code for main procedure and AHelloWindow class
ahellow5.hpp | Class header file for AHelloWindow
ahellow5.h | Symbolic definitions file shared by all source files
adialog5.cpp | Source code for the ATextDialog class
adialog5.hpp | Class header file for ATextDialog
aearthw5.cpp | Source code for the AEarthWindow class
aearthw5.hpp | Class header file for AEarthWindow
ahellow5.rc | Resource file source
ahellow5.ico | Icon file
ahellow6.rtf and ahello6.hpj | Help source files for Windows help
ahello6.ipf | IPF help source files

#### The Primary Source Code File

The ahellow5.cpp file contains the source code for the main procedure and AHelloWindow class functions. The tasks performed by this code are described in the following sections.

The AHelloWindow Class Header File

The ahellow5.hpp file contains the class definition and interface specifications for the AHelloWindow class, with a few modifications for version 5.

#### The Symbolic Definitions File

The ahellow5.h file contains the symbolic definitions for this application. These symbols and their definitions provide the IDs for the application window components.

#### The Text Dialog Source Code File

The adialog5.cpp file contains the source code for the ATextDialog class, modified for help in version 5.

#### The ATextDialog Class Header File

The adialog5.hpp file contains the class definition and interface specifications for the ATextDialog class. The adialog5.hpp file is the same as the adialog4.cpp file.

#### The Earth Window Source File

The aearthw5.cpp file contains the source code for the Earth window graphic that is drawn using native-system graphics calls.

#### The AEarthWindow Class Header File

The aearthw5.hpp file contains the class definition and interface specifications for the AEarthWindow class.

#### The Resource File

Version 5 of the Hello World application provides a resource file, ahellow5.rc, which contains all the resources from version 4, as well as additional resources, including a help table.

#### The Icon File

The ahellow5.ico file is used as the icon that displays when the application is minimized. This icon is the same as for

#### The Help Window Source Files

The ahellow5.ipf file contains the text and IPF or RTF tags used to produce the help information for the Hello World application. IPF uses a tag language to format the text that appears in a help window. For example, :p. is the paragraph tag, which you use to start a new paragraph.

The OS/2 makefiles provided with Hello World version 5 use the IPFC compiler, provided by the OS/2 Developer's Toolkit, to compile the help file.

Refer to the OS/2 Information Presentation Facility Guide and Reference or the IPF Information Presentation Facility User and Programmer's Guide for descriptions of other tags used in the help source file.

The Motif makefiles provided with Hello World version 5 use the IPFC compiler as well.

The makefiles provided with Hello World version 5 use the native Windows help compiler, by default, which uses Rich Text Format (RTF). You can also use IPFC/X compiler to compile the help file by specifying `nmake USE_IPF=1` for the makefile.

A sample file, ahellow5.rtf is provided with the Hello World version 5. The following code is taken from the ahellow5.rtf file:

    {\rtf1\ansi \deff2
    {\fonttbl{\f0\froman Tms Rmn;}{\f1\fdecor Symbol;}{\f2\fswiss Helv;}{\f3\fmodern pica;}{\f4\fmodern Courier;}{\f5\fswiss Univers (WN);}}
    {\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;
    \red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue127;\red0\green127\blue127;\red0\green127\blue0;\red127\green0\blue127;\red127\green0\blue0;\red127\green127\blue0;\red127\green127\blue127;
    \red192\green192\blue192;}
    \sectd \pard \f2 \fs20
    ${\footnote Table of Contents}
    #{\footnote IPFToRTFContents}\par \b {\fs28 Table of Contents:}\b0 \par \ri90\qr{\uldb Index}{\v IPFToRTFIndex}\par \ri0\ql
    \par\li360\fi-180
    {\uldb C++ Hello World - Application Help}
    \par\li720\fi-180
    {\uldb C++ Hello World - Main Window Help}{\v 100}

    \page \li0
    ${\footnote C++ Hello World - Application Help}\par \pard \cf1 \f2 \fs28 \tx0 \b C++ Hello World - Application Help\b0 \par \pard \fs20 \par \pard \li0 \fi0 \tx0 This file contains the help for the C++ Hello World Application.
    \par \pard
    \page \li0
    ${\footnote C++ Hello World - Main Window Help}
    #{\footnote 100}\par \pard \cf1 \f2 \fs28 \tx0 \b C++ Hello World - Main Window Help\b0 \par \pard \fs20
    {K{\footnote ;main window help}}\par \pard \li0 \fi0 \tx0 This is the help panel for the main window.
    The main window contains the following areas:
    \par \pard
    \par \li270 \fi-270 {\f1 \'B7} The title bar icon, which provides access to the system menu
    \par \par \li270 \fi-270 {\f1 \'B7} The window title, which displays the title of the window
    \par \par \li270 \fi-270 {\f1 \'B7} The menu bar, which allows the user to select specific actions
    \par \par \li270 \fi-270 {\f1 \'B7} A status line, which contains the current alignment
    \par \par \li270 \fi-270 {\f1 \'B7} A client area, which is divided into three areas:

You also need a project file (.HPJ) which is used by the Windows Help Compiler (HCW or HC31) to create the .HLP file.

#### Exploring Hello World Version 5

The following sections describe each of the tasks performed by version 5 of the Hello World application that were not described for previous versions.

#### Constructing the Client Window with Split Canvases

In previous versions of the Hello World application, the client window contained a simple static text window. Version 5 provides an sample of a client window with three visible windows:

- A static text window containing "Hello World!!!" from the previous versions
- A new static text window with a graphical view of the earth from space
- A new list box containing different language versions of the phrase, "Hello World!!!"

The two new windows are described in detail in later sections of this chapter.

Use the ICanvas class for a common and easy-to-use method for placing multiple windows into a client window. Version 5 places the two static text windows into a horizontal split canvas, called helloCanvas, and then places helloCanvas and the list box into a vertical canvas called clientWindow. It also places windows in a split canvas by identifying the canvas as the control window's parent. For example, the split canvases in the client area of the Hello World main window are initialized in the AHelloWindow constructor in the ahellow5.cpp file, as follows:

       ,clientWindow(WND_CANVAS, this, this)
       ,helloCanvas(WND_HCANVAS,
                    &clientWindow,
                    &clientWindow,
                    IRectangle(),
                    IWindow::visible |
                    ISplitCanvas::horizontal)
       ,hello(WND_HELLO,
              &helloCanvas,
              &helloCanvas)
       ,statusLine(WND_STATUS, this, this)
       ,earthWindow(WND_EARTH, &helloCanvas)
       ,listBox(WND_LISTBOX,
                &clientWindow,
                &clientWindow,
                IRectangle(),
                IListBox::defaultStyle() |
                IControl::tabStop |
                IListBox::noAdjustPosition)

The order in which you place your child windows into a split canvas determines the order in which they will be seen. For example, the AHelloWindow::hello static text window appears above the earthWindow static text window because it is created as the first child of the helloCanvas window. Likewise, the helloCanvas window appears to the left of the list box because it is created before the list box.

After initializing the canvases, the following statements from the ahellow5.cpp file set the client window and the proportions for its child windows in the vertical split canvas.

    setClient(&clientWindow);
    clientWindow.setSplitWindowPercentage(&helloCanvas, 60);
    clientWindow.setSplitWindowPercentage(&listBox, 40);

#### Creating and Using a List Box

Hello World version 5 provides you with the ability to change the Hello World text by selecting different language versions of the phrase "Hello World" from a list box. The IListBox object in Hello World version 5 is called listBox and is initialized in the AHelloWindow constructor in ahellow5.cpp as follows:

       ,listBox(WND_LISTBOX,
                &clientWindow,
                &clientWindow,
                IRectangle(),
                IListBox::defaultStyle() |
                IWindow::tabStop |
                IListBox::noAdjustPosition)

The inherited tabStop style indicates that you can tab to the list box. The noAdjustPosition style prevents the list box from being automatically resized when an item in the list does not fit inside the current window.

One way you can populate the newly created list box is to use IListBox::addAscending. This function adds a text string to the list box in ascending alphabetical order. For example, Hello World version 5 uses the addAscending function to load a variable number of strings from the resource file into the list box as follows:

    for (int i=0;i<HI_COUNT;i++ )
       listBox.addAscending(HI_WORLD+i);

The strings are defined in the resource file, ahellow5.rc, as follows:

    // Change HI_COUNT in ahellow5.h to change number of HIs used.
    HI_WORLD,      "Hello, World!"              //English
    HI_WORLD+1,    "Hi, World!"                 //American
    HI_WORLD+2,    "Howdy, World!"              //Southern American
    HI_WORLD+3,    "Alo, Mundo!"                //Portuguese
    HI_WORLD+4,    "Ola, Mondo!"                //Spanish
    HI_WORLD+5,    "Hallo wereld!"              //Dutch
    HI_WORLD+6,    "Hallo Welt!"                //German
    HI_WORLD+7,    "Bonjour le monde!"          //French
    HI_WORLD+8,    "Put your language here!"    //Add more items, too!

HI_WORLD is a symbolic definition for the constant string ID of the first string. HI_COUNT is the symbolic definition for the constant number of strings to load. In this sample, HI_COUNT is defined as 8. Therefore, only HI_WORLD through HI_WORLD+7 are loaded. You can add another item to the list by changing the HI_WORLD constant in the symbolic definition file, ahellow5.h, and adding your strings to the HI_WORLD list.

Once you create the list box and fill it with items, define a select handler for processing list box selections. Hello World version 5 provides a select handler class, called ASelectHandler. (It is similar to the command handler added in Hello World version 3.)

The three differences are as follows:

- The handler function overridden is called selected, instead of command.
- The event passed into the function is an IControlEvent, instead of an ICommandEvent.
- The function being called processes selections made to our list box.

The ASelectHandler is defined in the AHelloWindow class header file, ahellow5.hpp, using the following class definition:

    class ASelectHandler : public ISelectHandler
    {
      public:
    /*------------------------------ Constructor -----------------------------|
    | Construct the object with:                                              |
    | 1) A pointer to the main frame window                                   |
    -------------------------------------------------------------------------*/
        ASelectHandler(AHelloWindow *helloFrame);

    /*------------------------------ Destructor ------------------------------|
    | Destruct the object with:                                               |
    | 1) No parameters                                                        |
    -------------------------------------------------------------------------*/
        virtual
         ~ASelectHandler() { }

      protected:
    /*------------------------ Override Selected Function --------------------|
    | The selected() function is called to handle list box selection events.  |
    |------------------------------------------------------------------------*/
        virtual bool
          selected(IControlEvent& ctlEvent);

      private:
        AHelloWindow
         *frame;
    };

The ASelectHandler::selected function and the AHelloWindow::setTextFromListBox function provide the selection event handling for version 5. These functions are listed below and can be found in the ahellow5.cpp file:

    AHelloWindow &
      AHelloWindow :: setTextFromListBox()
    {

    /*------------------------------------------------------------------------|
    |  Create a cursor to the list box.  Using the default filter for a       |
    |    list box cursor, selectedItems, causes the setToFirst() function     |
    |    to position the cursor to the first selected item.                   |
    |  Set the hello IStaticText control text value.                          |
    |------------------------------------------------------------------------*/
      IListBox::Cursor lbCursor(listBox);
      lbCursor.setToFirst();
      hello.setText(listBox.elementAt(lbCursor));

      return (*this);                       //Return a reference to the frame
    }; /* end AHelloWindow :: setTextFromListBox() */

    :
    :

    bool
      ASelectHandler :: selected(IControlEvent & evt)
    {

    /*------------------------------------------------------------------------|
    |  Call the AHelloWindow::setTextFromListBox function for the frame used  |
    |    to construct this select handler.                                    |
    |------------------------------------------------------------------------*/
      frame->setTextFromListBox();

      return (true);                        //Event is always processed
    } /* end ASelectHandler :: selected(...) */

The setTextFromListBox function introduces a new Open Class Library class, IListBox::Cursor. Use a list box cursor to scan through the items in a list box. The constructor used in Hello World version 5 for creating the lbCursor object contains only one argument, the list box object to be scanned. You can also specify an additional argument, called a filter, to specify if you want to scan all the items in the list or only the items that are selected. Because the setTextFromListBox function looks for the first item selected, the default filter type, selected, is used.

The IListBox::Cursor::setToFirst function positions the cursor to the first selected item. Then, the IListBox::elementAt function uses the cursor to locate and return the text string identified by the first selected item. Hello World version 5 uses the string value to set the Hello World text.

Like the command handler in Hello World version 3, the ASelectHandler::selected function is not called until you attach the handler to the proper window. In this case, you attach the select handler to the list box using the ASelectHandler inherited IHandler function, handleEventsFor. This causes the ASelectHandler::selected function to be called each time you select a list box item.

To stop handling selection events, use the stopHandlingEventsFor function, again specifying the list box.

#### Using Native System Functions and Graphics

The aearthw5.hpp and aearthw5.cpp files contain the class header and implementation for the AEarthWindow class. Refer to the comments and code in these files for examples of the following:

- Displaying a graphics window using IDrawingCanvas, IGEllipse, and IGraphicBundle objects
- Creating and using an IResizeHandler object to resize the window whenever it is changed
- Representing geometric shapes using IRectangle and IPoint objects
- Using IColor objects as arguments to native function calls

#### Setting Up the Help Area

Use the following steps to create IPF help information for your application:

1. Create a file containing the help information.

   Create the source text that displays in your application's help window using the IPF format (.ipf file) for the OS/2 operating system and the IPF/X format (.ipf file) for the Windows and Motif environments. Compile your file into a help file (.hlp file) using the IPFC compiler.

   Refer to the Information Presentation Facility documentation for descriptions of the tags you use to create the source .ipf file.

   For an example of a .ipf source file, see the Hello World version 5 ahellow5.ipf file.

2. Define the help window title and the help submenu in your resource file. defined in the Windows ahellow5.rc file, as follows:

       STR_HTITLE, "C++ Hello World - Help Window"   //Help window title string

       POPUP     "&Help"                   ,  MI_HELP  ,  RIGHTJUSTIFY
         BEGIN
           MENUITEM  "&General help..."        ,  SC_HELPEXTENDED  /*MIS_SYSCOMMAND*/
           MENUITEM  "&Keys help..."           ,  SC_HELPKEYS  /*MIS_SYSCOMMAND*/
           MENUITEM  "Help &index..."          ,  SC_HELPINDEX  /*MIS_SYSCOMMAND*/
         END

   The OS/2 .rc file appears as follows:

       STR_HTITLE, "C++ Hello World - Help Window"   //Help window title string

       SUBMENU "~Help", MI_HELP, MIS_HELP            //Help submenu
         BEGIN
           MENUITEM "~General help...",   SC_HELPEXTENDED, MIS_SYSCOMMAND
           MENUITEM "~Keys help...",      SC_HELPKEYS, MIS_SYSCOMMAND
           MENUITEM "Help ~index...",     SC_HELPINDEX, MIS_SYSCOMMAND
         END

   MI_HELP is the help menu ID.

   Normally, you specify MIS_HELP for a menu item to cause a help event, rather than a command event, to be posted when the menu item is selected.

   When you specify MIS_HELP (OS/2) or RIGHTJUSTIFY (Windows) for a submenu item, Motif automatically positions the item to the far right of the menu bar. OS/2 PM ignores MIS_HELP specified on submenu items. Windows NT 3.51 ignores RIGHTJUSTIFY specified on submenu items.

   When MIS_SYSCOMMAND is specified with the predefined SC_HELP* IDs, a system command event is generated. The default system command handler recognizes the predefined IDs and shows the appropriate help panel, except for SC_HELPKEYS, which by default does nothing. SC_HELP* IDs are defined in the `<icconst.h>` file. You can override this default processing for SC_HELPKEYS, using an IHelpHandler, which is described in a later step.

3. Define a help table in the resource file.

   The help table defines the relationship between the window ID and the general or contextual panel ID that is defined in the .ipf file. The following help table is defined in the resource file, ahellow5.rc, for Hello World version 5:

       HELPTABLE HELP_TABLE
         BEGIN
           HELPITEM WND_MAIN,        SUBTABLE_MAIN,   100
           HELPITEM WND_TEXTDIALOG,  SUBTABLE_DIALOG, 200
         END

       HELPSUBTABLE SUBTABLE_MAIN                      //Main window help subtable
         BEGIN                                         //
           HELPSUBITEM WND_HELLO, 100                  //Hello static text help ID
           HELPSUBITEM WND_LISTBOX,102                 //List box help ID
           HELPSUBITEM MI_EDIT, 110                    //Edit menu item help ID
           HELPSUBITEM MI_ALIGNMENT, 111               //Alignment menu item help ID
           HELPSUBITEM MI_LEFT, 112                    //Left command help ID
           HELPSUBITEM MI_CENTER, 113                  //Center command help ID
           HELPSUBITEM MI_RIGHT, 114                   //Right command help ID
           HELPSUBITEM MI_TEXT, 199                    //Text command help ID
         END                                           //

       HELPSUBTABLE SUBTABLE_DIALOG                    //Text dialog help subtable
         BEGIN                                         //
           HELPSUBITEM DID_ENTRY, 201                  //Entry field help ID
           HELPSUBITEM DID_OK, 202                     //OK command help ID
           HELPSUBITEM DID_CANCEL, 203                 //Cancel command help ID
         END                                           //

   WND_HELLO and WND_LISTBOX are control IDs, MI_* are menu item IDs, and the DID_* are push button IDs. Each window ID is related to a help panel ID. In the preceding example, WND_MAIN and WND_HELLO both correspond to help panel ID 100. That is, pressing the F1 key in the main window area displays the same help panel as selecting General help... from the Help submenu.

4. Create a help window object for your application window.

   Use the IHelpWindow class to associate help information with an application window. Hello World version 5 defines the private data member, helpWindow, as an IHelpWindow object. It is initialized in the AHelloWindow constructor in ahellow5.cpp using the following statement:

       ,helpWindow(HELP_TABLE,this)

   The first parameter identifies the help table defined in the resource file. The second parameter identifies the application window for which the help is being provided.

   Use the IHelpWindow::addLibraries member function to associate a help file with a help window. The AHelloWindow constructor in Hello World version 5 provides an example:

       helpWindow.addLibraries("ahellow5.hlp");

   You can set the title of the help window by using the IHelpWindow::setTitle member function. The following code sets the title from a string defined in the resource file:

       helpWindow.setTitle(STR_HTITLE);

5. Create a help handler by creating an IHelpHandler derived class.

   A help handler processes help events. Create your own help handler class derived from IHelpHandler to provide help event processing that is unique to your application. Hello World version 5 uses a help handler only to display the keys help panel describing accelerator key definitions.

   To override keys help processing, do the following:

   1. Define a new class that is derived from IHelpHandler, as shown in the Hello World version 5 class definition file, ahellow5.hpp.

          /**************************************************************************
          * Clas AHelpHandler -- Provides help for keys                             *
          **************************************************************************/
          class AHelpHandler : public IHelpHandler
          {
            public:

          /*------------------------------ Destructor ------------------------------|
          | Destruct the object with:                                               |
          | 1) No parameters                                                        |
          -------------------------------------------------------------------------*/
              virtual ~AHelpHandler() { }

            protected:
          /*----------------------- Override keysHelpId Function -------------------|
          | The keysHelpId() function is called to set the event result to the      |
          |   ID within the Hello World help libraries for Keys Help.               |
          |------------------------------------------------------------------------*/
              virtual bool
                keysHelpId(IEvent& evt);
          };

   2. Provide the overridden virtual function keysHelpId, which is called when keys help is requested. The following code, from the Hello World version 5 ahellow5.cpp file, shows how to implement this function.

          bool AHelpHandler :: keysHelpId(IEvent& evt)
          {
            evt.setResult(1000);                  //1000=keys help ID in
                                                  //  ahellow5.ipf file

            return (true);                        //Event is always processed
          } /* end AHelpHandler :: keysHelpId(...) */

      In the preceding code, the help panel ID for the Hello World version 5 keys help is set in the event result.

   3. Start and stop help events processing.

      Your help handler, previously described, does not begin handling help events until you use the handleEventsFor member function. For example, the following code causes the helpHandler to begin processing help events for this frame window:

          helpHandler.handleEventsFor(this);

      Typically, you include this statement in the constructor for the frame window.

      Note that the window that handles help events must be an associated window. That is, you should identify the window as the associated window on the IHelpWindow constructor or explicitly identify the window as an associated window using the IHelpWindow::setAssociatedWindow function.

      When you want to stop handling help events, for example, when you close your frame window, use the stopHandlingEventsFor member function, as follows:

          helpHandler.stopHandlingEventsFor(this);

      You typically include this statement in the destructor for the frame window.

   4. Associate secondary frame windows with the parent window's help window.
   5. Attach the following special handler to child frame windows in your application. This handler is needed so that help processes correctly for these windows.

          class ChildFrameHelpHandler : public IHandler {
          typedef IHandler Inherited;
          /*******************************************************************************
          *  This handler enables the IPF Help Manager to use help tables to display    *
          *  contextual help for a child frame window (one whose parent window is not    *
          *  the desktop).  This handler should only be attached to child frame windows. *
          *******************************************************************************/
          public:
          virtual ChildFrameHelpHandler
           &handleEventsFor       ( IFrameWindow* frame ),
           &stopHandlingEventsFor ( IFrameWindow* frame );
          protected:
          virtual bool
            dispatchHandlerEvent  ( IEvent& evt );
          ChildFrameHelpHandler
           &setActiveWindow       ( IEvent& evt, bool active = true );
          private:
          virtual IHandler
           &handleEventsFor       ( IWindow* window  ),
           &stopHandlingEventsFor ( IWindow* window  );
          };

          bool ChildFrameHelpHandler :: dispatchHandlerEvent ( IEvent& evt )
          {
            switch ( evt.eventId() )
            {
               case WM_ACTIVATE:
                  setActiveWindow(evt, evt.parameter1().number1());
                  break;
               case WM_HELP:
                  setActiveWindow(evt, true);
                  break;
               default:
                  break;
            } /* endswitch */

            return false;                     // Never stop processing of event
          }

          ChildFrameHelpHandler&
            ChildFrameHelpHandler :: setActiveWindow ( IEvent& evt,
                                                       bool active )
          {
            IHelpWindow* help = IHelpWindow::helpWindow(evt.window());
            if (help)
            {
               IFrameWindow* frame = 0;
               if (active)
               {
                  frame = (IFrameWindow*)evt.window();
               }
               help->setActiveWindow(frame, frame);
            }
            return *this;
          }

          ChildFrameHelpHandler&
            ChildFrameHelpHandler :: handleEventsFor ( IFrameWindow* frame )
          {
            IASSERTPARM(frame != 0);
            Inherited::handleEventsFor(frame);
            return *this;
          }

          ChildFrameHelpHandler&
            ChildFrameHelpHandler :: stopHandlingEventsFor ( IFrameWindow* frame )
          {
            IASSERTPARM(frame != 0);
            Inherited::stopHandlingEventsFor(frame);
            return *this;
          }

          IHandler& ChildFrameHelpHandler :: handleEventsFor ( IWindow* window  )
          {           // private to hide version in IHandler
            ITHROWLIBRARYERROR(IC_MEMBER_ACCESS_ERROR,
                               IErrorInfo::invalidRequest,
                               IException::recoverable);
            return *this;
          }

          IHandler& ChildFrameHelpHandler :: stopHandlingEventsFor ( IWindow* window  )
          {           // private to hide version in IHandler
            ITHROWLIBRARYERROR(IC_MEMBER_ACCESS_ERROR,
                               IErrorInfo::invalidRequest,
                               IException::recoverable);
            return *this;
          }

#### Assigning Help IDs to Windows

You can assign helpIDs directly to windows by using `IWindow::setHelpId( unsigned long topicId );` while maintaining portability. When F1 is pressed, the window with focus is then be queried for its context helpID and if one is found, it is used to identify the help panel to display. If one is not found and there is a help table, it is searched for the appropriate helpID to use.

If you are not using a help table, the helpId of the active frame is used as the general help panel.

#### Using Native Windows Help Files with IHelpWindow

By default, IHelpWindow uses the native help for the platform to handle help requests using a .hlp file that was created from RTF or IPF source. This allows the code you write to be portable while giving your users native look-and-feel. IPF help files are also portable between the various platforms. RTF help files are not portable. In addition, some functions provided by IPF are not available when using Windows native help (RTF). The major differences are as follows:

- There is only one instance of Windows Help for all your applications.
- The size and position of WinHelp is NOT relative to any particular application.
- IPF uses a set of filenames to locate help; WinHelp is one file at a time, but you must still use IHelpWindow::addLibraries to change the help file name.
- IPF help has sections for CONTENTS, INDEX, KEYS, GENERAL, and USING. WinHelp has HELP_FINDER and HELPONHELP.
- Only IPF allows the application to change the Help Manager menu and accelerators.
- Only IPF allows the application to set a title for each help object.
- Only IPF allows querying of handles for IPF sections, such as the coverpage or contents.
- Only IPF allows the application to toggle showing of the help IDs in the help manager window titles.

Events and Event Handlers
Canvas Controls
Resources

Converting Application Resources
Adding Menus to your Application
Layout Using Canvas Controls
Creating and Using Text Controls
Using List and Slider Controls

IEvent
ICanvas
ICommandHandler
IHandler
IHelpWindow
IHelpHandler
IListBox
IMenu
IMenuBar