View RSS Feed

Development Team Blog

Hot Keys without On_Key (updated)

Rate this Entry
The Visual DataFlex On_Key command is the recommended technique to use when creating Hot Key assignments in your application. But there are certain key combinations that are not available to the On_Key command. For example the CTRL+SHIFT+TAB key combination cannot be assigned using On_Key.

Ever since Visual DataFlex 12.1 there is an alternative way to assign a hot key by using the cCJAction class. This class is part of the CodeJock commandbar set of wrapper classes and supports a property called piShortCutKey. You can set this property using virtual key codes, whenever that key combination is pressed, the cCJAction object's OnExecute procedure is fired. Below is an example....

Object oGlobalCommandBarSystem is a cCJCommandBarSystem
    // We build this invisible action object just to force the shortcut key to get set up.
    // Ctrl+Shift+Tab = PreviousTab.        
    Object oPreviousTabAction is a cCJAction
        Set piShortCutKey to (xtpKey_Shift + xtpKey_Ctrl) VK_TAB

        Procedure OnExecute Variant vCommandBarControl
            Forward Send OnExecute vCommandBarControl
            Send Info_Box "Ctrl+Shift+Tab just got pressed"
piShortCutKey is one of those funny 'folded' properties (like Size & Location) where you pass two separate values when setting it.

The first value is a code representing the modifier key combinations (Shift, Ctrl, etc). For these you will need to pass special CodeJock constants that represent the various modifier keys: xtpKey_Shift etc. Just start typing xtpKey... and the Studio's CodeSense will help you with the rest. These constants are binary encoded so, to combine modifier keys, use an expression and add the constants together.

The second value is the actual key value, e.g. TAB, A, B, C etc. For this you need to pass a Win32 virtual key code. These are all prefixed with VK_. Once again, just start typing and the Studio's CodeSense will help you with the rest.

The cCJAction object must be nested inside your application's global cCJCommandbarSystem object. This is the object that wraps around your application's CodeJock menu bar and toolbar objects. If you don't use CodeJock menus (why not?) then you can just create a cCJCommandBarSystem object anyway. Just place it inside your application's main panel object (look at the Order.src sample application for an example).

cCJAction is a superclass of cCJMenuItem, which is used to implement menu item, toolbar item and context menu item objects. Why not just make the hotkey assignment inside one of these objects? Well you can, but there are two catches:

Firstly, what if you only want a hot key assignment, i.e. you do not actually want a menu item? The second problem is with context menus. it is not a good idea to rely on CodeJock context menus for making hot key assignments. Why not? Because the hot key is never assigned until the first time that the menu item is paged, i.e. when someone drops down the context menu for the first time.

If you select a cCJMenuItem object in the Studio's Code Explorer and look at the properties in the Properties Panel, you will not see the piShortCutKey property listed. This property has deliberately not been exposed in the Studio. The reason is that setting piShortCutKey is not compatible with the VDF On_Key command. Unpredictable things will happen if you assign the same key code using both On_Key and piShortCutKey. The Studio only models the way that we recommend you to use things. The VDF class library is full of On_Key assignments and we recommend that you always use the On_Key command in preference to setting piShortCutKey to keep everything working in a consistent and predictable way.

However, in the cases where you want to assign a hot key that is not covered by the On_Key command then there is no reason not to use the above technique.

Update - Using On_Key with Multiple Key Combinations

Since I wrote this article Vincent Oorsprong has demonstrated (on the Forum) how to use the On_Key command for almost any key combination, including the Ctrl+Shift+Tab combination that I was demonstrating above.

The trick is to realize that the various Key_??? symbols are simply integer constants that can be added together to represent a key value or a value for a combination of keys. If you know what the key value is for a certain key combination, then you can assign that value directly using the On_Key command.

For example:

// On_Key constant for Ctrl+Shift+Tab
Define C_CtrlShiftTab for 7170

On_Key C_CtrlShiftTab Send SomeMessage
How can you know what is the integer value for a particular key combination? Well you can write a small program that can query any key combination. For example...

Use Windows.pkg

Object oPanel is a BasicPanel
    Set Size to 200 200

    Object oForm1 is a Form
        Set Size to 13 100
        Set Location to 12 20
        Procedure Key Integer iKeyValue Returns Integer
            Forward Send Key iKeyValue
            Set Value to iKeyValue
            On_Key iKeyValue Send Showme
    Procedure ShowMe
        Send Info_Box "Test"

Send Activate to oPanel
If you run this program and type a key combination (such as Ctrl+Shift+Tab) you will see the integer value that you need displayed in the Form object. If you press the key a second time it will trigger the On_Key event for that combination and you will see the Info_Box. This confirms that the key combination will work properly with the On_Key assignment.

I actually prefer this On_Key technique of Vincent's to the one that I elaborated at the top of this blog article as it means that you can avoid mixing different hot key handlers in the same application.

Updated 20-Nov-2009 at 01:28 PM by John van Houten



  1. Michael Mullan's Avatar
    so will this work (does this already work in the 15.1) studio code to change the current tab in the editor?


  2. John van Houten's Avatar
    It is in the current 15.1 Studio, but I can't say 100% yet if this feature will make it all the way to release.
  3. ramide's Avatar
    You could post an example of how to dynamically create these key shortcuts?

    I have a dynamic menu and my idea is to dynamically assign a set of keys to open each View ... It would be possible?