vbAccelerator Accelerator Control

Intercept

Accelerator Sample Application

If you've ever tried to pick a keyboard accelerator for the menu items Back and Next in your application, you might have discovered a limitation in VB's ability to set up accelerators. IE offers some sensibly chosen keyboard accelerators for its Back, Next, Home shortcuts, using Alt and the arrow and Home keys, but you won't be able to set them up in standard VB. Another thing that can be annoying is that you cannot set up accelerators at run-time, only at design time. This means if you are loading custom menus then you won't be able to give them an accelerator. This control allows you to work around both of these problems.

The vbAccelerator Accelerator Control

This control uses a Windows Hook to intercept keyboard messages whilst your application is running. Because it affects all windows within your application's thread, it doesn't matter which window has focus, the accelerator will also be detected. (So beware! Don't, for example, set up an accelerator on the 'A' key...)

Using the control is simple. Just drop one control on your application's main form and then call the AddAccelerator method with the key code, shift constants added together and a string property to identify the accelerator. Then whenever the accelerator is pressed the control's Accelerator event will fire, passing you the index of the accelerator in the control's array. You can get the string key property which identifies the accelerator from the index with the Key property.

To indicate that an accelerator is associated with a menu, you can set the caption of the menu to show the accelerator. To do this, set the Caption property of the menu to the regular caption plus a tab plus the text for the accelerator. So for example to set up a Home menu item with Alt+Home as the displayed accelerator, do this:

   mnu.Caption = "&Home Page" & vbTab & "Alt+Home"

Why Is This an OCX and Not a DLL?

Normally I would code this sort of component as a DLL because you don't need the overhead of a control implementation to achieve this (particularly when there are no property pages or real design-time features).

The main problem with implementing accelerators is that they can interfere with the IDE. What happens if you set up an accelerator on the Ctrl+Break key combination? With a Windows Hook, this can eat the message before it gets to the VB IDE, leaving you with no way to interrupt the code whilst it is running.

There appears to be only one solution to this in VB: to check the EventsFrozen property of the Ambient object. But the Ambient object is only available in a UserControl. Having said that, there is a Microsoft DLL called the "Debug Object for AddressOf Subclassing" available from the which seems to solve this problem. No code though, so I'm not using it. Anyone got an idea how its done?