When creating or managing client-server applications, it is frequently beneficial to employ different keyboard shortcuts to increase efficiency. Although keyboard shortcuts are typically used with menus, this article investigates the utilization of keyboard shortcuts in a Uniface Windows application that doesn't have menus. The objective of this new approach is to enable end users or system administrators to modify keyboard shortcuts in the usys.ini file without accessing the application's source code. This functionality was already available for menu accelerators but was absent for Forms that do not have a menu.
Accelerators are keyboard combinations linked to specific menu items. These combinations can be defined in the usys.ini file. In the [accelerators] section, you can connect a key combination with a menu item in a form component, like the example below:
By defining "Fileopen" in the menu editor, Uniface automatically adds "Ctrl+O" to the menu text and registers it as an accelerator in Windows. Pressing Ctrl+O activates the menu item without displaying the characters in the current field. The Windows operating system handles the translation and triggers the menu-item selection event, also firing the menu option trigger in 4GL.
But what if you don't have a menu and still want to use key combinations for certain actions? In such cases, you can define them in the Keyboard Translation Table (KTT). However, this approach is more static and harder to maintain. The configured key combinations in the KTT are not visible from the outside. Additionally, 4GL involves checking numbers in the $char register, making the code less verbose. Here's an example:
Defined in the Keyboard Translation Table, you can have the following lines for Ctrl+K, Ctrl+L, and Ctrl+P:
In the user key trigger, you can define the desired actions:
trigger userkey
message/info "User key %%$char pressed!"
To address the absence of menus and the need for keyboard accelerators, we’ve added a new section to the usys.ini file: [userkeys]. Here, we explain how to utilize user-defined keys.
Accelerators activate menu items and subsequently fires the menu’s option trigger. On the other hand, the userkey definition fires the userkey trigger.
The userkey trigger can also be fired by a keyboard combination defined in the KTT as we saw earlier in this blog. Here’s an example of a user key definition in the usys.ini file:
[userkeys]
fileopen=Ctrl+O
When this definition exists, and there is no menu or active menu with the same keyboard combination, pressing Ctrl+’O’ fires the userkey trigger, setting $result to “fileopen.”.
This approach allows having the same accelerators in Forms with or without menus. However, if a menu with the same accelerator exists, it takes precedence over the user key definitions. The order of precedence is as follows:
-
Menu items with an accelerator
-
Label text with an underscore, used to set focus to an associated field or default keys for a button.
-
User key definition in the usys.ini
-
HTML widget property UNIFACEKEYS
-
User key definition in the keyboard translation table (KTT)
Labels on a Form or default keys for buttons take precedence over user keys. Labels with underscored characters indicate that pressing Alt+<char> sets the input focus to the associated field, while buttons with underscored characters imply that pressing Alt+<char> fires the detail trigger.
The userkeys section can also contain keys like F1... F12, NUMPAD-, NUMPAD/, NUMPAD*, TAB, ESC or cursor keys.
Function keys are sometimes in use by a widget control. For example, a multiline edit control uses TAB to insert a Tab character, while other controls have no specific handling, and the system will move the keyboard input to the next control in the Form. It is important to choose the right key combination (or single key) to avoid possible conflicts with the Windows operating system or the applications controls. In the appendix of this blog, you will find an overview of the keyboard keys and their possible usage. Also, we’ve added a recommendation to help you, as developer, choose the right key when you do not want to combine the key with Ctrl or Alt.
Uniface keys and the HTML widget
To pass keystrokes directly to Uniface when using the HTML widget, the property “unifacekeys” comes into play. Suppose you want to perform a retrieve on Ctrl+R, ensuring this key combination reaches the UNIFACE kernel instead of JavaScript, you can define the following in the widget section:
Html=uhtml(unifacekeys=Ctrl+R)
This configuration sends Ctrl+R to the Uniface keyboard translation table. If a user key definition exists for this combination, it takes precedence. The “unifacekeys” property primarily determines which keys are sent to Uniface instead of JavaScript. The user key definition is always checked for each keystroke in the HTML widget, explaining why it has a higher priority than JavaScript or the “unifacekeys” property.
Certain key combinations, like Alt+F4 to close a form or Alt+SPACEBAR to activate a menu, are reserved by the operating system and cannot be used for accelerators or user keys. See the appendix for details on the different keys.
When using accelerators or user key definitions, it’s advisable to provide clear descriptions for the actions. For example, use “fileopen=Ctrl+O.” In the case of the userkey trigger, this description will appear in the proc-script, making it more readable and easier to maintain. Additionally, check the component for labels or buttons using keyboard shortcuts and avoid conflicting key combinations, as labels take precedence over user key definitions. By using Ctrl+<character> for menus and user keys, you can avoid conflicts between label shortcuts, accelerators, and user keys.
In this chapter you’ll find an overview of single keys recognized by UNIFACE. The table is showing the <key>, without modifier like Ctrl or Alt. Of course, you can use these keys in combination with Ctrl or Alt.
Keyboard key as recognized by Uniface
|
|
Usage possible or recommended as standalone key
|
|
Conflicts in components using edit controls
|
|
|
Many controls are using this internally
|
|
|
Many controls are using this internally
|
|
|
Can be used as standalone key only when the QUIT trigger on component level returns (-1)
|
|
|
Many controls are using this internally
|
|
|
Many controls are using this internally
|
|
|
Multiline, lists and tree controls are using this internally
|
|
|
Multiline, lists and tree controls are using this internally. Ctrl+PAGEUP is used by Tab widget.
|
|
|
Multiline, lists and tree controls are using this internally
|
|
|
Multiline, lists and tree controls are using this internally. Ctrl+PAGEDOWN is used by Tab widget.
|
|
|
Many controls are using this internally
|
|
|
Many controls are using this internally
|
|
|
Many controls are using this internally
|
|
|
Many controls are using this internally
|
|
|
Many controls are using this internally
|
|
|
Many controls are using this internally
|
|
|
Can be used but not recommended, conflicts with tree control which use the Shift * for expansion
|
|
|
Can be used but not recommended
|
|
|
Can be used but not recommended
|
|
|
|
|
|
Generally used for Rename
|
|
|
Generally used for Search
|
|
|
|
|
|
Generally used for Refresh
|
|
|
Generally used to go to Address Bar
|
|
|
Generally used for spell check
|
|
|
|
|
|
Generally used for Compile and Run
|
|
|
Generally used to activate Menu
|
|
|
Generally used to exit Full screen
|
|
|
|
|