|Keyboard Configuration Utility (Keybcf)||Screens|
DOS, Windows and OS/2:
On DOS, Windows and OS/2, in many instances, you can enhance a PC application's interface by detecting the presence of a mouse and then allowing its optional use. COBOL provides both high and low level routines for accessing the mouse. It is now possible to write sophisticated new applications that exploit all of the mouse features. You can also quickly change existing applications to use the mouse if one is present.
Mouse support is not available on UNIX.
The section Adding Mouse Support to Existing Applications presents information on how to incorporate mouse support into an existing application quickly. The section Using Call-by-name Mouse Routines describes how to use all of the mouse features.
Many existing character PC COBOL applications use Adis, the enhanced screen and keyboard management functions of COBOL. If your program contains a Screen Section, uses the ACCEPT/DISPLAY verb extensions that control positioning or highlighting, or calls the x"AF" routine, you are using Adis. See the chapter Adis for information on Adis.
You can enhance such applications by using the mouse to:
With these mouse routines, your application's user interface behaves as in the past without a mouse. However, if a mouse is present, many operations can be simplified or shortened.
You can add each of these functions to an existing application by including a small amount of code. You access the Adis mouse routines by calling the x"AF" routine with specific function codes. These function codes enable you to:
You cannot mix these x"AF" call by number routines with the newer call by name routines in the same application.
A sample program, admouse.cbl , illustrates these routines and techniques. This program is provided in your cobol\demo directory.
Before accessing any of the other mouse functions, you must initialize the mouse. The initialization call tells Adis to load the mouse driver and draw the mouse pointer. When the application has finished with the mouse, it must be terminated. Termination cancels the mouse driver and deletes the mouse pointer.
The following section of code shows how to initialize or terminate the mouse:
01 use-mouse-function pic x comp-x value h"40". 01 terminate-mouse pic x comp-x value h"00". 01 activate-mouse pic x comp-x value h"01". ... call x"AF" using use-mouse-function activate-mouse
call x"AF" using use-mouse-function terminate-mouse
||is a hexadecimal constant, a Micro Focus extension for representing hexadecimal binary values for numeric fields.|
||is equivalent to a one-byte comp field with a value of decimal 64.|
For more information on named constants, see your Language Reference.
Adis returns a value of 255 in
if the mouse cannot be initialized.
You might not want to display the mouse pointer on every screen or menu in your application, so these two functions enable you to show and hide the mouse when appropriate. A good guideline is to show the mouse pointer if the mouse can actually be used to do something at that point.
The following section of code shows you how to enable or disable the mouse:
01 enable-mouse-function pic x comp-x value h"42". 01 show-mouse pic x comp-x value h"01". 01 hide-mouse pic x comp-x value h"00". ... call x"AF" using enable-mouse-function show-mouse
call x"AF" using enable-mouse-function hide-mouse
Once the mouse pointer is displayed, the user can use it to point at fields on the screen. In its default setting, if the user presses the first button (usually the left button), the cursor is positioned at the start of the field pointed to by the mouse. If the mouse pointer is not over a valid input field, Adis sounds a warning beep. When the mouse pointer is hidden, button presses are ignored.
Using the mouse to select items from a menu requires the program to detect that the mouse button was pressed and determine the mouse pointer's location on the screen at that time. Adis looks for button 1 on the mouse; any other button presses are ignored. Button presses are interpreted by Adis as Adis key 27.
By default, Adis keys other than Enter (Adis key 0) do not terminate an ACCEPT statement. You can change this by using the following code:
The following section of code shows how to enable the mouse to terminate an ACCEPT statement:
01 set-bit-pairs pic x comp-x value h"01". 01 mouse-can-terminate-accept pic x(4) comp-x value h"01321b01". 01 mouse-cannot-terminate-accept pic x(4) comp-x value h"02321b01". ... call x"AF" using set-bit-pairs mouse-can-terminate-accept
call x"AF" using set-bit-pairs mouse-cannot-terminate-accept
Enabling the mouse button to terminate the ACCEPT statement gives the user a second Enter key. This behavior is not always appropriate in your application's dialog.
To determine that it was the mouse that terminated the ACCEPT statement, you must examine the CRT-STATUS data item referenced in the Special-Names paragraph. The CRT-STATUS data item is defined as:
01 key-pressed. 05 key-type pic x. 05 key1 pic x comp-x. 05 keyx redefines key1 pic x. 05 key2 pic x comp-x.
If the ACCEPT statement is terminated by the Enter key, the
key-type data item has a value of 0. If the mouse
terminates the ACCEPT statement,
key-type has a
value of 2 and
key1 has a value of 27.
Example code to interpret the key-type:
display screen accept screen evaluate key-type also key1 when "0" also any * <code to process enter key> when "2" also 27 * <code to process mouse button> when "1" also 1 * <code to process function key 1> ... end-evaluate
If you have determined that the mouse button was pressed, you can query the position of the mouse pointer with another call:
01 get-mouse-details pic x comp-x value h"43". 01 mouse-details. 05 mouse-x pic 9(4) comp-x. 05 mouse-y pic 9(4) comp-x. 05 mouse-status pic 9(4) comp-x. ... call x"AF" using get-mouse-details mouse-details
The mouse coordinates assume the upper left corner of the screen is
(0,0). How you translate these coordinates into a menu selection depends
on the orientation (horizontal or vertical), the relative position of the
menu on screen, and the length of each menu item. The
field indicates which mouse button was pressed when the last mouse button
The section Adding Mouse Support to Existing Applications described how you can quickly modify existing applications that contain Adis ACCEPT and DISPLAY statements to use the mouse if one is present. This support enables you to:
However, this support does not enable you to use all of the mouse features. A set of call-by-name mouse routines are available that enable you to access all of the mouse features.
You cannot mix these call by name routines with the older x"AF" call by number routines in the same application.
You cannot use these call-by-name routines where you are using the Micro Focus extensions to the ACCEPT verb. However, they do provide access to several mouse features not possible with the high level routines. These include:
In this section, we look at these new routines and the techniques for using them.
A sample program, rtsmouse.cbl , illustrates these routines and techniques and is provided in your cobol\demo directory. You might want to compile the program and run it with the discussion that follows.
As with the Adis mouse functions, initialization and termination calls are required.
The following section of code shows how initialization and termination calls are carried out:
01 mouse-handle pic x(4) comp-x. 01 mouse-buttons pic x(2) comp-x. ... call "CBL_INIT_MOUSE" using mouse-handle mouse-buttons
call "CBL_TERM_MOUSE" using mouse-handle
The mouse initialization call sets the COBOL special register RETURN-CODE to zero if a mouse is present, and returns both a mouse handle and the number of buttons on the mouse. The mouse handle is a required first parameter of all the other mouse routines. A nonzero value in RETURN-CODE indicates that no mouse was found and that the mouse handle is invalid. Passing an invalid handle to a mouse routine can cause your machine to lock up in some environments.
The following sections describe the aspects of the mouse's behavior you can control using the CBL_ routines.
As a general rule, you want to display the mouse pointer if the user can do something with the mouse on the current screen, for example, click on a button or menu item.
Routines are available both to show and hide the mouse:
call "CBL_SHOW_MOUSE" using mouse-handle
call "CBL_HIDE_MOUSE" using mouse-handle
The routine CBL_HIDE_MOUSE is available only when running a full screen session. The routine behaves unpredictably when running a Windowed session.
You also can make the mouse pointer visible on the portion of the screen where it can be used, but invisible everywhere else.
The following section of code shows how to specify a rectangular area where the mouse is invisible:
01 hidden-area. 05 top-row pic x(2) comp-x. 05 left-col pic x(2) comp-x. 05 bottom-row pic x(2) comp-x. 05 right-col pic x(2) comp-x. ... call "PC_SET_MOUSE_HIDE_AREA" using mouse-handle hidden-area
The CBL_SET_MOUSE_POSITION routine enables you to move the mouse pointer to any location on the screen.
The following section of code shows how you would move the mouse to a specific location on the screen:
01 mouse-position. 05 mouse-row pic x(2) comp-x. 05 mouse-col pic x(2) comp-x. ... call "CBL_SET_MOUSE_POSITION" using mouse-handle mouse-position
The CBL_GET_MOUSE_POSITION routine enables you to return the location of the mouse pointer.
Unlike the Adis mouse functions, you do not have to wait until a button is pressed to get the mouse pointer's position.
The following section of code shows how to return the mouse's current position:
01 mouse-position. 05 mouse-row pic x(2) comp-x. 05 mouse-col pic x(2) comp-x. ... call "CBL_GET_MOUSE_POSITION" using mouse-handle mouse-position
For both routines, the mouse coordinates assume the upper left corner of the screen is (0,0).
A mouse event is generated any time the user moves the mouse pointer, or presses or releases a mouse button. Mouse events are asynchronous; that is, they can occur independently and when other actions are being performed. For instance, the user can move the mouse pointer while the program is in the middle of a file update. So that an application does not miss any potentially important mouse events, these events are stored in a queue until you retrieve them. Reading an event from the queue removes it from the queue.
The following section of code shows how you can determine how many events are waiting in the mouse event queue:
01 queued-events pic x(2) comp-x. ... call "CBL_GET_MOUSE_STATUS" using mouse-handle queued-events
You can read from the queue in two ways:
|Read With Wait||Returns the next event from the queue if there is one. If there are no events in the event queue, the application is suspended until a mouse event occurs, and that event is returned.|
|Read With No Wait||Returns the next event from the queue if one is there.
If there are no events in the event queue, all zeros are returned in
The following section of code shows how mouse events are retrieved from the queue:
01 read-nowait pic x comp-x value h"00". 01 read-wait pic x comp-x value h"01". 01 event-data. 05 event-type pic x(2) comp-x. 05 event-time pic x(4) comp-x. 05 event-row pic x(2) comp-x. 05 event-col pic x(2) comp-x. call "CBL_READ_MOUSE_EVENT" using mouse-handle event-data read-nowait
call "CBL_READ_MOUSE_EVENT" using mouse-handle event-data read-wait
||is the row that the mouse pointer was on when the event started. Remember that the first row is row 0.|
||is the column that the mouse pointer was on when the event started. Remember that the first column is column 0.|
||is the elapsed time from some arbitrary but fixed starting time. The event time is useful when you need to know the elapsed time between two mouse events. For instance, you might want to support both single and double clicking on the mouse buttons. If the event time is zero, there was no event (which implies that the Read No-Wait method was used).|
||contains the type of action that took place.
A different bit is set in this field for each event type. The bit combination identifies which events have occurred. The following table identifies the event actions and their corresponding bit positions. Button 1 is usually the left button on the mouse, and button 2 the right one.
|3||8+||Button 3 pressed.|
|2||4||Button 2 pressed.|
|1||2||Button 1 pressed.|
Since multiple events can occur at one time, you must test for
individual bits in
event-type. See the section Testing
the Value of a Bit for information on how to do this.
The following section of code shows how you can use one of the bit manipulation routines provided with COBOL to test a single bit in a byte:
78 mouse-moved value 1. 78 button1-pressed value 2. 78 button2-pressed value 4. 78 button3-pressed value 8. 01 event-data. 05 event-type pic x(2) comp-x. 05 event-time pic x(4) comp-x. 05 event-row pic x(2) comp-x. 05 event-co pic x(2) comp-x. 01 result pic x(2) comp-x. 01 button1-status pic x(8). ... call "CBL_READ_MOUSE_EVENT" using mouse-handle event-data read-nowait move button1-pressed to result
call "CBL_AND" using event-type result by value 2 if result = button1-pressed ...
The CBL_AND routine sets
result to zero unless the
bit tested for (in this case
button1-pressed) is set
After a call to CBL_READ_MOUSE_EVENT, a value of zero in
indicates that one or more mouse buttons were released.
To support clicking (the conventional method of indicating a choice with the mouse button, involving pressing the button and then releasing it) you need to save the previous state of each button. The click is not complete until the button is released.
The next section of code shows how to check for pressing and releasing the mouse button:
... if result = button1-pressed move "pressed" to button1-status else if button1-status = "pressed" move "released" to button1-status else move space to button1-status end-if end-if ...
Since the mouse pointer could have moved after the button was pressed, you should test the mouse pointer position after the click is complete. The following section of code shows how you could do this.
... if button1-status = "released" evaluate event-row also event-col when 24 also 10 thru 14 ... when 24 also 18 thru 22 ... end-evaluate end-if ...
The event mask enables you to specify what kinds of events are queued.
This mask has the same bit settings as
returned from a call to CBL_READ_MOUSE_EVENT. Setting a bit in the event
mask to 0 results in occurrences of the specified event not being stored
in the event queue. By default, all events are stored in the event queue.
The following section of code shows how you could set or examine the event mask:
01 event-mask pic x(2) comp-x. ... call "CBL_SET_MOUSE_MASK" using mouse-handle event-mask
call "CBL_GET_MOUSE_MASK" using mouse-handle event-mask
The routine CBL_SET_MOUSE_MASK is available only when running a full screen session. The routine behaves unpredictably when running a Windowed session.
When setting bits in the event mask, you will probably want to change the value of one bit without affecting the other bit settings. The ability to do this is shown in the following code:
01 source pic x(2) comp-x. ... move button1-pressed to source call "CBL_OR" using source event-mask by value 2
The mouse pointer is generated on the screen by performing a couple of low-level bit operations on the character and attribute on the screen with a special mouse pointer mask. This process ensures that the mouse pointer is visible whatever the foreground and background colors happen to be. You can control both the foreground and background colors used, and the character displayed at the mouse pointer position, by manipulating this mask with the following code. The following section of code shows how to control the character displayed at the mouse pointer position:
01 mouse-ptr-shape. 05 char-and-mask pic x comp-x. 05 attr-and-mask pic x comp-x. 05 char-xor-mask pic x comp-x. 05 attr-xor-mask pic x comp-x. 01 reserved pic x(10). ... call "PC_SET_MOUSE_SHAPE" using mouse-handle reserved mouse-ptr-shape
call "PC_GET_MOUSE_SHAPE" using mouse-handle reserved mouse-ptr-shape.
For more information on mouse calls, see the chapter Low-level Routines for Character Interfaces.
Copyright © 1999 MERANT International Limited. All rights reserved.
This document and the proprietary marks and names used herein are protected by international law.
|Keyboard Configuration Utility (Keybcf)||Screens|