Modifying Your PM Programs for Pen for OS/2

by Vera Dulaney and Kevin Lee

Last quarter, we provided an overview of how to best use Pen for OS/2. This quarter, we pick up on that concept and describe how to modify a Presentation Manager (PM) program to be pen-aware and, if modification is not possible, we also describe how to write a gesture command handler for an existing PM program.

To Recap...
Pen for OS/2 gives the computer users a much more intuitive pointing device over a mouse. Existing Presentation Manager (PM) applications can easily be modified to make use of the pen interface.

When a menu item is selected from a PM application window, the WM_COMMAND message is sent to its window procedure. Similarly, in a Pen for OS/2 system, when a gesture is given on a PM window, the WM_RECO message is sent to its window procedure. Therefore, Pen for OS/2 performs the actions specified by the gesture. If your application wants to handle the gesture by itself, it must process the WM_RECO message, returning to PM with the RECO_PROCESSED message.

If you do not want to modify your PM application to handle a gesture, your application was already distributed, or no way exists to recall, modify, or redistribute it, but you still want to handle a gesture within your application, you can write a separate command handler. Then, put this command handler name in the gesture setting of your application. When a gesture is given on your application window, Pen for OS/2 initiates this command handler to take care of the gesture.

Recognizing the Pen
For all gestures given on an PM window (even if the gesture is not recognized by Pen for OS/2), the WM_RECO message is sent to the window program. Like other PM messages, the WM_RECO message has 2 parameters, mp1 and mp2. The mp1 parameter has the window coordinate of the hot spot of a gesture; the mp2 parameter has the address of RECODATA structure. Each gesture has its own hot spot. The WM_RECO message is sent to the window that has the hot spot. The RECODATA structure has 13 fields; however, this article explains only the two most common, HRECO and RECOID. For an explanation of the other fields, please see the PENPM.H file in Pen for OS/2 Developer's Toolkit, which is on your accompanying Developer Connection CD-ROM.

The HRECO field is the Recognition subsystem handle. Pen for OS/2 Version 1.0 supports only the Gesture subsystem. Future Pen for OS/2 releases might also include support for the Voice subsystem.

The RedQueryRecoSubsystem API takes the handle as input and returns the subsystem name, as well as the number of events in the subsystem. The RECOID field is an Event ID of the recognition subsystem. The RedRecoNameFromID API uses the HRECO and RECOID fields, and returns the event name. For example, if the HRECO is 1 and RECOID is 6, the Pigtail gesture name is returned. The application writer can do whatever is needed with the subsystem and its event ID.

For the unrecognized gesture, a NULL event name will be returned by the RedRecoNameFromID API. While you process the WM_RECO message, do not give a message or a dialog box. This will cause a deadlock to occur. If you have to give the box, simply post a message to yourself, then give the box while you process the message. After you process the WM_RECO message, return to PM with RECO_PROCESSED. Then, Pen for OS/2 knows that the application has handled the gesture. The sample code shows the WM_RECO message handler in the client window. For more information, please check the WMRECO program in the Pen for OS/2 Developer's Toolkit sample program.

Writing a Pen for OS/2 Command Handler
You can write a command handler for an application and put the handler name in the gesture setting of the application. When a gesture is given on the application window, Pen for OS/2 initiates the command handler, retrieve the RECODATA, and perform an action required for the gesture. For a subsequent gesture given on the application window, WM_RECO_COMMAND is sent to the command handler window procedure. In this way, any actions required for the gestures can be done by the handler, not by Pen for OS/2.

The following explains how to assign the command handler to the gesture setting of the application: You can put the command handler name (without the .EXE extension) in the Command field. If the command handler is not in a directory identified on the PATH= parameter in your CONFIG.SYS file, you must include its full path name. Any parameters put in the Parameters field are in argv of command handler. Several gestures can share one command handler or each gesture can have its own command handler. Up to 20 command handlers can run at any time.
 * On the Workplace Shell desktop, click the right mouse button on the application icon.
 * Select the right arrow in Open item, and then select Settings. The settings dialog window appears and the Gesture setting page is added by Pen for OS/2. In this page, from the listbox of all gestures, you can give your command handler name to any gestures.
 * To set a command handler to a gesture, highlight the gesture and select the Edit button. Another dialog window appears with Command and Parameters fields.

When the command handler is initiated, it registers itself as a command handler using the RedRegisterRecoCommand API. Pen for OS/2 saves the command handler name in its internal table. After the registration, it calls the RedRecoDataFromEnv API to retrieve the RECODATA structure. The Command, Parameter, and Prefix Command fields pointed to by three pointer fields in RECODATA are attached after the RECODATA, so this API must have a large buffer.

Like a Pen-aware application, the command handler can use the HRECO and RECOID in RECODATA to retrieve subsystem and event names. When subsequent gesture is given on the application window, Pen for OS/2 checks the gesture setting of the subsequent gesture to get the command handler name and, if it cannot find the command handler in its internal table, it initiates another command handler. Otherwise it sends the WM_RECO_COMMAND message to the running command handler. The processing of this message is same as the WM_RECO message, except for the mp1 parameter.

If any file is accessed inside the command handler, use the full path name of the file. The DosQueryCurrentDisk and DosQueryCurrentDir APIs usually give a root directory of the boot disk, but not always.

An example of the Client Window procedure of a command handler follows. For command handler details, please see the RECODISP sample program in the Pen for OS/2 Developer's Toolkit.