Jump to content

PMGuide - Keyboard Accelerators

From EDM2

Reprint Courtesy of International Business Machines Corporation, © International Business Machines Corporation

Presentation Manager Programming Guide and Reference
  1. How to Use this Book
  2. Device Functions
  3. Direct Manipulation Functions
  4. Dynamic Data Formatting Functions
  5. Hooks and Procedures
  6. Profile Functions
  7. Spooler Functions
  8. Window Functions
  9. Message Processing
  10. Data Types
  11. Errors
  12. Atom Tables
  13. Button Controls
  14. Clipboards
  15. Combination Box
  16. Container Controls
  17. Control Windows
  18. Cursors
  19. Dialog Windows
  20. Direct Manipulation
  21. Drawing in Windows
  22. Dynamic Data Exchange
  23. Entry-Field Controls
  24. File Dialog Controls
  25. Font Dialog Controls
  26. Frame Windows
  27. Hooks
  28. Initialization Files
  29. Keyboard Accelerators
  30. List-Box Controls
  31. Menus
  32. Messages and Message Queues
  33. Multiple-Line Entry Field Controls
  34. Mouse and Keyboard Input
  35. Mouse Pointers and Icons
  36. Notebook Controls
  37. Painting and Drawing
  38. Presentation Parameters
  39. Resource Files
  40. Scroll-Bar Controls
  41. Slider Controls
  42. Spin Button Controls
  43. Static Controls
  44. Title-Bar Controls
  45. Value Set Controls
  46. Windows
  47. Window Classes
  48. Window Procedures
  49. Window Timers
  50. Appendices
  51. Notices
  52. Glossary

A keyboard accelerator (shortcut key to the user) is a keystroke that generates a command message for an application. This chapter describes how to use keyboard accelerators in your PM applications.

About Keyboard Accelerators

Using a keyboard accelerator has the same effect as choosing a menu item. While menus provide an easy way to learn an application's command set, accelerators provide quick access to those commands.

Without accelerators, a user might generate commands by pressing the Alt key to access the menu bar, using the Arrow keys to select an item, then pressing the Enter key to choose the item. In contrast, accelerators allow the user to generate commands with a single keystroke.

Like menu items, accelerators can generate WM_COMMAND, WM_HELP, and WM_SYSCOMMAND messages. Although, normally, accelerators are used to generate existing commands as menu items, they also can send commands that have no menu-item equivalent.

Accelerator Tables

An accelerator table contains an array of accelerators. Accelerator tables exist at two levels within the operating system: a single accelerator table for the system queue and individual accelerator tables for application windows. Accelerators in the system queue apply to all applications-for example, the F1 key always generates a WM_HELP message. Having accelerators for individual application windows ensures that an application can define its own accelerators without interfering with other applications. An accelerator for an application window can override the accelerator in the system queue. An application can modify both its own accelerator table and the system's accelerator table.

The application can set and query the accelerator table for a specific window or for the entire system. For example, an application can query the system accelerator table, copy it, modify the copied data structures; and then, use the modified copy to set the system accelerator table. An application also can modify its window's accelerator table at run time to respond more appropriately to the current environment.

Note
An application that modifies any accelerator table other than its own should maintain the original accelerator table; and, before terminating, restore that table.

Accelerator-Table Resources

You can use accelerators in an application by creating an accelerator-table resource in a resource-definition file. Then, when the application creates a standard frame window, the application can associate that window with the resource.

As specified in a resource-definition file, an accelerator table consists of a list of accelerator items, each defining the keystroke that triggers the accelerator, the command the accelerator generates, and the accelerator's style. The style specifies whether the keystroke is a virtual key, a character, or a scan code, and whether the generated message is WM_COMMAND, WM_SYSCOMMAND, or WM_HELP; WM_COMMAND is the default.

Accelerator-Table Handles

Applications that use accelerator tables refer to them with a 32-bit handle. An application using this handle, by default, can make most API function calls for accelerators without having to account for the internal structures that define the accelerator table. When an application needs to dynamically create or change an accelerator table, it must use the ACCEL and ACCELTABLE data structures.

Accelerator-Table Data Structures

An accelerator table consists of individual accelerator items. Each item in the table is represented by an ACCEL structure that defines the accelerator's style, keystroke, and command identifier. Typically, an application defines these aspects of an accelerator in a resource-definition file, but the ACCEL structure also can be built in memory at run time. An accelerator table is represented by an ACCELTABLE structure that specifies the number of accelerator items in the table, the code page used for the keystrokes in the accelerator items, and an array of ACCEL structures (one for each item in the table). Applications that use ACCELTABLE structures directly must allocate sufficient memory to hold all the items in the table.

Accelerator-Item Styles

An accelerator item has a style that determines what combination of keys produces the accelerator and what command message is generated by the accelerator. An application can specify the following accelerator-item styles in the fs field of the ACCEL structure:

Style Description
AF_ALT Specifies that the user must hold down the Alt key while pressing the accelerator key.
AF_CHAR Specifies that the keystroke is a character that is translated using the code page for the accelerator table. (This is the default style.)
AF_CONTROL Specifies that the user must hold down the Ctrl key while pressing the accelerator key.
AF_HELP Specifies that the accelerator generates a WM_HELP message instead of a WM_COMMAND message.
AF_LONEKEY Specifies that the user need not press another key while the accelerator key is down. Typically, this style is used with the Alt key to specify that simply pressing and releasing that key triggers the accelerator.
AF_SCANCODE Specifies that the keystroke is an untranslated scan code from the keyboard.
AF_SHIFT Specifies that the user must hold down the Shift key when pressing the accelerator key.
AF_SYSCOMMAND Specifies that the accelerator generates a WM_SYSCOMMAND message instead of a WM_COMMAND message.
AF_VIRTUALKEY Specifies that the keystroke is a virtual key-for example, the F1 function key.

Using Keyboard Accelerators

This section explains how to perform the following tasks:

  • Create an accelerator-table resource
  • Include an accelerator table in a frame window
  • Modify an accelerator table

Creating an Accelerator-Table Resource

The following code fragment shows a typical accelerator-table resource:

    ACCELTABLE ID_ACCEL_RESOURCE
    BEGIN
        VK_ESC,    IDM_ED_UNDO,  AF_VIRTUALKEY | AF_SHIFT
        VK_DELETE, IDM_ED_CUT,   AF_VIRTUALKEY
        VK_F2,     IDM_ED_COPY,  AF_VIRTUALKEY
        VK_INSERT, IDM_ED_PASTE, AF_VIRTUALKEY
    END

This accelerator table has four accelerator items. The first one is triggered when the user presses Shift+Esc, which sends a WM_COMMAND message (the default).

An accelerator table in a resource-definition file has an identifier (ID_ACCEL_RESOURCE in the previous example). You can associate an accelerator-table resource with a standard frame window by specifying the table's idResources parameter of the WinCreateStdWindow function.

An application can load an accelerator table resource-definition file automatically when creating a standard frame window, or it can load the resource independently and associate it with a window or with the entire system.

Including an Accelerator Table in a Frame Window

You can add an accelerator table to a frame window either by using the WinSetAccelTable function or by defining an accelerator-table resource (as shown in the previous section) and creating a frame window with the FCF_ACCELTABLE frame style. The second method is shown in the following code fragment:

    HWND  hwndFrame,hwndClient;
    CHAR  szClassName[]="MyClass";
    CHAR  szTitle[]="MyWindow";

    ULONG flControlStyle=
                FCF_MINMAX      |     /* Min and max buttons          */
                FCF_SHELLPOSITION |     /* System size and position     */
                FCF_SIZEBORDER    |     /* Size border                  */
                FCF_TITLEBAR      |     /* Title bar                    */
                FCF_TASKLIST      |     /* Task list                    */
                FCF_ACCELTABLE    |     /* Accelerator table            */
                FCF_SYSMENU       |     /* System menu                  */
                FCF_MENU;                /* Menu                         */

    hwndFrame=WinCreateStdWindow(HWND_DESKTOP,
        WS_VISIBLE,
        &flControlStyle,
        szClassName,
        szTitle,
        0,
        (HMODULE)NULL,
        ID_MENU_RESOURCE,
        &hwndClient);

Notice that if you set the flControlStyle parameter to the FCF_STANDARD flag, you must define an accelerator-table resource, because FCF_STANDARD includes the FCF_ACCELTABLE flag.

If the window being created also has a menu, the menu resource and accelerator resource must have the same resource identifier; this is because the WinCreateStdWindow function has only one input parameter to specify the resource identifiers for menus, accelerator tables, and icons. If an application creates an accelerator table resource-definition file; then, opens a standard frame window (as shown in the preceding example), the accelerator table is installed automatically in the window's message queue, and keyboard events are translated during the normal processing of events. The application simply responds to WM_COMMAND, WM_SYSCOMMAND, and WM_HELP messages; it does not matter whether these messages come from a menu or an accelerator.

An application also can add an accelerator table to a window by calling the WinSetAccelTable function with an accelerator-table handle and a frame-window handle. The application can call either the WinLoadAccelTable function to retrieve an accelerator table from a resource file or the WinCreateAccelTable function to create an accelerator table from an accelerator-table data structure in memory.

Modifying an Accelerator Table

You can modify an accelerator table, for either your application windows or the system, by doing the following:

  1. Retrieve the handle of the accelerator table.
  2. Use that handle to copy the accelerator-table data to an application-supplied buffer.
  3. Change the data in the buffer.
  4. Use the changed data to create a new accelerator table.

Then you can use the new accelerator-table handle to set the accelerator table, as outlined in the following list:

  1. Call WinQueryAccelTable to retrieve an accelerator-table handle.
  2. Call WinCopyAccelTable with a NULL buffer handle to determine how many bytes are in the table.
  3. Allocate sufficient memory for the accelerator-table data.
  4. Call WinCopyAccelTable, with a pointer to the allocated memory.
  5. Modify the data in the buffer (assuming it has the form of an ACCELTABLE structure).
  6. Call WinCreateAccelTable, passing a pointer to the buffer with the modified accelerator-table data.
  7. Call WinSetAccelTable with the handle returned by WinCreateAccelTable.