HOWTO: Using Accelerator Keys with Modal Dialog Box Main Window
ID: Q100770
|
The information in this article applies to:
-
The Microsoft Foundation Classes (MFC), used with:
-
Microsoft Visual C++ for Windows
-
Microsoft Visual C++, 32-bit Editions, versions 2.0, 2.1, 4.0, 5.0, 6.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 steps to modify the TRACER sample to
correctly process accelerator keys:
- Load the TRACER project into Visual C++.
- For all versions of 16-bit Visual C++, and Visual C++ 32-bit Editions through version 2.2, start App Studio.
For Visual C++ 4.0 and later, select the Resource View in the Project Workspace window.
- Edit the dialog box resource and specify the "thin" border style.
This step is required for a dialog box that contains a menu.
- 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).
- Associate the menu with the dialog box by entering the menu ID in
the dialog resource properties edit control.
- Select the "&Exit\tCTRL+E" menu item and click the ClassWizard
button on the toolbar.
- In the Add Class dialog box, choose Select Class. Then choose
CPromptDlg and click 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.
- 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.
- The Add Member Function dialog box proposes a name for the
function which you can edit if desired. Click OK.
- Click Edit Code. Insert the following line into the function:
PostMessage(WM_COMMAND, IDOK, 0L);
This gives the same effect as clicking OK when the user
chooses Exit from the File menu. Clicking OK closes
TRACER.
- Create a new accelerator resource and associate the CTRL+E key
combination with ID_FILE_EXIT.
- Save the resources and close App Studio.
- 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
- 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 Add Function. Note that there are now two OnInitDialog() functions,
one for Macintosh, surrounded by #ifdef _MAC/#endif directives, and the
one just added.
- 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;
- 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));
- Edit the CTracerApp class definition to add the following line to
the public section:
virtual BOOL ProcessMessageFilter(int code, LPMSG lpMsg);
- 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);
}
- 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.
Additional query words:
Keywords : kbui kbKeyAccel kbMenu kbMFC kbVC100 kbVC150 kbVC151 kbVC152 kbVC200 kbVC210 kbVC400 kbVC500 kbVC600 kbGrpMFCATL
Version : winnt:2.0,2.1,4.0,5.0,6.0
Platform : winnt
Issue type : kbhowto
|