Accelerator keys are shortcut keys with which the user can choose a command from a menu by using a single keystroke. For example, a user could select the Delete command simply by pressing the DEL key. Accelerator keys are part of the resource-definition file and are tied into the application through the C-language source code.
To provide accelerator keys to menus and menu items in your application, follow these steps:
1.In the resource-definition file, mark the accelerator key for each item in the MENUITEM statements.
2.In the resource-definition file, create an accelerator table. An accelerator table lists the accelerator keys and corresponding menu identifiers. You create it using the ACCELERATORS resource statement.
3.In the C-language source file, load the accelerator table by using the LoadAccelerators function.
4.Change the message loop so that it processes accelerator-key messages.
The menu text should indicate each item's accelerator key so that the user can tell which key to use for the command. Add the key assignments to the MENUITEM definitions in the .RC file. For example, suppose your application has the following pop-up menu defined in its resource-definition file:
GroceryMenu MENU
POPUP "&Meats"
BEGIN
MENUITEM "&Beef\tF9", IDM_BEEF
MENUITEM "&Chicken\tShift+F9", IDM_CHICKEN
MENUITEM "&Lamb\tCtrl+F9", IDM_LAMB
MENUITEM "&Pork\tAlt+F9", IDM_PORK
END
END
The pop-up menu Meats has the four items Beef, Chicken, Lamb, and Pork. Each item has a mnemonic, indicated by the ampersand (&), and an accelerator key separated from the name with a tab (\t). Whenever a menu item has a corresponding accelerator key, it should be displayed in this way. The accelerator keys in this sample are F9, SHIFT+F9, CTRL+F9, and ALT+F9.
To use accelerator keys, add an accelerator table to the resource-definition file
by using the ACCELERATORS statement. This statement lists the accelerator
keys and the corresponding menu identifiers of the associated items. In the
ACCELERATORS statement, as with other resource statements, BEGIN starts the entry and END marks its end. Following is a typical accelerator table:
GroceryMenu ACCELERATORS
BEGIN
VK_F9, IDM_BEEF, VIRTKEY
VK_F9, IDM_CHICKEN, VIRTKEY, SHIFT
VK_F9, IDM_LAMB, VIRTKEY, CONTROL
VK_F9, IDM_PORK, VIRTKEY, ALT
END
This example defines four accelerator keys, one for each menu item. The first accelerator key is simply the F9 key; the other three are key combinations using the ALT, SHIFT, or CTRL key in combination with the F9 key.
The accelerator keys are defined by using the Windows virtual-key code, as indicated by the VIRTKEY option. Virtual keys are device-independent key values that Windows translates for each computer. These keys offer a way to guarantee that the same key is used on all computers without your needing to know what the actual value of the key is on any computer. You may also use ASCII key codes for accelerators, in which case, you would use the ASCII option.
The ACCELERATORS statement associates each accelerator key with a menu identifier. In the preceding example, the IDM_BEEF, IDM_CHICKEN, IDM_LAMB, and IDM_PORK constants are the menu identifiers of the items on the Grocery menu. When the user presses an accelerator key, these are the values that are passed to the window procedure.
The accelerator table, like any other resource, must be loaded before your application can use it. To load the accelerator table, use the LoadAccelerators function. This function takes a handle of the current instance of the application and the name of the accelerator table (as defined in the .RC file); it returns a handle of the accelerator table for the associated menu. Typically, you load a menu's accelerator table when that menu's window has just been created—that is, within the WM_CREATE case of the window procedure. The following example shows how to load an accelerator table:
HINSTANCE hinst; /* handle of current instance */
HACCEL hAccTable; /* handle of accelerator table */
.
.
.
case WM_CREATE:
hAccTable = LoadAccelerators(hinst, "GroceryMenu");
break;
In this example, the LoadAccelerators function loads the accelerator table for GroceryMenu into memory. The function then assigns the handle identifying the table to the hAccTable variable. The hinst variable identifies the application's resource-definition file; GroceryMenu is the name of the accelerator table.
Once the table is loaded, the application can use the TranslateAccelerator function to translate accelerator keys for that menu.
To use the accelerator table, you must add the TranslateAccelerator function to the message loop. When the message loop receives a keyboard-input message containing an accelerator key, TranslateAccelerator converts the message to a WM_COMMAND message containing the appropriate menu identifier for that accelerator key, and sends the resulting WM_COMMAND message to the window procedure.
The message loop should test each message to determine whether it is an accelerator-key message; if it is, the loop should translate and dispatch the message by using TranslateAccelerator. If the message is not an accelerator-key message, the loop should process it as usual.
Note:
TranslateAccelerator also translates accelerator keys for commands the user chooses from the System menu. In such cases, the function translates the keyboard-input message into a WM_SYSCOMMAND message.
After you add the TranslateAccelerator function, the message loop should look like this:
while (GetMessage(&msg, NULL, NULL, NULL)) {
if (!TranslateAccelerator(hWnd, hAccTable, &msg)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
In this example, the TranslateAccelerator function checks each message to determine whether it is an accelerator-key message. If the message is an accelerator-key message, the window handle hWnd identifies the window whose messages are to be translated (if any are found). The window handle must identify the window that contains the menu with the accelerator keys. The accelerator handle hAccTable specifies the accelerator table to use when translating the accelerator keys. If the message was generated by means of an accelerator key, the TranslateAccelerator function converts the keystroke to a WM_COMMAND message containing the appropriate menu identifier, and sends that WM_COMMAND message to the window procedure.
If the message is not an accelerator-key message, the application processes it as usual, by using the TranslateMessage and DispatchMessage functions.