INFO: Using Accelerator Keys with Modal Dialog Box Main Window

Last reviewed: October 10, 1997
Article ID: Q100770
The information in this article applies to:
  • The Microsoft Foundation Classes (MFC) included with:

        - Microsoft Visual C++ for Windows, versions 1.0, 1.5, 1.51, 1.52
        - Microsoft Visual C++ 32-bit Edition, versions 2.0, 2.1, 4.0
    

SUMMARY

The TRACER sample application, provided with the Microsoft Foundation Class Library, uses a modal dialog box as its main window. Many applications that use this technique also include a main menu on the dialog box (the TRACER sample does not use a menu). Typically, one or more of the menu items has a keyboard accelerator associated with it. The text below details the steps required to add a menu and keyboard accelerators to the TRACER sample.

MORE INFORMATION

A typical application, developed for the Windows operating system using C and the Microsoft Windows Software Development Kit (SDK), that uses keyboard accelerators calls the TranslateAccelerator() function in its main message loop. However, when you use a modal dialog box as the main window, the application does not have a main message loop; instead, the application uses the dialog manager message loop (built into Windows) to translate and dispatch messages. Of course, because this message loop is not designed to process accelerators, it does not call the TranslateAccelerator() function.

To process accelerator keys in a modal dialog box, you must override the CWinApp::ProcessMessageFilter() function. The framework calls ProcessMessageFilter() before it processes a message.

Perform the following eighteen steps to modify the TRACER sample to correctly process accelerator keys.

  1. Load the TRACER project into Visual C++. For Visual C++ for Windows, all versions, and Visual C++ 32-bit Edition, versions through 2.2, start App Studio. For Visual C++ 32-bit Edition, version 4.0, select the Resource View in the Project Workspace window.

  2. Edit the dialog box resource and specify the "thin" border style. This step is required for a dialog box that contains a menu.

  3. Create a new menu resource that contains a top level entry "&File" and a menu item "&Exit\tCTRL+E".(CTRL-X is usually associated with cutting text, so CTRL-E was used instead).

  4. Associate the menu with the dialog box by entering the menu ID in the dialog resource properties edit control.

  5. Select the "&Exit\tCTRL+E" menu item and click the ClassWizard button on the toolbar.

  6. In the Add Class dialog box, choose Select Class. Then choose CPromptDlg and choose OK. Visual C++ 4.0 recognizes that the menu resource is not associated with any object and prompts you to associate it with the CPromptDlg class.

  7. In the ClassWizard dialog box, select the menu ID associated with the Exit menu, ID_FILE_EXIT, and the COMMAND message. Then choose Add Function.

  8. The Add Member Function dialog box proposes a name for the function which you can edit if desired. Choose OK.

  9. Choose Edit Code. Insert the following line into the function:

          PostMessage(WM_COMMAND, IDOK, 0L);
    

    This gives the same effect as clicking the OK button when the user chooses Exit from the File menu. Clicking the OK button closes TRACER.

  10. Create a new accelerator resource and associate the CTRL+E key combination with ID_FILE_EXIT.

  11. Save the resources and close App Studio.

  12. Edit the TRACER.CPP file to declare the following variables after the #include statements:

          HWND    ghDlg;          // Handle to main dialog box
          HACCEL  ghAccelTable;   // Handle to accelerator table
    
    

  13. In ClassWizard, choose the CPromptDlg and the WM_INITDIALOG message and add a function. With Visual C++ 4.0, choose the CPromptDlg class, the CPromptDlg Object ID, the WM_INITDIALOG message, and press Add Function. Note that now there are two OnInitDialog() functions, one for Macintosh, surrounded by #ifdef _MAC/#endif directives, and the one just added.

  14. Edit the function added above to include the following line of code:

          ghDlg = m_hWnd;
    

    In Visual C++ 4.0, be sure to edit the newly added function, not the existing, Machintosh-specific one.

          ghDlg = m_hWnd;
    

  15. Edit CTraceApp::InitInstance() in the TRACER.CPP file to add the following line immediately after the call to SetDialogBkColor() or, as in Visual C++ 4.0, after the declaration of dlg, the CPromptDlg object:

         ghAccelTable = LoadAccelerators(AfxGetInstanceHandle(),
    
            MAKEINTRESOURCE(IDR_ACCELERATOR1));
    
    

  16. Edit the CTracerApp class definition to add the following line to the public section:

         virtual BOOL ProcessMessageFilter(int code, LPMSG lpMsg);
    

  17. Add the following function after the InitInstance() function:

           BOOL CTracerApp::ProcessMessageFilter(int code, LPMSG lpMsg)
           {
    
              if (code < 0)
                 CWinApp::ProcessMessageFilter(code, lpMsg);
    
              if (ghDlg && ghAccelTable)
                 {
                 if (::TranslateAccelerator(ghDlg, ghAccelTable, lpMsg))
                    return(TRUE);
                 }
    
             return CWinApp::ProcessMessageFilter(code, lpMsg);
          }
    
    

  18. Compile and run TRACER. It should have a menu. When you choose

        Exit from the File menu or press CTRL+E the application closes, as
        expected.
    
Keywords          : MfcUI kbinfo
Technology        : kbmfc
Version           : 1.0 1.5 1.51 1.52 2.0 2.1 4.0
Platform          : NT WINDOWS


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


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: October 10, 1997
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.