Click here to Skip to main content
Click here to Skip to main content

How to enable context sensitive help for individual controls on a FormView

By , 25 Oct 2002
Rate this:
Please Sign up or sign in to vote.

Overview

Context sensitive help can be a powerful feature for any program that you develop. But FormView's are treated differently, with all the controls on it as a single help topic. That may not be what you want!

Implementing Context Help

To get context sensitive help to work for the controls on your FormView, you need to add the following to your CFormView derived class:

  • Map the WM_HELPHITTEST, and the WM_COMMANDHELP messages for your FormView
  • The WM_HELPHITTEST is sent by the system on clicking on an area of a window after enabling context sensitive help. The WM_COMMANDHELP message is sent when the user presses the F1 help key. We need to get our FormView to respond to these messages correctly and from there display the correct Help topic ID in the help file. The function prototypes for these messages and code looks like this:

    // in your FormViews header file
    afx_msg LRESULT OnHelpHitTest(WPARAM wParam, LPARAM lParam);
    afx_msg LRESULT OnCommandHelp(WPARAM wParam, LPARAM lParam);
     
    // in your FormViews MESSAGE_MAP
    ON_MESSAGE(WM_HELPHITTEST, OnHelpHitTest)
    ON_MESSAGE(WM_COMMANDHELP, OnCommandHelp)
    
    // Your views class function
    
    LRESULT CYourFormView::OnHelpHitTest(WPARAM wParam, LPARAM lParam)
    {
        // message is sent to us as follows:
        // dwContext = ::SendMessage(hWnd, WM_HELPHITTEST,0,MAKELONG(point.x, point.y));
        // WPARAM = 0 ;
        // LPARAM = Point clicked
     
        CPoint p((DWORD)lParam) ;
     
        ClientToScreen(&p) ;
     
        CWnd *pWnd = WindowFromPoint(p) ;
        if (pWnd != NULL)
        {
            // convert to correct help ID, see makehelp.bat
            if (pWnd == this)
                return IDD + 0x20000 ;    
            else
                return pWnd->GetDlgCtrlID() + 0x60000 ; // see later about 0x60000
            }
        return 0 ;            // failed!
    }
    
    LRESULT    CContextHelpView::OnCommandHelp(WPARAM wParam, LPARAM lParam)
    {
        // message is sent to us as a test to see whether we make WinHelp appear
        // return non-zero if we process the message
        // wParam = 0, not used
        // lParam = 0, not used
        CWnd *pWnd = GetFocus();
        if (pWnd != NULL)
            {
            DWORD helpID;
            // convert to correct help ID
            if (pWnd == this)
                helpID = IDD + 0x20000 ;
            else
                helpID = pWnd->GetDlgCtrlID() + 0x60000 ;
            // we have a control with the focus, pop-up help for it
            AfxGetApp()->WinHelp(helpID);
            return TRUE;
            }
        return FALSE;        // let default handling process it
    }
    
  • Setup your makehelp.bat file to map IDC_* control ID's to help topics HIDC_* ones
  • By default your help file does not support by control help ID's. To get them to work you need to cause the MakeHelp.bat file map the ID's across to the correct Help ID range. I did this by adding the following lines to the MakeHelp.bat file, which should be present in your project's main directory

    @echo off
    REM -- First make map file from Microsoft Visual C++ generated resource.h
    echo // MAKEHELP.BAT generated Help Map file.  Used by CONTEXTHELP.HPJ.
    > "hlp\ContextHelp.hm"
    echo. >> "hlp\ContextHelp.hm"
    echo // Commands (ID_* and IDM_*) >> hlp\ContextHelp.hm"
    makehm ID_,HID_,0x10000 IDM_,HIDM_,0x10000 resource.h >> "hlp\ContextHelp.hm"
    echo. >> "hlp\ContextHelp.hm"
    echo // Prompts (IDP_*) >> "hlp\ContextHelp.hm"
    makehm IDP_,HIDP_,0x30000 resource.h >> "hlp\ContextHelp.hm"
    echo. >> "hlp\ContextHelp.hm"
    echo // Resources (IDR_*) >> "hlp\ContextHelp.hm"
    makehm IDR_,HIDR_,0x20000 resource.h >> "hlp\ContextHelp.hm"
    echo. >> "hlp\ContextHelp.hm"
    echo // Dialogs (IDD_*) >> "hlp\ContextHelp.hm"
    makehm IDD_,HIDD_,0x20000 resource.h >> "hlp\ContextHelp.hm"
    echo. >> "hlp\ContextHelp.hm"
    echo // Frame Controls (IDW_*) >> "hlp\ContextHelp.hm"
    makehm IDW_,HIDW_,0x50000 resource.h >> "hlp\ContextHelp.hm"
    echo. >> "hlp\ContextHelp.hm"
    echo // Commands (IDC_*) >> "hlp\ContextHelp.hm"
    makehm IDC_,HIDC_,0x60000 resource.h >> "hlp\ContextHelp.hm"
    REM -- Make help for Project CONTEXTHELP
    
    
    echo Building Win32 Help files
    start /wait hcw /C /E /M "hlp\ContextHelp.hpj"
    if errorlevel 1 goto :Error
    if not exist "hlp\ContextHelp.hlp" goto :Error
    if not exist "hlp\ContextHelp.cnt" goto :Error
    echo.
    if exist Debug\nul copy "hlp\ContextHelp.hlp" Debug
    if exist Debug\nul copy "hlp\ContextHelp.cnt" Debug
    if exist Release\nul copy "hlp\ContextHelp.hlp" Release
    if exist Release\nul copy "hlp\ContextHelp.cnt" Release
    echo.
    goto :done
    
    :Error
    echo hlp\ContextHelp.hpj(1) : error: Problem encountered creating help file
    
    :done
    echo.
    

    Adding these lines will make sure that your help files .hm file has the ID's needed to map the controls correctly. I chose the the value 0x60000 as the base range for dialog controls in the help file, if you use a different value, you need to modify the CYourFormView::OnHelpHitTest() function to return the control ID + the base value.

  • Add the help topics to your help file
  • Once you have the context sensitive help working, you need to map the topics in your help file to prove that everything is working correctly. The minimum you need to add per topic is:

    ${\footnote Button 4 topic}
    K{\footnote Button 4 topic}
    #{\footnote HIDC_BUTTON4}
    {\b Button 4 topic}\line
    This comes up when you click on button 4 for context help\par
    \line
    \page

Included at the top of this article is a working example

Updates

  • 25-10-2002 Now works with the F1 key as requested by Joel Charbonnet, example updated
  • Enjoy!

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Roger Allen
Software Developer (Senior) Sirius Analytical Instruments
United Kingdom United Kingdom
A research and development programmer working for a pharmaceutical instrument company for the past 17 years.
 
I am one of those lucky people who enjoys his work and spends more time than he should either doing work or reseaching new stuff. I can also be found on playing DDO on the Cannith server (Send a tell to "Maetrim" who is my current main)
 
I am also a keep fit fanatic, doing cross country running and am seriously into [url]http://www.ryushinkan.co.uk/[/url] Karate at this time of my life, training from 4-6 times a week and recently achieved my 1st Dan after 6 years.

Comments and Discussions

 
GeneralDoes not work for dialogs PinmemberSam Hobbs27-Feb-03 8:03 
GeneralRe: Does not work for dialogs PinmemberHerbert Illfelder5-Mar-03 11:49 
GeneralRe: Does not work for dialogs PinmemberSam Hobbs5-Mar-03 12:57 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.140415.2 | Last Updated 26 Oct 2002
Article Copyright 2002 by Roger Allen
Everything else Copyright © CodeProject, 1999-2014
Terms of Use
Layout: fixed | fluid