Using MFC in C++ Part 2: Menus - Adding accelerator keys
(Page 8 of 9 )
Accelerator keys allow a user to access menu items quicker by pressing a pre-defined combination of keys, instead of having to click on a specific menu item everytime it is requred. An accelerator table, which contains a list accelerator keys, has the following structure:
[TableName] ACCELERATORS
{
KeyCode, Message Id [, Type, Options]
KeyCode, Message Id [, Type, Options]
KeyCode, Message Id [, Type, Options]
}
KeyCode: The KeyCode value should contain the key combination that will trigger the accelerator. The key code can be either:
Type: Can be either empty, VIRTKEY or ASCII, as described above.
Options: If CONTROL is specified, then the control key must be pressed to trigger this accelerator key. If SHIFT is specified, then the shift key must be pressed to trigger this accelerator key. If ALT is specified, then the alt key must be pressed to trigger this accelerator key.
Adding an accelerator key for a menu item is easy. To make the CMainWin::OnItem1() function execute when we press the Control key and the 1 (one) key, we would add the following code to the end of our resource file, menu.rc:
MyKeys ACCELERATORS
{
"1", IDM_1, CONTROL, VIRTKEY
}
To trigger the CMainWin::OnItem2() function when we prress the F2 key, we would add this accelerator key:
VK_F2, IDM_2, VIRTKEY
To trigger our the CMainWin::OnItem3() function when we press the “3” key, we would add this accelerator key:
51, IDM_3, ASCII // 51 is the ascii code for the 3 key
We can’t actually use these accelerator keys yet. We need to load the accelerator table. Double click on menu.cpp and add the following line just before the end of the CMainWin constructor:
if(!LoadAccelTable("MyKeys"))
MessageBox("Couldn't load the accelerator table");
The LoadAccelTable function is a member of the CFrameWnd class, accepts one parameter, the name of the menu (in quotes), and returns a BOOL value. It loads our accelerator table into memory and sends the notification messages to our application when the right combination of keys is pressed.
To make sure our accelerator keys work, compile and run our app. First, press Cntl+1. Next, press the F2 key. Lastly, press just the “3” key. Each different OnItem function should be triggered.
To make our menu items display the accelerator keys they respond to, change the MENU table in menu.rc, like this:
MyMenu MENU
{
POPUP "Popup"
{
MENUITEM "Item One/tCntl+1", IDM_1
MENUITEM "Item Two/tF2", IDM_2
MENUITEM SEPARATOR
MENUITEM "Item Three/t3", IDM_3
}
}
(Page 8 of 9 )
Accelerator keys allow a user to access menu items quicker by pressing a pre-defined combination of keys, instead of having to click on a specific menu item everytime it is requred. An accelerator table, which contains a list accelerator keys, has the following structure:
[TableName] ACCELERATORS
{
KeyCode, Message Id [, Type, Options]
KeyCode, Message Id [, Type, Options]
KeyCode, Message Id [, Type, Options]
}
KeyCode: The KeyCode value should contain the key combination that will trigger the accelerator. The key code can be either:
- Any alphanumeric character enclosed in quotes, such as “a”, “C”, “6”. These are case sensitive.
- The header file afxres.h defines several macros for “virtual keys”. Virtual key macros allow keys such as F1 and F2 (VK_F1 to VK_F12) to be used as accelerator keys. If a virtual key is used as the key code, then the type should be set to VIRTKEY.
- The ASCII code number of a character. If an ASCII key code is used, then the type should be set to ASCII.
Type: Can be either empty, VIRTKEY or ASCII, as described above.
Options: If CONTROL is specified, then the control key must be pressed to trigger this accelerator key. If SHIFT is specified, then the shift key must be pressed to trigger this accelerator key. If ALT is specified, then the alt key must be pressed to trigger this accelerator key.
Adding an accelerator key for a menu item is easy. To make the CMainWin::OnItem1() function execute when we press the Control key and the 1 (one) key, we would add the following code to the end of our resource file, menu.rc:
MyKeys ACCELERATORS
{
"1", IDM_1, CONTROL, VIRTKEY
}
To trigger the CMainWin::OnItem2() function when we prress the F2 key, we would add this accelerator key:
VK_F2, IDM_2, VIRTKEY
To trigger our the CMainWin::OnItem3() function when we press the “3” key, we would add this accelerator key:
51, IDM_3, ASCII // 51 is the ascii code for the 3 key
We can’t actually use these accelerator keys yet. We need to load the accelerator table. Double click on menu.cpp and add the following line just before the end of the CMainWin constructor:
if(!LoadAccelTable("MyKeys"))
MessageBox("Couldn't load the accelerator table");
The LoadAccelTable function is a member of the CFrameWnd class, accepts one parameter, the name of the menu (in quotes), and returns a BOOL value. It loads our accelerator table into memory and sends the notification messages to our application when the right combination of keys is pressed.
To make sure our accelerator keys work, compile and run our app. First, press Cntl+1. Next, press the F2 key. Lastly, press just the “3” key. Each different OnItem function should be triggered.
To make our menu items display the accelerator keys they respond to, change the MENU table in menu.rc, like this:
MyMenu MENU
{
POPUP "Popup"
{
MENUITEM "Item One/tCntl+1", IDM_1
MENUITEM "Item Two/tF2", IDM_2
MENUITEM SEPARATOR
MENUITEM "Item Three/t3", IDM_3
}
}