ACCEL ATTACH statement


Attach a table of keyboard accelerators to a DDT dialog.


ACCEL ATTACH hDlg, AccelTbl() TO hAccelHandle


ACCEL ATTACH permits you to attach one table of accelerator key definitions to each DDT dialog in your application.

The keyboard accelerator itself is a specific keystroke combination, which results in a %WM_COMMAND or %WM_SYSCOMMAND message being placed into the application's message queue.

Keyboard accelerators are very similar to command accelerators, and often permit the same action selections as menus offer. Since keyboard accelerators can be used directly, they negate the need to navigate a menu in order to perform a specific action.

Typically, application menu items inform users of available keyboard accelerators so expert users can work more efficiently without using the actual menus, but can still use the menu if required. The following image shows a menu showing command accelerator and keyboard accelerators for menu items (the command accelerators are underscored):


On Windows XP and Windows 2000 you may need to press the ALT key before Command Accelerators are made visible. You can set if Command Accelerators are visible when using the ALT key or all the time in the Windows Display Settings.

For a command accelerator to operate, the specific menu item must be visible and enabled. Conversely, keyboard accelerators can be used without the menu being open. In the example above, the CTRL+X keystroke combination will perform the CUT action, but the accelerator letter t will only perform the Cut action if the EDIT menu is opened first.


To utilize ACCEL ATTACH, you must first build the array AccelTbl() of ACCELAPI User-Defined Types (UDTs). This ACCELAPI structure is a 6-byte structure with the following definition:


  FVIRT AS BYTE ' Flags: One or more of %FVIRTKEY, %FSHIFT, %FALT and %FCONTROL

  KEY AS WORD ' Accelerator key: ASCII code, or virtual key code {%FVIRTKEY}

  CMD AS WORD ' Accelerator ID code gets passed in CB.CTL {LO(WORD, WPARAM)}


You must build the array of ACCELAPI types yourself, then attach it to a dialog by executing an ACCEL ATTACH statement. There must be no empty elements in the array, so it must be sized accurately.


The .FVIRT flags can be combined together with the OR operator to combine the actions of the individual flags, as follows:


The ALT key must be pressed along with the accelerator key.


The CTRL key must be pressed along with the accelerator key.


The SHIFT key must be pressed along with the accelerator key.


The .KEY member specifies a virtual-key code. If this flag is not specified, the key member is assumed to specify an ASCII character code. %FVIRTKEY permits case-insensitive accelerator keystroke definitions - the Capslock state is ignored. For example, ALT+A and ALT+a (as determined by the Capslock key) produce the same accelerator event. If %FVIRTKEY is not used, the accelerator ALT+A would not trigger if Capslock were inactive.


If the %FVIRTKEY flag is specified in the .FVIRT member, the .KEY field contains the virtual key code for the accelerator key. Virtual key equates are defined in the WIN32API.INC file, starting with the prefix %VK_.

If %FVIRTKEY is not specified, the accelerator key code in the .KEY member is the ASCII code of the accelerator key. In this case, alphanumeric keystrokes become case-sensitive and the state of the Capslock key state becomes important. For example, if an accelerator were defined for ALT+A, it would be activated only if the Capslock key was on. Conversely, if an accelerator were defined for ALT+a then it would only be activated Capslock was off.


The .CMD member should contain the user-defined numeric ID code of the accelerator. When an accelerator keystroke occurs, a WM_COMMAND message is sent to the dialog Callback Function, with the accelerator identifier returned by the CB.CTL function.

It is usual practice to use the ID of a control that is to be activated by an accelerator. Accelerator notification codes sent to the Callback Function have CB.CTLMSG set to 1 (as opposed to button click events messages where CB.CTLMSG = %BN_CLICKED).


The handle of the dialog to attach the accelerator table to.


Double-word or Long-integer variable where the handle of the attached accelerator table will be stored, or zero if the attach operation was unsuccessful.


If a previous table was attached to the target dialog, the table is automatically destroyed when the new table is attached in its place. The accelerator table is also destroyed automatically when the dialog is closed.

You can destroy the current accelerator table by executing ACCEL ATTACH with an array which is not dimensioned, but there is little or no reason to ever perform this action.

Accelerator tables can only run correctly when they are created in the same module that creates the dialog to which each table is attached.

See also






FOR x& = 0 TO 8


  ac(x&).key = %VK_1 + x& ' CTRL+SHIFT+1 to 9

  ac(x&).cmd = %BTN1 + x& ' %BTN1 to %BTN9



ACCEL ATTACH hDlg, ac() TO hAccelHandle