FIX: F1 Help Routed Wrongly for Additional Top-Level Windows

Last reviewed: September 19, 1997
Article ID: Q167961
The information in this article applies to:
  • The Microsoft Foundation Classes (MFC) included with: - Microsoft Visual C++ for Windows, 16-bit edition, version 1.52 - Microsoft Visual C++, 32-bit Editions, versions 2.0, 2.1, 2.2

SYMPTOMS

When you press the F1 key to display help for a window that is not a descendant of the application's main window, it does not display the proper help text.

CAUSE

MFC assumes that the currently active window is a descendant of the main window. So, for windows that are children of the desktop, MFC routes WM_COMMANDHELP to the mainframe instead of the active window.

RESOLUTION

Add an ID_HELP command handler in the CMainFrame that searches for the active window based on the window with the current focus and walks up the parent tree sending the WM_COMMANDHELP message. Use the code shown in the sample code section.

STATUS

Microsoft has confirmed this to be a bug in the Microsoft products listed at the beginning of this article. This problem has been fixed in Visual C++ version 4.0.

MORE INFORMATION

When you press the F1 key, an ID_HELP command message is generated and is usually routed and handled in the application's main frame message map using CFrameWnd::OnHelp(). Then, the OnHelp functions (CFrameWnd and CWnd) finds the active window using ::GetLastActivePopup(hWnd), thereby passing the handle to the application's main frame. Unfortunately, this only returns windows handles that are a descendant of hWnd. If another top-level window was active when you pressed the F1 key, the main frame window is still used and the subsequent WM_COMMANDHELP messages is never sent to the correct active window.

The sample code below fixes this bug by sending the message to the window with the current focus before going through the default MFC logic.

Sample Code

   //////////////////////////////////////
   // HEADER file
   class CMainFrame : public CMDIFrameWnd
   {
      afx_msg void OnHelp();
      ...

   //////////////////////////////////////
   // IMPLEMENTATION file
   #include "afxpriv.h"

   BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)
   ...
      ON_COMMAND(ID_HELP, CMainFrame::OnHelp)
   END_MESSAGE_MAP()

   void CMainFrame::OnHelp()
   {
      if (m_dwPromptContext != 0)
      {
         if (m_dwPromptContext !=
            HID_BASE_PROMPT + AFX_IDP_FAILED_TO_LAUNCH_HELP)
            AfxGetApp()->WinHelp(m_dwPromptContext);
         return;
      }

      // attempt to get help from whoever has the focus
      HWND hWnd = ::GetFocus();
      while (hWnd != NULL)
      {
         // attempt to process help
         if (::SendMessage(hWnd, WM_COMMANDHELP, 0, 0))
            return;

         // check next parent/owner in the parent/owner chain
         CWnd* pWnd = CWnd::FromHandlePermanent(hWnd);
         if (pWnd != NULL)
            hWnd = pWnd->GetOwner()->GetSafeHwnd();
         else
            // otherwise, return parent in the Windows sense
            hWnd = ::GetParent(hWnd);
      }
      CWnd::OnHelp();

(c) Microsoft Corporation 1997, All Rights Reserved. Contributions by Adam Kim, Microsoft Corporation
Keywords          : MfcDocView kbprg kbbuglist kbfixlist
Technology        : kbMfc
Version           : 1.52 2.0 2.1 2.2
Platform          : NT WINDOWS
Issue type        : kbbug
Solution Type     : kbfix


================================================================================


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: September 19, 1997
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.