vbAccelerator Accelerator Control
Intercept
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?
|