PreviousException Handling Frameworks Component FrameworksNext"

Chapter 31: GUI Class Frameworks (Windows & OS/2)

This chapter documents the frameworks used by the Object COBOL GUI classes. The information here will help you to create windows and dialog boxes by subclassing, and to write application code to run the interface.

The information in this chapter applies only to Object COBOL systems running on Windows or OS/2.

31.1 Overview

The GUI class frameworks are concerned with event handling and the display of other objects on GUI objects. Events are the link between the user, your interface and your application code.

For example, whenever the user moves the mouse, clicks a button or pushes a key, the operating system notifies your application of an event. If you code your interface using the Windows or OS/2 Presentation Manager API you have to poll for all these events, and act on the ones you are interested in.

The GUI Class library simplifies writing an interface by enabling you to specify those events you are interested in. You then get notified only of the events which you specified. All the polling is handled for you by the EventManager class, and in such a way that a computer can continue to execute other applications while yours is idle.

31.2 Event Handling

A GUI object displayed on your desktop receives many events from the operating system. However, your application is only notified of those events in which you have registered an interest. You can register an interest in events in one of two ways:

Each type of event which can occur has a unique identifier, the Event ID.

31.2.1 Event ID Format

You can categorize the events a GUI object can receive or raise as either of the following:

All events are represented as PIC X(4) COMP-5 data items. You can give logical events any numeric IDs which do not coincide with IDs already assigned to physical events. Physical event IDs defined in the copyfile p2cevent.cpy; if you accepted default directories when you installed the product, this will be in \cobol\source\oops. We suggest that you do not number your events starting with the lowest number available; future releases of Object COBOL GUI classes may handle a much greater number of physical events than they do currently.

All the physical events recognized by the GUI objects supplied with Object COBOL have IDs assigned to level 78 data items in copyfile p2cevent.cpy.

31.2.2 Invoking a Method from an Event

You can register an interest in an event so that when the event occurs it invokes a method. To do this, you send a GUI object the "setEventTo" message.

For example, if you had a pushbutton on a window, you might want to send a message to the window every time the button is pushed. The code below sets up aButton so that every time it is pushed, aWindow gets the "buttonPushed" message:

   move p2ce-clicked to event
   invoke aButton "setEventTo" using 
                               event aWindow
                               z"buttonPushed"

In this example, P2CE-CLICKED is one of the physical event IDs declared in copyfile p2cevent.cpy. Note the "z" at the start of the literal giving the message name; this is a piece of syntax which appends a null-byte (x"00") to the end of a literal. This enables the "setEventTo" method to find the end of the string.

All GUI objects supplied with this class library respond to the "setEventTo" message. There is also a "setEvent" method; this has the same functionality as "setEventTo", but instead of providing a target object and a method name, you pass a CallBack as the parameter.

31.2.3 Remapping Events

You can map physical events to logical events. This helps you to decouple an application object from the user interface. For example, in the supplied Bank application demonstration, pushing the Add button or selecting Add from the File menu of the main window raises the logical event add-record on the Bank window.

The controlling application object has registered an interest in add-record events on the Bank window. The effect is that the application is notified whenever the user wants to add a record. The application does not need to know about the controls on the Bank window, only to know what is being requested when the controls are operated.

The two pieces of code below show how you could set up this type of mapping between a physical event and a logical event. In the initialization code for the window which owns the pushbutton you would put:

    move p2ce-clicked to physicalEvent
    move add-record   to logicalEvent
    invoke aButton "translateEvent" using
                                    physicalEvent
                                    self
                                    logicalEvent

In the initialization code for your application you would code:

    move add-record to logicalEvent
    invoke theBankWindow "setEventTo" using logicalEvent
                                            self
                                            "addRecord "

When the end-user of your application pushes the button on the window, the button raises an ADD-RECORD event on the window. The application object has registered an interest in the ADD-RECORD event, and gets the "addRecord" message (this part of the mechanism is the same as described in the section Invoking a Method from an Event).

31.2.4 Interface for Methods Invoked by Events

This section documents the interface for methods invoked by events. A method is invoked as a result of an event against which it has been registered by the "setEventTo" or "setEvent" methods. The event method receives an event object which it can interrogate for further information about the event, although in many cases you will not need to do this.

Implement the interface to methods which are invoked by events as follows:

 method-id. "methodName".
 linkage section. 
 01  anEventObject          object reference.
 procedure division using anEventObject. 
* Code to interrogate anEventObject and handle the event.
    exit method.
 end method "methodName". 

You can get the object handle of the object which received the event from the event object, as well as the state of the keyboard and the position of the mouse at the time of the event. For more information, look up the interface for the Event class in your on-line Class Library Reference.

31.3 Subclassing GUI Objects

One of the easiest ways to create a GUI for your application is to create one class for each different window or dialog box displayed by your interface. You can do this by subclassing from Window, or from Modal and Modeless (for the dialog boxes).

Then you write instance initialization code for each subclass which sets the title, size, position and gadgets (gadgets are things like pushbuttons, menus and entryfields) for that particular window or dialog box. This section tells you how to write the instance initialization code so that it works together with the "new" class method provided by the GUI Class Library classes.

To create a new GUI object of any kind, you send its class object the "new" message. For example:

   invoke BankWindow "new" using oo-desktop
                       returning aBankWindow

In the code above, OO-DESKTOP is the parent to the window. The parent to a window or dialog box can be another window or dialog box, or the operating system desktop. The operating system is represented by OO-DESKTOP, which you should declare as OBJECT REFERENCE EXTERNAL so that it can be initialized by the EventManager.

The "new" method, which is implemented for you when you subclass from any of the supplied GUI classes, creates a new instance of your GUI object, and sends the instance the "initialize" message. You can put all the code to initialize your instance inside an "initialize" method and it gets invoked for you by the "new" method.

Your "initialize" method must have the following interface:

 
 method-id. "initialize".
 linkage section.
 01  lnkParent               object reference. 
 procedure division using lnkParent. 
    invoke super "initialize" using lnkParent
* Code to initialize this instance. 
    exit program
 end method "initialize"

The first line of your "initialize" method sends the "initialize" message to the superclass, so that the basic initialization for your GUI object gets carried out. This includes registering your GUI object as a child of its parent.

You can see some example code for initializing GUI objects in the BeepWindow (beepwin3.cbl) and BankWindow (bwindow.cbl) classes included with the tutorials for this product. The initialization code for BeepWindow is explained in the chapter Writing a Class Program Tutorial, and there is further discussion of GUI programming in the chapter GUI Programming Tutorial.


Copyright © 1999 MERANT International Limited. All rights reserved.
This document and the proprietary marks and names used herein are protected by international law.

PreviousException Handling Frameworks Component FrameworksNext"