65.9K
CodeProject is changing. Read more.
Home

Enabling context help in a PropertySheet embedded in another PropertySheet

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.31/5 (4 votes)

Jun 14, 2005

CPOL
viewsIcon

39945

Context sensitive help does not work for a PropertySheet embedded within the page of another PropertySheet.

Overview

This is a very short article to show a solution for context sensitive help problem for a propertysheet embedded within the page of another propertysheet. The help command gets swallowed by the system and help is not shown.

While recently upgrading the help system for one of our applications from WinHelp to HTML help, we noticed that the context sensitive help of a propertysheet embedded in the page of another sheet was not being shown. After much tracing around through the MFC source and reading MSDN, I realized that when a propertysheet gets the WM_HELPINFO message which is sent by ::IsDialogMessage(), it is not processed correctly due to the sheet having the window style of WS_CHILD.

The fix

Once I had identified the problem, the fix comes quite easily.

  1. Inherit your own class from CPropertySheet.

    This class should be used to replace the existing embedded sheet object in your property page.

  2. Map the WM_HELPINFO message.

    This is the message we need to map to fix the problem.

// add the header function prototype
afx_msg BOOL OnHelpInfo(HELPINFO * pHelpInfo);

// add the message map entry
ON_WM_HELPINFO()

// add the function code
BOOL CPropertySheetEx::OnHelpInfo(HELPINFO* pHelpInfo)
{
    BOOL ret = FALSE;
    bool handled = false;

    if (GetStyle() & WS_CHILD)
    {
        // were an embedded property sheet, need to pass up 
        // the chain to get this message processed correctly
        CWnd * pWnd = GetParent();
        while (pWnd != NULL && pWnd->GetStyle() & WS_CHILD)
        {
            // move up the window heirarchy while 
            // finding child windows
            pWnd = pWnd->GetParent();
        }
        if (pWnd != NULL)
        {
            ret = GetParent()->GetParent()->SendMessage(WM_HELP, 
                                         0, (LPARAM)(pHelpInfo));
            handled = true;
        }
        // the sheet does not have a non child parent, 
        // some kind of problem!
        ASSERT(handled);    
    }
    if (!handled)
    {
        ret = CPropertySheet::OnHelpInfo(pHelpInfo);
    }
    return ret;
}

And that's it, everything should now work correctly.