Windowing Support for Text-based Systems | Presentation Manager Applications (32-bit) |
This chapter explains how to create OS/2 Presentation Manager applications using the 16-bit COBOL system. It assumes that you have a basic knowledge of the concepts involved in writing a Presentation Manager program.
This chapter assumes that you are using the 16-bit Presentation Manager API. The 32-bit API available with OS/2 V2.0 and later uses different parameters in some calls; it is described in the chapter Presentation Manager Applications (32-bit).
Presentation Manager (PM) is a graphical user interface (GUI) for OS/2 which provides functions for creating windowed applications. Presentation Manager implements the Common User Access (CUA) user interface standard, allowing you to create applications with a common style of interface.
Micro Focus offers three approaches to 16-bit Presentation Manager programming in COBOL:
The chapter Comparison of Methods for Creating User Interfaces explains the advantages and disadvantages of each approach.
In addition to this COBOL system you need the OS/2 Programmer's Toolkit available from your operating system supplier. This software package includes the Dialog Editor, Icon Editor, and Resource Compiler, as well as the C header files that contain the type information and constants used by the OS/2 application programming interface (API) functions.
The Resource Compiler converts menu definitions, icon declarations, accelerator tables, and other structures from readable ASCII files to a binary format which can be incorporated within an .exe or .dll module. The editors enable you to paint dialog boxes, icons and fonts.
Your OS/2 Programmer's Reference describes the OS/2 API functions used by Presentation Manager applications. However, the function descriptions and examples in the OS/2 Programmer's Reference are in C. This chapter explains those descriptions for programmers unfamiliar with C and describes how to translate them into COBOL. This COBOL system includes the H2cpy utility, which allows you to translate #define and typedef information in the C header files into their COBOL equivalents. See your Programmer's Guide to Writing Programs for details about converting C header files with H2cpy.
This system includes two sample Presentation Manager programs, Pmhello and Pmcalc2. These are used as examples in this chapter.
OS/2 offers Presentation Manager as a graphical user interface to applications in a multitasking environment. An application running under Presentation Manager shares the display with other tasks by using windows, which it creates for interaction with the user. Presentation Manager manages the screen, so an application does not have to worry about other windows on the screen.
In a traditional environment, the program accepts user input in a predetermined order. This is called procedure logic. In a windowed environment, applications respond to user input events as they occur. This is called message-based or event-driven logic. For example, a window event such as a mouse click can occur at any time; the application must respond to that event immediately.
Presentation Manager puts information from the mouse and keyboard in a standard format called a message. These messages are stored in a queue until they are retrieved by the application - there is a separate queue for each application. Each message in the queue contains information identifying the window that received the message, the message event itself (for example "left button pressed" or "Escape key pressed") and any other applicable information.
Such event driven programming is an integral part of Presentation Manager object oriented programming where events are called messages and recipients of messages are called objects. Examples of Presentation Manager objects are windows, dialog boxes and menus.
A Presentation Manager application must create a message queue and implement a message loop. This loop retrieves messages from the message queue and dispatches them to the message handler (called a Window Procedure or WinProc for short) for the window receiving the message.
Each WinProc implements a window class. Many instances of each window class (or type) can be created, but they all share the same WinProc. Window classes are given a name and must be registered with the Presentation Manager subsystem before they can be used.
Extensions have been added to the COBOL syntax to enable the systems programming facilities required to use API's like the Presentation Manager API. These extensions are grouped under the name Systems Programming Extensions.
The Systems Programming Extensions include:
All of these are described fully in the Language Reference. Examples of their use are given in this chapter.
The OS/2 API uses a different parameter-passing convention to COBOL. Usually, COBOL pushes parameters onto the stack by processing the items in CALL statements from right to left. OS/2 API routines, however, expect them in the reverse order; that is, from left to right. Also, COBOL normally expects the calling program to tidy the stack of used parameters after a call whereas OS/2 API routines do this work themselves. You must therefore define the appropriate convention and specify it when calling OS/2 API routines.
To define a calling convention in COBOL, use the CALL-CONVENTION clause in the Special-Names paragraph (see your Language Reference). This clause associates a name with a particular calling convention. You use the name in each call for which the defined convention is to apply.
The calling convention is set with a 16-bit number, where each bit is assigned a particular meaning. This is described in the chapter The COBOL Interfacing Environment in your Programmer's Guide to Writing Programs.
The OS/2 API routines can be treated as a special case of a subprogram that can be called directly from COBOL. The API routines should always be called using a calling convention that includes the Pascal conventions (bits 1 and 2 set in the value, for example CALL-CONVENTION 3) and, since these routines are always resolved at link time, all calls to API routines should be static linked. This must be done either by the recommended method of using CALL-CONVENTION 11 (combining conventions 8 and 3) or by the obsolete method of preceding the API routine name with a double-underscore prefix.
Example
special-names. call-convention 11 is os2api call-convention 3 is os2apiold. . . . call os2api "WinInitialize" using ... . . . call os2apiold "_ _WinInitialize" using ...
If the COBOL program is to be called by an OS/2 API routine, you will need to specify the calling convention in the PROCEDURE DIVISION header:
procedure division os2api.
By default, the parameters passed by a COBOL CALL statement are address references, using the address of the parameters in memory. Presentation Manager requires some parameters to be passed by value. The example below shows how to do this.
Remember to specify the size in bytes using the SIZE clause with numeric literals. If you do not specify the SIZE clause, a size of four is assumed.
Example
call "myprog" using by reference param-1 by value param-2 by value 27 size 2
The mechanisms for returning values from a WinProc, and receiving values returned from an API routine are explained in the following sections.
The RETURNING phrase of a CALL statement stores a value returned by an OS/2 API function.
Example
call os2api "WinInitialize" using by value 0 size 2 returning hab
This stores the result returned by the API function WinInitialize in the
data item hab
. Presentation Manager calls return either a
two- or four-byte value.
A Presentation Manager window procedure often needs to return a value to the function that called it. In COBOL use the RETURNING phrase on the EXIT PROGRAM statement:
Example
exit program returning mresult
A data item declared as PROCEDURE-POINTER passes the address of a window procedure to the Presentation Manager so that it can call that procedure with messages for the window.
Example
03 WndProc usage procedure-pointer. . . . . . . entry "WndProc" using by value hwnd set WndProc to entry "WndProc" call os2api "WinRegisterClass" using by value hab by reference MyClass by value WndProc by value CSClass by value 0 size 2 returning my-refum-value.
Since a Presentation Manager program can process a new event before the processing of a prior event is complete, recursion is required. That is, a program must be able to call itself. It is important that the processing of data should not hold up the handling of events.
Example
Support for recursion enables you to write a message loop as follows:
perform until loop-end call os2api "WinGetMsg" using ... call os2api "WinDispatchMsg" using ... end-perform
By default, all COBOL variables are global ; that is, any variable defined in the Working-Storage Section can be referenced from any other section of the program.
Since Presentation Manager can call an entry point several times, the local data from one call needs to be protected by another call entering the same code. This COBOL system lets you create variables that are local to a particular invocation of a procedure; these variables can be referenced only within that procedure. These variables are created on the stack when a procedure using them is called, then discarded when the procedure terminates. You define these variables in the Local-Storage Section.
Use local variables when writing recursive procedures (see your Programmer's Guide to Writing Programs). If you use global variables in a recursive procedure, each new procedure invocation references the same storage location for a particular variable-name, overwriting information that should be unique to that invocation. The Local-Storage Section eliminates this problem by creating an individual set of procedure variables for each invocation.
Indirect recursion occurs when a procedure invokes Presentation Manager, which in turn calls that procedure. Although it is indirect, this recursion can still overwrite variables that should remain distinct for each invocation. Therefore, unless you are certain that a variable in a Presentation Manager program is truly global and will not change between invocations of a procedure, you should declare it in the Local-Storage Section.
This section of code illustrates the use of the Local-Storage Section:
working-storage section. ... local-storage section. 01 hps pic x(4) comp-5. 01 rcl. 03 xleft pic x(4) comp-5. 03 xbottom pic x(4) comp-5. 03 xright pic x(4) comp-5. 03 xtop pic x(4) comp-5. 01 mresult pic x(4) comp-5. linkage section. 01 hwnd pic x(4) comp-5. 01 msg pic xx comp-5. 01 mp1 pic x(4) comp-5. 01 mp2 pic x(4) comp-5. procedure division os2api. main-control section. entry os2api "ClientWndProc" using by value hwnd by value msg by value mp1 by value mp2. ...
All Presentation Manager programs must perform the same basic steps:
The first action in your Presentation Manager application is to call
the WinInitialize function. Calling this function declares that this
program or thread is going to use Presentation Manager. WinInitialize
returns the handle of an anchor block (hab
). The anchor
block handle is a value that identifies the application to Presentation
Manager.
call os2api "WinInitialize" using by value 0 size 2 returning hab.
In this example, the first parameter passed to the function is an
initialization option and must be set to 0. The returned parameter,
hab
, is the handle to the anchor block for the application.
The next step in your program is to set up a message queue for this
thread. The message queue receives messages sent to all of the windows
which were created by the current program or thread. Your application must
create a message queue before it can create a window. The returned
parameter, hmq
, is the handle to the message queue. This
message queue handle is saved so it can later be passed to the function
that terminates the message queue.
call os2api "WinCreateMsgQueue" using by value hab by value 0 size 2 returning hmq.
Next your program calls WinRegisterClass to create a window class. Every window that is created under Presentation Manager must belong to a window class. The window class defines a window procedure and other information, such as default window styles.
set WndProc to entry "WndProc" call os2api "WinRegisterClass" using by value hab by reference MyClass by value WndProc by value CSClass by value zerobytes size 2 returning bool
After you have created the window class you can create a window. A Presentation Manager window is the main method of interacting with the user.
Your program creates a standard window by calling the WinCreateWindow or the WinCreateStdWindow function:
call os2api "WinCreateStdWindow" using by value Hwnd-Desktop by value WSWindow by reference ctldata by reference MyClass by reference "mytitle" & x"00" by value 0 size 4 by value 0 size 2 by value 0 size 2 by reference hwndClient returning hwndFrame
Presentation Manager sends many messages to each window to convey important information and to inform them of a wide variety of events. To receive these your application includes a message loop. This loop collects messages from your message queue and dispatches them, via Presentation Manager, to the window specified by the window handle contained in the message.
The function WinGetMsg reads the next available message from the queue. The WinDispatchMsg function dispatches this message throughout the system so the message can be processed.
Example
Processing the message loop:
perform until loop-end call os2api "WinGetMsg" using by value hab by reference qmsg by value 0 size 4 by value 0 size 2 by value 0 size 2 returning bool if boolfalse set loop-end to true else call os2api "WinDispatchMsg" using by value hab by reference qmsg end-if end-perform
When your program dispatches a message to Presentation Manager using WinDispatchMsg, Presentation Manager evaluates the message and, if appropriate, sends it to your client window. The link between the window and the window procedure is established by the WinRegisterClass call.
Example
This section of code outlines how to process the WM-PAINT message in a window procedure.
entry "ClientWndProc" using by value hwnd by value msg by value mp1 by value mp2. ... evaluate msg when wm-paint call os2api "WinBeginPaint" using by value hwnd by value 0 size 4 by value 0 size 4 returning hps ... call os2api "WinEndPaint" using by value hps ... when other call os2api "WinDefWindowProc" using by value hwnd by value msg by value mp1 by value mp2 returning mresult ... end-evaluate exit program returning mresult.
Before your program exits it should release the resources it got from Presentation Manager. First you call WinDestroyWindow to close any windows created by WinCreateStdWindow or WinCreateWindow. Then you call WinDestroyMsgQueue to dispose of the message queue created in the WinCreateMsgQueue call. Finally, your program must call WinTerminate to tell the system that you have finished with Presentation Manager.
Example
Terminating Presentation Manager:
call os2api "WinDestroyWindow" using by value hwndFrame call os2api "WinDestroyMsgQueue" using by value hmq call os2api "WinTerminate" using by value hab
The OS/2 Programmer's Reference describes all the OS/2 API functions in terms of the C programming language. For those programmers unfamiliar with C, this section explains how to translate these descriptions into COBOL.
Your OS/2 Programmer's Toolkit includes definitions of many of the Presentation Manager function parameters in C header (.h) files. This COBOL system includes the H2cpy utility to convert typedef, function prototype and #define statements in .h files to COBOL copyfile form. See your Programmer's Guide to Writing Programs for instructions on using H2cpy and for details on typedefs and CALL prototypes.
This COBOL system contains a utility, H2cpy, to convert C header files into COBOL copyfiles. The utility converts C header files including those supplied with the OS/2 Programmer's Toolkit into COBOL type definitions and COBOL CALL prototypes. It is especially useful if you want to write Presentation Manager applications in COBOL using the System Programming Extensions.
Before you can compile any of the sample programs (or your own Presentation Manager software), you must first run H2cpy to translate the C header files into COBOL, using a command line such as:
h2cpy os2.h /D incl_pm /D incl_base /I \incdir /X
This translates the os2.h file and all its included files (in this example assumed to be located in the directory \incdir) into the COBOL copyfile os2.cpy. You may use the COPY statement to include this file in your program. The Compiler will then validate any function calls that you make to ensure that the parameters conform to the COBOL CALL prototype in os2.cpy. H2cpy will automatically generate useful CALL prototypes from the C function prototypes. However, it may be that you find the validation inappropriate in some cases. You have the choice of either modifying os2.cpy or of running H2cpy with the option to suppress the generation of CALL prototypes.
The C definition of the WinCreateStdWindow API function is shown in the following example; the rest of this section explains how to translate this C definition into COBOL.
HWND WinCreateStdWindow (HWND hwndParent, ULONG flStyle, PULONG pflCreateFlags, PSZ pszClientClass, PSZ pszTitle, ULONG styleClient, HMODULE hmod, USHORT idResources, PHWND phwndClient);
The following list defines each of the words in the example:
Word |
Meaning |
---|---|
HWND |
Function returns data of type HWND |
WinCreateStdWindow | Function-name |
HWND |
The data-type of the parameter hwndParent
|
hwndParent |
Possible name for the parameter (optional in the definition, but required in any use of the function) |
ULONG |
The data-type of the parameter flStyle
|
flStyle |
Possible name for the parameter |
. . . |
Remaining data types and names |
); |
End of the function definition |
All OS/2 API function definitions appear in at least one of the OS/2 header files. The names used for the parameters are not significant and may differ between the documented function definition and the equivalent definition in the header file.
You now need to find the definitions of the data types and other constructs and decide how to code them in COBOL. This information is in the files produced by H2cpy. Coding is fairly straightforward but instead of passing fully typed pointer parameters by value, as described in the C function definition, COBOL can often pass them more conveniently using the BY REFERENCE clause as may be shown in the COBOL prototype.
The first thing you need to determine is the calling convention required by the WinCreateStdWindow routine.
Look this routine-name up in os2.cpy and you will find a CALL prototype definition such as:
entry "WinCreateStdWindow" using by value data-pointer by value uns-long by reference uns-long by reference any by reference any by value uns-long by value uns-short by value uns-short by reference data-pointer returning data-pointer
The parameters are specified in terms of COBOL type definitions data-pointer
,
uns-long
, and others, which are defined at the beginning of
the os2.cpy file. The parameter any
signifies that
any data-type can be used. All COBOL CALL statements referencing
WinCreateStdWindow must use parameters that conform with the corresponding
data-type otherwise the Compiler will give an error. Wherever possible it
is preferable to use the type definition when defining data items rather
than the explicit COBOL PICTURE so that your program will be more portable
between different OS/2 API environments.
The calling convention that the routine WinCreateStdWindow requires is given in the Special-Names paragraph of the program in which it is defined. Look in os2.cpy for the program-id preceding the call prototype and you will find a declaration such as:
program-id. "c_typedefs" is external. special-names. call-convention 3 is pascal-convention.
This tells you that the routine WinCreateStdWindow must be called with a calling convention of 3. This means that you must define a calling convention for calls to the OS/2 API routines. To combine the Pascal calling convention with the static-link call convention, add the following line to the Special-Names paragraph:
call-convention 11 is os2api
Returning to the C definition of the WinCreateStdWindow example above,
the first data-type you need to translate is HWND
. Since
WinCreateStdWindow returns a value of type HWND
, you need to
define a storage location for that value, say hwndResult
.
Looking up HWND
in the file os2.cpy, you find this
definition:
01 HWND is typedef usage data-pointer.
The word TYPEDEF indicates that the data-type HWND
is a
type definition and so can be used to define the type (usage) of the
variable hwndResult
. HWND
is defined as having
the data-type data-pointer
, which is defined at the
beginning of the os2.cpy file as:
77 data-pointer pointer is typedef.
The data types HWND
and data-pointer
are,
therefore, both equivalent to the COBOL USAGE POINTER and they can all be
used interchangeably. The COBOL CALL prototype found earlier indicates
that the routine returns a value of type data-pointer
and so
you can define hwndResult
in terms of HWND
.
However, as a COBOL programmer you may find the definition more convenient
with the equivalent line:
01 hwndResult usage data-pointer.
Next consider the parameters to the function call. The first parameter
has type HWND
, which has already been determined as type
data-pointer
. The CALL prototype says that the first
parameter must be passed BY VALUE and have a type data-pointer
and so you can write the line:
01 hwndParent usage data-pointer.
Next is data-type ULONG
. From os2.cpy you get:
01 ULONG is typedef usage uns-long.
The CALL prototype says that the second parameter must have a type
uns-long
and so you can write the line:
01 flStyle usage uns-long.
Next is data-type PULONG
. From os2.cpy you get:
01 PULONG is typedef usage data-pointer.
The CALL prototype says that the third parameter must have a type
uns-long
, so PULONG
cannot be used directly.
The C definition for PULONG
indicates that it is a pointer
to a data item of type ULONG
, so you can write the line:
01 flCreateFlags usage uns-long.
Next is data-type PSZ
. From os2.cpy you get:
01 PSZ is typedef usage data-pointer.
The CALL prototype says that the fourth and fifth parameters must be passed BY REFERENCE but can be of any type. The BY REFERENCE clause is a convenient COBOL way of avoiding direct use of parameter pointers and of permitting type checking. It is otherwise equivalent to passing a parameter as an untyped pointer BY VALUE.
The C header file declares the parameter pszClientClass
as
a char pointer. In C, a char pointer references a char datatype which
represents both a one-byte numeric item or the start of a multi-byte text
string. In contrast, COBOL recognizes a one-byte numeric item and a
multi-byte alphanumeric item as distinct data types. For this reason, when
H2cpy translates a C function prototype parameter that is a char pointer
it cannot specify a specific data type and so generates any
.
The API function description indicates that the parameter pszClientClass
is a pointer to a C string which is a multi-byte text item that is
terminated by a C null character. The closest COBOL equivalent is either
an alphanumeric data item that includes a C null character within its
value or a concatenation of an alphanumeric data item with an explicit C
null character. (You can use the DELIMITED clause if you are prepared to
modify your CALL prototype; see your Language Reference
for details.)
It is generally convenient to use the COBOL concatenation
operator. For example you can define the BY REFERENCE parameters
for pszClientClass
and pszTitle
as:
01 szClientClass pic x(9) value "My-Class" & x"00". 01 szTitle pic x(9) value "My-Title" & x"00".
Where a literal such as x"00" is used many times, it is important that the correct value is coded each time. This can be done in a simple way by declaring the literal as a level-78 item and thereafter using the level-78 name:
78 c-null value x"00". 01 szClientClass pic x(9) value "My-Class" & c-null. 01 szTitle pic x(9) value "My-Title" & c-null.
After defining the complete list of parameters using similar methods, you end up with the following source lines:
copy "os2.cpy" replacing ==call-convention 3== by ==call-convention 11==. program-id. pmdemo. special-names. call-convention 11 is os2api. working-storage section. 78 c-null value x"00". 01 hwndParent usage data-pointer. 01 flStyle usage uns-long. 01 flCreateFlags usage uns-long. 01 szClientClass pic x(9) value "My-Class" & c-null. 01 szTitle pic x(9) value "My-Title" & c-null. 01 styleClient usage uns-long. 01 hmod usage uns-short. 01 idResources usage uns-short. 01 hwndClient usage data-pointer. 01 hwndResult usage data-pointer.
Note: The standard naming convention used in the C header files
uses a type-name prefixed by the letter P to indicate a far pointer to
that type. For example, PULONG
indicates a far pointer to a
variable of type ULONG
.
When calling an OS/2 API routine, you must either use CALL-CONVENTION 11 or if you use CALL-CONVENTION 3 you must precede each name by two underscore characters ( _ _ ). This ensures that the call is static (resolved at link time).
After you have performed all these conversions, the COBOL call to the API function WinCreateStdWindow becomes:
call os2api "WinCreateStdWindow" using by value hwndParent by value flStyle by reference flCreateFlags by reference szClientClass by reference szTitle by value styleClient by value hmod by value idResources by reference hwndClient returning hwndResult
If the values you pass to the function are numeric constants, you can use the:
by value literal size n
construct as long as you specify the size of the literal. Therefore, if
the values you specify for styleClient
, hmod
,
and idResources
are all 0, you can replace the parameters by
literals. Constant alphanumeric literals can also be used, to give the
following call:
call os2api "WinCreateStdWindow" using by value hwndParent by value flStyle by reference flCreateFlags by reference "My-Class" & c-null by reference "My-Title" & c-null by value 0 size 4 by value 0 size 2 by value 0 size 2 by reference hwndClient returning hwndResult
Constants defined at level-78 do not have any size associated with them. When they are used as parameters in a CALL statement, they default to a size of four bytes. The SIZE phrase of the USING clause can be used specifically to set the number of bytes passed as the parameter.
For example, the constant CS_SIZEREDRAW
is defined in the
C header files and generates a COBOL statement in os2.cpy:
78 CS-SIZEREDRAW value h"00000004".
If you use this literal value as a parameter, you would have to add a SIZE 4 clause to specify the correct size.
... by value CS-SIZEREDRAW size 4
Note: C uses the underscore character ( _ ) to split long names or prefixes. The underscore cannot be used in COBOL. Therefore, H2cpy replaces all underscores in names with hyphens (-) .
H2cpy does not convert C macros defined in the header files, because COBOL has no equivalent feature. However, in COBOL, the REDEFINES statement can often be used to achieve the same effect.
Example
The message parameters used by Presentation Manager are defined as type
MPARAM
. H2cpy produces the following definition for this
type:
01 MPARAM is typedef usage data-pointer.
The message parameters are actually used in different ways, depending on the message being sent. Therefore, C macros are provided in the header files to access parts of the message parameter. To access them in COBOL, you can use the mechanism shown below.
A variable mp1
of type MPARAM
would be
defined this way:
01 mp1 pointer. 01 mp1-9 redefines mp1 pic S9(9) comp-5. 01 redefines mp1. 03 mp1w1 pic S9(4) comp-5. 03 mp1w2 pic S9(4) comp-5. 01 redefines mp1. 03 mp1b1 pic S9(2) comp-5. 03 mp1b2 pic S9(2) comp-5. 03 mp1b3 pic S9(2) comp-5. 03 mp1b4 pic S9(2) comp-5.
The bytes and words of mp1
can now be accessed
individually. The equivalents of the principal C macros are as follows:
C Macro |
COBOL |
---|---|
MPFROMCHAR(x) |
move 0 to mp1-9 |
MPFROMSHORT(x) |
move x to mp1w1 |
CHAR1FROMMP |
mp1b1 |
CHAR4FROMMP |
mp1b4 |
The following sections explain how to compile, link and debug your Presentation Manager application.
Compiling a program for Presentation Manager is no different from compiling any other program. Since OS/2 runs only on machines using an 80286 (or more advanced) processor, you can use the TARGET"286" directive to produce slightly faster and more compact code. However, this is not required.
For running under Animator or Animator V2, the compiler normally creates a .def file. If you have already created a .def file for the Presentation Manager .exe file, you should specify one of these directives:
When linking Presentation Manager applications, you must create a .def file with the WINDOWAPI attribute in the NAME statement, or the resulting executable file will not be able to run in a window. The .def file must also include an EXPORTS statement to tell the operating system the starting address of the window procedure.
For example, the commands to compile and link Pmcalc2 are:
cobol pmcalc2.cbl target(286); link pmcalc2+cobintfn,,,lcobol+cobfp87o+os2,pmcalc2.def/nod; rc pmcalc2.res pmcalc2.exe
pmcalc2.def contains these lines:
NAME PMCALC2 WINDOWAPI PROTMODE STACKSIZE 16384 EXPORTS MWndProc @1 BWndProc @2 DlgProc @3
Applications for Presentation Manager must be linked with os2.lib rather than doscalls.lib, since the latter supports only the kernel OS/2 API calls. For OS/2 V2.0 or later use the library os2286.lib .
If the application includes icons , dialog boxes, or other resources, you must use the Resource Compiler (RC) to add the compiled resource to the linked executable file. The OS/2 Programmer's Toolkit manuals explain how to use the Resource Compiler.
You can use Xilerator, Animator or Animator V2 to debug a Presentation Manager application.
Xilerator, part of the add-on product Toolset, is a text-based COBOL debugger. It works in a similar way to Animator but, whereas Animator debugs programs at the intermediate code level, Xilerator debugs programs at the generated code level.
When debugging a Presentation Manager application on OS/2 V2, Xilerator uses hard mode debugging. This means that Xilerator runs in a text window on the Presentation Manager screen but, while your program is stopped in Xilerator, you cannot access any other window. If you move or resize the Xilerator window, any parts of your application's windows that are exposed are not repainted until the next time that you allow your application to run.
To use Xilerator, compile with the GANIM directive and link in the usual way to give an .exe file. For example, the commands to prepare Pmcalc2 are:
cobol pmcalc2.cbl target(286) ganim; link pmcalc2+cobintfn,,,lcobol+cobfp87o+os2,pmcalc.def/nod;
Then to xilerate pmcalc2.exe, type:
xil pmcalc2.exe
It is possible to use Animator to debug Presentation Manager applications by using cross-session mode, but there are two disadvantages:
For Presentation Manager programming, compile with the ANIM and OPT"0" (to prevent the automatic link) directives and manually link with the Coblib and OS/2 run-time support libraries (coblib.dll and os2286 on OS/2 V2.0 or later) and an appropriate .def file to create a .dll file. If you specify the directive DEFFILE"filename" where filename is the name of the .def file, the Compiler produces a suitable .def file for you.
Before starting the animation, any Presentation Manager resources needed by the application must be made available. These can be linked into the .dll file with the Resource Compiler before animating, provided the program contains code to get its module handle. An example of code to do this is given below:
01 filler. 03 modname pic x(7) value "pmcalc2" & x"00". 03 modhandle pic xx. . . . . . . call os2api "DosGetModHandle" using modname modhandle if return-code not = 0 move x"0000" to modhandle end-if
In any call that requires a module handle (for example, DosGetResource),
the modhandle
variable obtained is used. To ensure that the
call executes correctly, the program being animated must be in the current
directory.
To prepare the Pmcalc2 sample program for Animator debugging, use these commands:
cobol pmcalc2.cbl target"286" anim opt"0" deffile"pmcalc2.dfa"; link pmcalc2+cobintfn,,,coblib+cobfp87o+os2,pmcalc2.dfa/nod; rc pmcalc2.res pmcalc2.dll
Then to animate the program in cross-session mode, type:
animate pmcalc2.dll user-session(pm)
It is possible to use Animator V2 to debug Presentation Manager applications using cross-session mode. This has the disadvantage that your application's user interface will run very slowly, as it would under Animator, but it can use hard mode debugging which does not cause Presentation Manager to fail when your application is stopped under Animator V2.
To use Animator V2 with hard mode debugging, prepare a .dll file in the same way as for Animator, and ensure that the environment variable COBANIM_2 is set to ANIMGUI.
The OS/2 Programmer's Toolkit contains the Resource Compiler and Editor. These utilities, together with documentation, are available from your operating system supplier. The Resource Compiler converts items such as menu definitions, icon declarations and accelerator tables from ASCII text to a binary format that can be incorporated in an .exe or .dll module.
The OS/2 Programmer's Toolkit Editor enables you to paint dialog boxes, icons, and fonts.
Two sample programs included with this system provide examples of Presentation Manager programs written in COBOL. The programs are:
Copyright © 1999 MERANT International Limited. All rights reserved.
This document and the proprietary marks and names
used herein are protected by international law.
Windowing Support for Text-based Systems | Presentation Manager Applications (32-bit) |