48.1.1 Accelerator Tables

The essential components of accelerators are accelerator tables and the TranslateAccelerator function. An accelerator table consists of an array of ACCEL structures, each defining an individual accelerator. The definition of an accelerator includes the following information:

The accelerator's keystroke combination

The accelerator's identifier

A flag specifying whether Windows should provide visual feedback by highlighting the corresponding menu item (if any) when the accelerator is used

To process accelerator keystrokes for a given thread, you must call the TranslateAccelerator function in the message loop associated with the thread's message queue. The TranslateAccelerator function monitors keyboard input to the message queue, checking for key combinations that match an entry in the accelerator table. When TranslateAccelerator finds a match, it translates the keyboard input (that is, the WM_KEYUP and WM_KEYDOWN messages) into a WM_COMMAND or WM_SYSCOMMAND message, and sends the message to the window procedure of the specified window. The following illustration shows how accelerators are processed:

The WM_COMMAND or WM_SYSCOMMAND message includes the identifier of the accelerator that caused TranslateAccelerator to generate the message. Your window procedure should examine the identifier to determine the source of the message, then process the message accordingly.

Accelerator tables exist at two different levels within Windows. Windows maintains a single, system-wide accelerator table that applies to all applications. An application cannot modify the system accelerator table. For a list and description of the accelerators provided by the system accelerator table, see Section 0.1.3, “Accelerator Keystroke Assignments.”

In addition to maintaining the system accelerator table, Windows maintains accelerator tables for each application. An application can define any number of accelerator tables for use with its own windows—a unique 32-bit handle (HACCEL) identifies each table. However, only one accelerator table can be active at a time for a given thread. The handle of the accelerator table that you pass to the TranslateAccelerator function determines which accelerator table is active for a thread. You can change the active accelerator table at any time by passing a different accelerator-table handle to TranslateAccelerator.