PreviousPresentation Manager Applications (32-bit) Microsoft Windows NT ApplicationsNext"

Chapter 16: Microsoft Windows Applications

This chapter explains how to use the 16-bit COBOL system to create 16-bit applications for running on Microsoft Windows. These applications will run in any 16-bit or 32-bit Windows environments, which are:

These 16-bit and 32-bit environments are referred to as Windows throughout this chapter.

16.1 Overview

There are five ways of creating 16-bit applications that can run under Windows:

16.2 Requirements

To develop Windows applications, you need the following:

16.2.1 Restrictions

The following restrictions apply when you use COBOL to create Windows applications:

16.3 Developing Character-based COBOL Applications

Any DOS application can be run in a DOS session under Windows. However, Windows applications are native to Windows and can be run directly from an icon. They use the Windows Application Programmer's Interface (API) to manage all the operating system requests. In particular they use the Windows memory management , enabling large applications to run. You can add Windows API calls to your application if it is a Windows application, enabling you to use the facilities of Windows.

Most existing applications that run under DOS and use the static linked run-time system can be relinked with different libraries to run under Windows in their own window, known as a COBOL Text Window . The library files lcoboldw.lib or coblibw.lib, supplied with this system, when linked with the application instead of cobapi.lib, perform the following functions:

The following rules apply when linking with lcoboldw.lib:

16.3.1 Compiling, Linking and Debugging

The following sections describe how to compile, link and debug your existing character-based applications to run as Windows applications.

16.3.1.1 Compiling the Application

No special directives are needed when compiling applications for running under Windows. (Except you might want to use the TARGET"286" and DEFFILETYPE"win" directives.)

Applications to be run under Windows can be compiled under DOS or OS/2 in the normal way, or compiled under Windows using cobolw.exe .

16.3.1.2 Linking the Application

The Linker can be invoked in two ways, either by using the cob command or by using the Linker directly. To link the application with lcobol.lib using the cob command, enter:

cob -x:wl app-obj-files

To link the application with coblib.lib using the cob command, enter:

cob -x:wc app-obj-files

To link the character-based application using the Linker command line, enter:

link app-obj-files+cblwina,,,
        lcoboldw+lcobol+cobw,app-def-file /nod/noe;

where the parameters are:

app-obj-files The .obj files that make up the application, including any COBOL system files such as adis.obj and extfh.obj.
cblwina The Windows startup .obj file, included with this COBOL system.
lcoboldw.lib, lcobol.lib and cobw.lib
or
coblibw.lib, coblib.lib and cobw.lib
Library files supplied with this COBOL system.
app-def-file The name of the .def file containing the following lines:

exetype   windows 3.1
protmode
code preload moveable
   discardable
data preload moveable multiple
stacksize stacksize
heapsize  heapsize

See your Windows documentation to work out values for stacksize and heapsize. Example values are 16384 for stacksize and 1024 for heapsize.

If you use Windows API calls available only in Windows V3.1, you should also use cobw31.lib instead of cobw.lib.

You must always use a .def file when linking Windows applications. The Compiler can create a .def file for you if you use the DEFFILE, DEFFILETYPE"win" and NODLL directives when you compile your program. Alternatively, the file dwskel.def supplied with this system is a file that you can adapt to create your own .def files.

Since the link marks the .exe file as a Windows application, you do not need to run the Resource Compiler (rc.exe, supplied with the Windows SDK) unless you want to create your own icon for your application. Providing your own icon is described later in this chapter.

If your application contains dynamically linked subprograms, you should link these into Windows .dll files. See the section Creating Dynamic Link Libraries later in this chapter. Use the method described there for creating Windows .dll files, but use the library lcoboldw.lib instead of lcobolw.lib.

For static linked run-time system applications, if your application uses floating-point support, the object and library files for linking are different. Instead of cblwina.obj use cblwinaf.obj . You also need to link with cobfp87w.lib. See your Object COBOL User Guide for more details.

Example

To compile and link the sample program Tictac to run under Windows with the static linked run-time system, enter:

cob -x:lw tictac

or enter

cobol tictac;
link tictac+adis+adiskey+adisinit+cblwina,,,
    lcoboldw+lcobol+cobw,dwskel.def/noe/nod;

The resulting program can be run just like any other Windows application. For example:

win tictac

For COBOL Windows programs to run, the files cblsseg.dll and cblwin.dll , supplied with this COBOL system, must exist either in the application's directory, in the main Windows directory or in a directory on the PATH. The application does not run if cblsseg.dll and cblwin.dll cannot be found at run time.

16.3.1.3 Debugging the Application

If your application does not make use of the Windows API, you can use Animator to debug your application. Under Windows, invoke Animator using animatew.exe. Either use the command in a program icon in a program group, or run the command from the Run option in the File menu in Program Manager.

16.3.2 Customizing Your Application's Icon

By default, the icon used when you minimize the application's window is a simple square. You can create your own icon for your application. To do this you should create an icon of the same name as the application and use the Resource Compiler to attach it to the application after it has been linked. See the Microsoft Windows SDK documentation for more details about creating icons and about the Resource Compiler.

Example

If you have created your own icon for Tictac and saved it in a file called tictac.ico, do the following to attach it to tictac.exe :

  1. Create the file tictac.rc containing the line:
    tictac icon tictac.ico

  2. Create tictac.res by running the Resource Compiler as follows:
    rc -r tictac.rc

  3. Assuming you have compiled and linked tictac.exe as described previously, now attach tictac.res to tictac.exe using the command:
    rc tictac.res

Now, when you minimize the window containing Tictac, the icon you have created is used.

16.3.2.1 Setting the Application Title

By default, the title of a character-based COBOL application under Windows is the root of the executable-name. However, you can set the title for your application without changing your application source code.

After you link your application, specify a string resource with an ID of 100 and use the Resource Compiler to attach it to the application. The ID of the resource must be 100 to be picked up by the default window code. See the Microsoft Windows SDK documentation for more details about creating resources and the Resource Compiler.

Example

To create a custom title for Tictac:

  1. Create the file tictac.rc containing the required title:
    STRINGTABLE LOADONCALL DISCARDABLE
    BEGIN
        100 "This is a COBOL sample program"
    END

  2. Create tictac.res by running the Resource Compiler:
    rc -r tictac.rc

  3. Compile and link tictac.exe as described above.

  4. Attach tictac.res to tictac.exe using the command:
    rc tictac.res

Now, when you run the application, the window has your specified title.

16.3.2.2 Starting an Application Maximized

By default, a Windows application starts with the window in its normal state. You can make it start minimized by setting the appropriate option on the Program Manager Item Properties. However, the Program Manager under Windows does not provide an option to start an application maximized.

The COBOL Text Window provides additional support to enable a character-based Windows application to start maximized. To do this, you must create an RCDATA resource file that contains:

Example

To show Tictac maximized:

  1. Create the file tictac.rc containing:
    #include <windows.h>
    TICTAC-SHOW RCDATA LOADONCALL DISCARDABLE
    BEGIN
        SW_SHOWMAXIMIZED
    END

  2. Create tictac.res by running the Resource Compiler:
    rc -r tictac.rc

  3. Compile and link tictac.exe as described above.

  4. Attach tictac.res to tictac.exe using the command:
    rc tictac.res

Now, when you run the application it appears maximized.

16.3.3 Configuration Options

You can configure various options for the application by creating an initialization file in the Windows directory or by putting options for the application in the Windows initialization file, win.ini. In the initialization file, you create an entry for a program by adding the name of the program, surrounded by square brackets, followed by the configuration options on separate lines.

The following options can be configured:

Example

To configure Tictac to use the standard Windows colors and for all of the system function keys to be passed through to Tictac, the following entry would be needed in a tictac.ini file, or in the win.ini :

[TICTAC]
COBVIOMODE=WINDOWS
COBSYSTEMKEYS=APPLICATION
COBVIOOPT=OFF

16.3.3.1 Screen Emulation Mode

By default, the window created by lcoboldw.lib emulates a color screen. However, two other types of screen can be emulated by setting the value of COBVIOMODE using the line:

COBVIOMODE=parameter

The possible values of parameter are:

COLOR The default. The windows emulate a standard color screen. All color attributes are supported. Unless an attribute is specified, text is displayed white on black.
MONO The window emulates a monochrome screen. By default, text is displayed as white on a black background. The only attributes supported are underline, bold, reverse-video and blink.
WINDOWS This supports the same attributes as mono above, but the default Windows colors are used instead. This means that, by default, text is displayed as black on a white background. If the user changes the default colors using the Windows Control Panel, the application's window is updated accordingly.

If the application does not display any information, the COBOL Text Window is not displayed. It does not appear in the Windows Task List or display a termination message.

16.3.3.2 System Function Key Control

By default, certain function keys are not passed through to an application by Windows. Instead, they perform system functions. Examples of such keys are F10 and all Alt key combinations, such as Alt+F4. Because some COBOL programs might have been written to make use of these keys, a configuration option is provided to enable these keys to be passed through to the application instead of being processed by Windows.

This is controlled by setting COBSYSTEMKEYS using the line:

COBSYSTEMKEYS=parameter

The possible values of parameter are:

WINDOWS The default. The system keys are processed by Windows and perform their standard Windows functions (for example, Alt+F4 closes the window).
APPLICATION All system keys are passed through to the application; they do not perform their standard Windows functions. Even if this option is chosen, the user can still access the Windows system menu from the keyboard by pressing Alt+Space.

16.3.3.3 Screen Output Optimization Control

By default, code is active to ensure that screen output is optimized. This might cause problems if the application does not regularly perform screen I/O, in which case the optimization can be turned off.

This is controlled by setting COBVIOOPT using the line:

COBVIOOPT=parameter

The possible values of parameter are:

ON The default. Screen output optimization code is active.
OFF Optimizations are disabled. The window is updated each time screen I/O takes place.

16.3.3.4 Using the Blink Attribute

Windows does not provide direct support for the blink attribute. Instead, when you set the bit associated with the blink attribute, the background color appears with high intensity. You can override this behavior in character-based applications via an entry in the initialization file for the application. To enable support for blink, add the following entry:

COBBLINK=ON

Example

To enable the blink attribute for Tictac, create a tictac.ini file or a section of win.ini that contains the following:

[TICTAC]
COBBLINK=ON

16.3.3.5 Setting the Window Size

The default size for a text window is 25 lines by 80 columns. This can be overridden using the C4 and C5 run-time switches or by setting the size using the following options.

Set the width to integer columns (maximum 132) by giving the entry:

COBCOLS=integer

Set the height to integer lines (maximum 50) by giving the entry:

COBLINES=integer

16.3.4 Controlling Your Application's Window

The COBOL Text Window created by the run-time system for your character-based application has additional features on its system menu (accessed by choosing the box to the left of the window's caption or by pressing Alt+Space):

Menu Option
Action
Edit Displays a submenu containing the commands Mark, Copy, Copy Tabs, Paste and Scroll.
Mark Once Mark has been chosen, your user can mark an area in the window for copying to the Windows clipboard.

To mark using the mouse, the user moves the mouse cursor to the point at which to start marking and then holds down the left mouse button while moving the mouse to mark the area. Releasing the left mouse button stops the marking.

To mark using the keyboard, the user moves the caret to the start point using the cursor keys, then holds down the Shift key while continuing to move the caret to mark the area. Releasing the Shift key stops the marking.

Mark mode can be canceled by choosing Mark again, by pressing Escape or by performing Copy or Copy Tabs.

Copy Copies the marked area to the Windows clipboard and turns off Mark mode. The text is copied to the clipboard using the OEM System font. This preserves any specific graphics characters during the copy.
Copy Tabs Behaves like Copy, but spaces are replaced by tab characters. This is useful when copying columns of figures into the clipboard to be pasted into applications such as Microsoft Excel which uses the tab character as a column separator when pasting from the clipboard.
Paste Becomes enabled whenever the Windows clipboard contains text. If chosen, the contents of the clipboard are copied into the clipboard in the form of keystrokes. This means that the effect is the same as if your user had typed the information at the keyboard.
Scroll Causes the cursor keys to scroll the window instead of being passed through to the application. This enables your user to scroll the window, even if there is no mouse. Choosing Scroll again turns off this option.

A user with a mouse can scroll the window using the scroll bars as for any other Windows application.

Fonts Displays a dialog box enabling you to chose the font to be used in the default window.
Default Font Resets the font used in the default window to the system default font.
Settings Displays a dialog box that enables you to chose which of the current settings on the default window are saved when the application terminates.
Terminate Terminates the application.

16.3.5 Terminating the Application

An application can be terminated before it finishes, by choosing Close on the system menu.

When an application terminates normally, that is, by executing a STOP RUN, a message box is displayed stating that the application has terminated. The window for the application is not closed until your user pushes the OK button on the message box. This lets the user view the final results of the application before the window is closed.

16.3.6 Library Routines for Windows Applications

A set of COBOL system library routines provide additional functionality to COBOL applications under Windows. These routines are summarised here, and described in detail in the section Windows Library Routines at the end of this chapter.

Printer Handling routines:

There are also printer routines available that are portable between the 32-bit COBOL systems on Windows and OS/2. These routines are prefixed with PC_PRINT, and are described in the Library Routines chapter of the Programming Guide to Writing Programs.

Example

The following code specifies an About box containing the lines:

            This is an information box
                for this application
 01  AboutString pic x(48) value "This is an information box" &
                                x"0D0A" & "for this application".
    . . .
    call "PC_WIN_ABOUT"
                   using by reference AboutString
                         by value     48 size 2

16.4 Developing COBOL Applications That Call Windows Functions

This section describes briefly how to create COBOL applications that use the functions of Windows for screen and keyboard I/O, instead of using COBOL syntax. The information here describes how to compile, link and debug COBOL Windows programs.

The Microsoft Windows Software Development Kit manuals give full details of the programming interface to Windows. See the later section Translating C Definitions for details of how to convert C definitions of functions into COBOL syntax.

A number of sample Windows programs are supplied with this COBOL system. These are described later.

16.4.1 Using the Systems Programming Extensions

The Systems Programming Extensions in this COBOL system make all the features of Windows available to the COBOL programmer. Please refer to the chapter Presentation Manager Applications (16-bit) for more details.

16.4.2 Calling Conventions

The Windows 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. Windows 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 Windows API routines do this work themselves. You must therefore define the appropriate convention and specify it when calling Windows 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 Windows 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 winapi
     call-convention 3  is winapiold.
        . . .
     call winapi "LoadIcon" using ...
        . . .
     call winapiold "_ _LoadIcon" using ...

If the COBOL program is to be called by a Windows API routine, you need to specify the calling convention in the PROCEDURE DIVISION header:

 procedure division winapi.

16.4.3 The Windows Startup Module

Every Windows program must startup correctly, so that Windows can handle the program correctly and so that your program can obtain the four startup values needed for some of the calls. There are three methods for starting provided with this COBOL system:

See the manual Guide To Programming in the Microsoft Windows SDK documentation for further details of the startup values. You should not use lpszCmdLine to access the command line if you use lcoboldw.lib or coblibw.lib. Instead, use the COBOL syntax ACCEPT FROM COMMAND-LINE.

16.4.3.1 Using cblwgui.cbl with lcoboldw.lib and coblibw.lib

Calling the routine PC_WIN_STARTUP (in the module cblwgui.cbl) to startup a Windows GUI application causes Windows to call the program (and so start it) at entry point WinMain with the startup values passed as parameters:

 local-storage section. 
 linkage section. 
 01  hInst               pic xx   comp-5. 
 01  hPrevInstance       pic xx   comp-5. 
 01  lpszCmdLine         pic x(128) value spaces. 
 01  nCmdShow            pic xx   comp-5. 
 procedure division winapi. 
 MSWindowsInit section. 
      call "PC_WIN_STARTUP". 
      stop run. 
 entry winapi "WinMain" using hInst, 
                              hPrevInstance, 
                              lpszCmdLine, 
                              nCmdShow. 

 MyWinMain section. 
     if hPrevInstance = 0 
          ...

With this method you must link in the module cblwgui.obj. This is supplied as cblwgui.cbl to enable you to animate through it. You must compile it yourself to create cblwgui.obj.

For example to link Wincalc (using this startup method) with the shared run-time system:

cobol cblwgui omf(obj) ans85; 
cobol wincalc omf(obj) ans85; 
link wincalc+cblwgui+cblwina, wincalc.exe,wincalc, 
        coblibw+coblib+cobw,wincalc.def /noe/nod; 
rc wincalc.res

16.4.3.2 Using lcobolw.lib

When using the static linked run-time system lcobolw.lib for graphical applications, four Windows parameters are passed to the main entry point at startup. These can be declared as in the following example:

 linkage section.
 01 hInst               pic xx comp-5.
 01 hPrevInstance       pic xx comp-5.
 01 lpszCmdLine         pic x(120).
 01 nCmdShow            pic xx comp-5.
 procedure division winapi using by value     hInst
                                 by value     hPrevInstance
                                 by reference lpszCmdLine
                                 by value     nCmdShow.

The parameter lpzCmdLine contains the command line that was used to start the application. The window itself has no command line and so the ACCEPT FROM COMMAND-LINE statement should not be used.

16.4.3.3 Using PC_WIN_INIT

This method calls the routine PC_WIN_INIT to get the four Windows startup values.

For example:

 01  hInst               pic xx   comp-5. 
 01  hPrevInstance       pic xx   comp-5. 
 01  lpszCmdLine         pointer. 
 01  nCmdShow            pic xx   comp-5. 
       ...
     call "PC_WIN_INIT" using    hInst, 
                                 hPrevInstance, 
                                 lpszCmdLine, 
                                 nCmdShow

16.4.4 Translating C Definitions

The Windows Programmer's Reference, Volume 2: Functions describes all the Windows 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 Windows Software Development Kit includes definitions of many of the Windows function parameters in a C header (.h) file. 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.

16.4.4.1 H2cpy-to-C Header File Conversion

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 Windows Software Development Kit into COBOL type definitions and COBOL CALL prototypes. It is especially useful if you want to write Windows applications in COBOL using the System Programming Extensions.

Before you can compile any of the sample programs (or your own Windows software), you must first run H2cpy to translate the C header files into COBOL, using a command line such as:

h2cpy windows.h 

This translates the windows.h file into the COBOL copyfile windows.cpy. You can use the COPY statement to include this file in your program. The Compiler then validates any function calls that you make to ensure that the parameters conform to the COBOL CALL prototype in windows.cpy. H2cpy automatically generates useful CALL prototypes from the C function prototypes. However, you might find the validation inappropriate in some cases. You have the choice of either modifying windows.cpy or of running H2cpy with the option to suppress the generation of CALL prototypes.

16.4.4.2 Translating C Function Declarations

The C definition of the CreateWindow API function is shown in the following example; the rest of this section explains how to translate this C definition into COBOL.

HWND CreateWindow
                  (LPCSTR    lpszClassName,
                   LPCSTR    lpszWindowName,
                   DWORD     dwStyle,
                   int       x,
                   int       y,
                   int       nWidth,
                   int       nHeight,
                   HWND      hwndParent,
                   HMENU     hmenu,
                   HINSTANCE hinst,
                   void FAR* lpvParam);

The following list defines each of the words in the example:

Word
Meaning
HWND Function returns data of type HWND
CreateWindow Function-name
LPCSTR The data-type of the parameter lpszClassName
lpszClassName Possible name for the parameter (optional in the definition, but needed in any use of the function)
LPCSTR The data-type of the parameter lpszWindowName
lpszWindowName Possible name for the parameter
. . . Remaining data types and names until ...
void Describes the following data-type FAR* as an untyped pointer.
FAR* The data-type of the parameter lpvParam which is a pointer of type FAR
lpvParam Possible name for the parameter
); End of the function definition

All Windows API function definitions appear in the Windows header file. The names used for the parameters are not significant and can 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 can be shown in the COBOL prototype.

The first thing you need to determine is the calling convention needed by the CreateWindow routine. Look this routine name up in windows.cpy and you find a CALL prototype definition such as:

 entry "CreateWindow" using
               by reference  any
               by reference  any
               by value      uns-long
               by value      int
               by value      int
               by value      int
               by value      int
               by value      uns-int
               by value      uns-int
               by value      uns-int
               by value      data-pointer
           returning         uns-int

The parameters are specified in terms of COBOL type definitions, for example uns-long and int, that are defined at the beginning of the windows.cpy file. The parameter any signifies that any data-type can be used. All COBOL CALL statements referencing CreateWindow must use parameters that conform with the corresponding data-type otherwise the compiler gives 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 is more portable between different Windows API environments.

The calling convention that the routine CreateWindow needs is given in the Special-Names paragraph of the program in which it is defined. Look in windows.cpy for the program-id preceding the call prototype and you 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 CreateWindow must be called with a calling convention of 3. This means that you must define a calling convention for calls to the Windows API routines. To combine the Pascal call-convention with the static link call convention, add the following line to the Special-Names paragraph:

     call-convention 11 is winapi

Returning to the C definition of CreateWindow example above, the first data-type you need to translate is HWND. Since CreateWindow returns a value of type HWND, you need to define a storage location for that value, say hwndResult. Looking up HWND in the file windows.cpy, you find this definition:

 01  HWND  is typedef  usage uns-int.

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 uns-int, which is defined at the beginning of the windows.cpy file as:

 77  uns-int  pic  9(4)  comp-5 is typedef.

The data types HWND and uns-int are, therefore, both equivalent to the COBOL type, PIC 9(4) COMP-5 and they can all be used interchangeably. The COBOL CALL prototype found earlier indicates that the routine returns a value of type uns-int and so you can define hwndResult in

terms of HWND. However, as a COBOL programmer you might find the definition more convenient with the equivalent line:

 01  hwndResult  usage uns-int.

Next consider the parameters to the function call. The first parameter has type LPCSTR, which is described in windows.cpy as:

 01  LPCSTR  is typedef  usage data-pointer.

The CALL prototype says that the first and second 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 allowing type checking. It is otherwise equivalent to passing a parameter as an untyped pointer BY VALUE.

The C header file declares the parameter lpszClassName as a char pointer. In C, a char pointer references a char data-type 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 lpszClassName 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 in 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 lpszClassName and lpszWindowName as:

 01  szClassName       pic x(9)  value "My-Class"  & x"00".
 01  szWindowName      pic x(10) value "My-Window" & 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  szClassName       pic x(9)  value "My-Class"  & c-null.
 01  szWindowName      pic x(10) value "My-Window" & c-null.

The third parameter is data type DWORD. From windows.cpy you get:

 01  DWORD  is typedef  usage uns-long.

The CALL prototype says that the third parameter must be passed BY VALUE and have a type uns-long and so you can write the line:

 01  dwStyle  usage uns-long.

Next is data type int. From windows.cpy you get:

 77  int  pic s9(4)  comp-5 is typedef.

The CALL prototype says that the fourth parameter must have a type int and so, making the name more meaningful, you can write the line:

 01  x-Position  usage int.

After defining the complete list of parameters, you end up with the following source lines:

 copy "windows.cpy" replacing ==call-convention 3==
                    by        ==call-convention 11==.
 program-id. windemo.
 special-names.
     call-convention 11 is winapi.
 working-storage section.
 78  c-null            value x"00".
 01  hwndResult        usage uns-int.
 01  szClassName       pic x(9)  value "My-Class"  & c-null.
 01  szWindowName      pic x(10) value "My-Window" & c-null.
 01  dwStyle           usage uns-long.
 01  x-Position        usage int.
 01  y-Position        usage int.
 01  nWidth            usage int.
 01  nHeight           usage int.
 01  hwndParent        usage uns-int.
 01  hmenu-cbl         usage uns-int.
 01  hinst             usage uns-int.
 01  lpvParam          usage data-pointer.


Note: The standard naming convention used in the C header files uses a type-name prefixed by the letters P to indicate a near pointer and LP to indicate a far pointer to that type. For example, PBYTE and LPBYTE indicates a near and far pointer respectively to a variable of type BYTE . The parameter names in the API definitions follow a similar convention.

The name hmenu is already used for a data-type so we have to choose another, unique name for this parameter.


After you have performed all these conversions, the COBOL call to the API function CreateWindow becomes:

         call winapi "CreateWindow" using
                         by reference "My-Class"  & c-null
                         by reference "My-Window" & c-null
                         by value     dwStyle
                         by value     x-Position
                         by value     y-Position
                         by value     nWidth
                         by value     nHeight
                         by value     hwndParent
                         by value     hmenu-cbl
                         by value     hinst
                         by value     lpvParam
                   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 y-Position and nHeight are both 0, you can replace the parameters by literals. Alphanumeric literals can also be specified, as given in the following call:

         call winapi "CreateWindow" using
                         by reference szClassName
                         by reference szWindowName
                         by value     dwStyle
                         by value     x-Position
                         by value     0             size 2
                         by value     nWidth
                         by value     0             size 2
                         by value     hwndParent
                         by value     hmenu-cbl
                         by value     hinst
                         by value     lpvParam
                   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 WS_VISIBLE is defined in the C header files and generates a COBOL statement in windows.cpy:

 78  WS-VISIBLE        value h"10000000".

Where the C header file specifies a constant that involves more than a simple expression, H2cpy cannot generate any equivalent COBOL statement and you might need to specify it yourself. For example, the constants CW_USEDEFAULT and HWND_DESKTOP are such constants which you can specify as:

 78  CW-USEDEFAULT     value h"8000".
 78  HWND-DESKTOP      value 0.


Note: C uses the underscore (_) to split long names or prefixes. The underscore cannot be used in COBOL, so H2cpy replaces all underscores in names with hyphens (-) .


If you use these literal values as parameters then you can specify:

         call winapi "CreateWindow" using
                         by reference szClassName
                         by reference szWindowName
                         by value     WS-VISIBLE    size 4
                         by value     CW-USEDEFAULT size 2
                         by value     0             size 2
                         by value     CW-USEDEFAULT size 2
                         by value     0             size 2
                         by value     HWND-DESKTOP  size 2
                         by value     hmenu-cbl
                         by value     hinst
                         by value     lpvParam
                   returning hwndResult

16.4.5 Linking and Debugging

Graphical Windows applications can be compiled in the usual way. See the section Compiling the Application earlier in this chapter for more details. The following sections describe how to link and debug graphical applications to run as Windows applications.

16.4.5.1 Linking Graphical COBOL Applications

This section describes how to link your application if it has a graphical user interface using the Windows API. See the section Linking Character-based COBOL Applications earlier in this chapter if it has a character-based user interface.

All Windows programs must contain a startup function as the main entry point to the program. The module cblwina.obj supplied with this COBOL system contains the startup function and must, therefore, be linked with every COBOL Windows program.

When you link a program to run as a Windows application you must always include a .def file containing the line:

exetype          windows 3.1

If you do not include this line, the resulting .exe file is not able to run under Windows. You must also include an EXPORTS statement to publicize the window procedure start address to the operating system, as in the example below.

Windows applications must be linked with cobw.lib rather than cobapi.lib. The latter supports only calls to the DOS operating system.

If the application includes icons, dialog boxes or other resources, the Resource Compiler must be used to add the compiled resource to the linked executable. Details are given in the Windows Software Development Kit.

Link the application with the static linked run-time system as follows:

link app-obj-files+cblwina,,,
        lcobolw+lcobol+cobw,app-def-file /nod/noe;

Link the application with the shared run-time system as follows:

link app-obj-files[+cblwgui]+cblwina,,,
        coblibw+coblib+cobw,app-def-file /nod/noe;

If your application uses floating-point support, the object and library files for linking are different. Instead of cblwina.obj use cblwinaf.obj . You also need to link with cobfp87w.lib. See your Object COBOL User Guide for more details.

Example

To compile and link the Winhello sample program:

cobol winhello.cbl;
link winhello+cblwina,,,
        lcobolw+lcobol+cobw,winhello.def /nod/noe;

where winhello.def contains the lines:

description       "Welcome to COBOL and Windows."
exetype           windows 3.0
code              preload moveable discardable
data              preload moveable multiple
stacksize         16384
heapsize          1024
exports           mywndproc @1

16.4.5.2 Linking Large Applications

Under Windows V3.0 a COBOL application containing a Data Division larger than 64K must include the following additional line in the .def file:

apploader         '_ _MSLANGLOAD'

This is not needed for Windows V3.1 or later.

16.4.5.3 Creating Dynamic Link Libraries

For a full description of the concepts of dynamic link libraries (.dll files) in Windows see the Windows Software Development Kit documentation.

All Windows .dll files must contain a LibMain function, and a termination function called WEP which must be exported in the .def file for the .dll. The module cblwinl.obj supplied with this COBOL system contains the LibMain and WEP entries and must be linked with every COBOL Windows dynamic link library. The libinit.obj module supplied with this COBOL system must also be linked.

A COBOL Windows .dll is not normally shareable; it cannot be used at the same time by two applications. It can, however, be made reusable so each application that uses it loads a fresh copy. See the section Creating Reusable .exe and .dll Files.

Linking the object modules to form a dynamic link library is similar to linking to form an .exe file.

Example

Consider the following COBOL program, windll.cbl:

 procedure division using Return-String.
     move "Inside windll" to Return-String
     exit program.

 entry "windll2" using Return-String.
     move "Inside windll2" to Return-String
     exit program.

Typically, you can compile and link this program to produce windll.dll, callable by other Windows programs by either entering:

cobol windll.cbl;
cob -x:wdl windll

or entering:

cobol windll.cbl;
link windll+cblwinl+libinit,windll.dll,,
    lcobolw+lcobol+cobw,windll.def /nod/noe;

where windll.def contains the lines:

library              windll
description          "a cobol dll for windows."
exetype              windows 3.0
code                 preload fixed discardable
data                 preload fixed single
heapsize             1024
exports              windll  @1
                     windll2 @2
                     wep     @3 residentname

This .def file can be created by the Compiler if you use the DEFFILE and DEFFILETYPE"win" directives when you compile the program.

16.4.5.4 Using Dynamic Link Libraries

There are two basic methods of calling .dll functions in Windows:

16.4.5.5 Statically Linked Calls

If you use statically linked calls to a .dll file, you must do one of the following:

Example

Consider the following main program, winexe.cbl:

 special-names.
      call-convention 8 is static
 procedure division.
     call static "windll"
     call static "windll2".

The double underscore prefix ( _ _ ) can be used instead of call-convention 8 to force static linking.

Using the first method, the following lines would need to be added to the module definition file for Winexe:

imports
    windll.windll
    windll.windll2

Using the second method, you could create an imports library for Windll, using the Implib utility as follows:

implib windll.lib windll.def

Then, when you link winexe, you specify the library windll.lib on the link command line.

16.4.5.6 Dynamically Linked Routines

If you use dynamic calls, you do not need to supply any information to the Linker. At run time, the run-time system module that handles dynamic calls first searches through loaded executable files to see if the required subprogram is already loaded. If it isn't, the disk is searched for an executable file whose filename matches the subprogram-name.

Therefore, if you use dynamic linking, the first call you make to the .dll file must use the name of the .dll file. For example:

procedure division.
     call "windll"
     call "windll2".

16.4.5.7 Windows Mixed-language Programming

For details of mixed-language support, see your Programmer's Guide to Writing Programs.

16.4.5.8 Debugging

An application that makes use of the Windows API cannot be debugged using Animator or Animator V2. However, it can be debugged using Xilerator or CodeView. Xilerator gives more functionality when debugging COBOL code but CodeView also enables you to debug non-COBOL modules at source level.

16.4.5.8.1 Debugging with Xilerator

Xilerator, is a character COBOL debugger that is similar to Animator but debugs programs that have been generated to Intel 8086 machine code (.gnt or .obj programs). Xilerator appears in a window but, because it uses "hard mode" debugging, while your program is stopped in Xilerator you cannot select any other window.

16.4.5.8.2 Debugging with CodeView

CodeView for Windows is included with the Microsoft Windows V3 SDK. In general, CodeView supports the language with which it is supplied, both at source and machine-code level, and can be used effectively for mixed language applications. You can use CodeView with COBOL code at source and machine-code level, but since CodeView does not support COBOL data types, COBOL data is shown in hexadecimal form only.

CodeView 4.0 or 4.1 as supplied with Microsoft C/C++, V7.0 does not have a COBOL expression evaluator.

The program should be compiled using the EANIM"1" directive. The /CO directive should be specified when the program is linked.

Example

cobol winexe eanim"1";
link winexe+cblwina,,,lcobolw+lcobol+cobw,
        winexe.def /co /nod /noe;

If you are debugging a character application, link with lcoboldw.lib or coblibw.lib instead of lcobolw.lib.

The source of the program is not displayed when CodeView starts up. You should set a breakpoint at the name of the main program, execute up to that point (using the G or F5 command) and then step through the program until the source is displayed.

16.4.6 Tools

Tools available to the Windows programmer include:

The Resource Compiler converts objects such as menu definitions, icon declarations and accelerator tables from readable ASCII to a binary format which can be incorporated in an .exe or .dll module.

The editors enable you to paint dialog boxes, icons, cursors, bitmaps and fonts.

16.4.7 Hints and Tips

16.5 Creating Reusable .exe and .dll Files

Because COBOL programs under Windows are always large model, they cannot be used by two applications at the same time. Trying to start a COBOL .exe file when it is already running either gives an error or simply switches to the existing copy. Trying to run two programs that both use the same COBOL .dll file gives an unrecoverable application error.

However, both .exe and .dll files can be made reusable, so that a fresh copy is loaded for each task that uses it. This means that, if two tasks are using the same .exe or .dll file, twice as much memory is being taken up. This contrasts with normal sharable Windows .exe and .dll files, that share their code segments and only duplicate the single data segment.

To make an .exe file reusable, link in the mfreusex.obj module. For example, the link command (in the section Linking the Application) becomes:

link app-obj-files cblwina+mfreusex,,,
    lcoboldw+lcobol+cobw,app-def-file /nod/noe;

The resulting .exe file must have at least one non-accented alphabetic character in its name.

To make a .dll file reusable, link in the mfreused.obj module. For example, the link command (in the section Creating Dynamic Link Libraries) becomes:

link windll+cblwinl+libinit+mfreused,windll.dll,,
    lcobolw+lcobol+cobw,windll.def';

The resulting .dll file imports a function from mfreuse.dll. Thus, mfreuse.dll must be present when your .dll file is used. You can use coblibw or lcobolw in place of lcoboldw in the two examples above.

16.6 Sample Programs

There are four sample programs included with this system which illustrate Windows programming from COBOL. You can use these programs as examples of how to create Windows applications in COBOL.

Program
Description
Compress A COBOL application that simply reads and writes a file, and does not make use of the graphical user interface, but which runs under the control of Windows.
Sysmets A COBOL application that illustrates the system metrics. It shows the use, from COBOL, of a number of Windows features, including scroll bars.
Winhello A skeleton Windows program that shows the creation of a window class with window procedure. The window procedure simply puts some text in the window. This program is well commented with respect to the COBOL language enhancements used to facilitate Windows programming. Winhello can be used as the basis for most Windows applications.
Wincalc A COBOL application for Windows that implements a simple Reverse Polish Notation calculator with base conversions.

Wincalc demonstrates the use from COBOL of many Windows features:

- Standard window with a client window procedure
- Action bar and pull-down menus
- Accelerator keys
- Sending and receiving messages
- Child windows
- Subclassing
- WindowWords
- Area sensitive pointer (changes shape when on apressable button)
- Dialog boxes
- Message boxes
- Automatic window repositioning/resizing

16.7 Windows Library Routines

The following COBOL system library routines are available for use in creating Windows applications. They are portable between 16-bit COBOL systems on Windows and 32-bit COBOL systems on Windows NT and Windows 95.

General routines:

PC_WIN_ABOUT Add a Windows "About" box
PC_WIN_HANDLE Obtain handle of window used for screen I/O
PC_WIN_INIT Obtain startup values
PC_WIN_YIELD Process outstanding Windows messages

Windows printer handling routines:

PC_WIN_CLOSE_PRINTER Close a printer channel
PC_WIN_FREE_PBMP Free bitmap from memory
PC_WIN_LOAD_PBMP Load bitmap into memory
PC_WIN_OPEN_PRINTER Open a printer channel
PC_WIN_OPEN_PRINTER_EXT Extended open a printer channel
PC_WIN_PRINT_FILE Print a file
PC_WIN_PRINT_FILE_EXT Extended print a file
PC_WIN_PRINTER_CONTROL Send a printer control
PC_WIN_PRINTER_INFO Get printer information
PC_WIN_SET_PCOLOR Set printer color
PC_WIN_SET_PDEFAULT Set or reset default printer
PC_WIN_SET_PDEF_FONT Set default printer font
PC_WIN_SET_PFONT Set printer font
PC_WIN_WRITE_PBMP Write bitmap to a printer
PC_WIN_WRITE_PRINTER Write to a printer

There are also printer routines available that are portable between the 32-bit COBOL systems on Windows and OS/2. These routines are prefixed with PC_PRINT, and are described in the Library Routines chapter of the Programmer's Guide to Writing Programs.

The Windows-specific routines are described in the section Descriptions of Routines, below.

16.7.1 Introduction to Windows Printer Handling Routines

To use the Windows printer handling routines with .int and .gnt code files created using the 16-bit COBOL system, you must load the file mfprnt16.dll before calling any of the routines. You can do this by using the following code in your program:

     working-storage section. 
     01 mfprn-ptr  procedure-pointer. 
     procedure division. 
         set mfprn-ptr to entry "mfprnt16".

16.7.2 Description of Routines


PC_WIN_ABOUT

Provides an "About" box for a Windows application.

Syntax:
call "PC_WIN_ABOUT" using     text-string 
                    by value  text-length 
                    returning status-code
Parameters:

text-string         pic x(n)
text-length         pic x(2) comp-5.
status-code         See Key in the Preface
On Entry:

text-string The text to be placed in the "About" box. To split the text over a number of lines, include carriage return/line feed (x"0D0A") sequences in the text.
text-length The length of the text in text-string

On Exit:

None

Comments:

This routine is available only in the Windows environment.

This routine adds the item "About..." to the bottom of the system menu for the application. When your user selects this item, an information box is displayed. This box contains the name of the application, together with the text supplied to this routine.


PC_WIN_CLOSE_PRINTER

Closes a printer channel.

Syntax:
call "PC_WIN_CLOSE_PRINTER" using     printer-handle 
                            returning status-code
Parameters:

printer-handle      pic x(2) comp-5.
status-code         See Key in the Preface
On Entry:

printer-handle The handle of the printer returned when the printer was opened.

On Exit:

status-code Printer status code:

0 Successful
3 Printer device not open
4 Out of memory while printing
6 Disk full while spooling file
7 Print job aborted. No file spooled to Print Manager.
11 Write failure

Comments:

This routine is available only in the Windows environment.

You must open the printer before using this routine.


PC_WIN_FREE_PBMP

Frees a bitmap from memory, releasing its image and palette back to the operating system.

Syntax:
call "PC_WIN_FREE_PBMP" using     printer-handle 
                     by reference bmp-id 
                        returning status-code
Parameters:

printer-handle      pic x(2) comp-5.
bmp-id              pic x(2) comp-5.
status-code         See Key in the Preface
On Entry:

printer-handle The handle of the printer, returned when the printer was opened.
bmp-id The unique id of the loaded bitmap, returned when the bitmap was loaded.

On Exit:

status-code Printer status code:

0 Successful
3 Printer device not open
20 Failed to free bitmap

Comments:

This routine is available only in the Windows environment.

Example:
     call "PC_WIN_FREE_PBMP" using printer-handle, 
                      by reference bmp-idlogo, 
                         returning printer-retcode 
     end-call
See also:

PC_WIN_LOAD_PBMP
PC_WIN_WRITE_PBMP


PC_WIN_HANDLE

Returns the handle of the window used for screen I/O.

Syntax:
call "PC_WIN_HANDLE" using     hwnd 
                     returning status-code
Parameters:

hwnd (Windows 3) pic x(2) comp-5.
hwnd (Windows NT) pic x(4) comp-5.
status-code See Key in the Preface
On Entry:

None

On Exit:

hwnd Contains the window handle

Comments:

This routine is available only in the Windows environment.


PC_WIN_INIT

Returns the Windows startup values.

Syntax:
call "PC_WIN_INIT" using     hInst                     
         hPrevInstance                               lpszCmdLine                
              nCmdShow 
                   returning status-code
Parameters:

hInst               pic x(handle-size) comp-5.
hPrevInstance       pic x(handle-size) comp-5.
lpszCmdLine         pointer.
nCmdShow            pic x(handle-size) comp-5.
status-code         See Key in the Preface
On Entry:

None

On Exit:

hInst The handle of this instance.
hPrevInstance The handle of the previous instance.
lpszCmdLine A pointer to the command line. Not for COBOL use.
nCmdShow Flags to indicate the attributes attached to any windows created.

Comments:

This routine is available only in Windows environments including Windows NT.

handle-size has the values:

16-bit COBOL system 2
32-bit COBOL system 4

When starting a Windows application Windows returns four start-up values. These are required when calling a number of the Windows API routines. When using the shared run-time system, it is necessary to call this routine to get the start-up values so you can then use the Windows API.

You should not access the command line using the parameter passed here. Use ACCEPT ... FROM COMMAND-LINE instead.


PC_WIN_LOAD_PBMP

Loads a bitmap into memory ready for the PC_WIN_WRITE_PBMP function.

Syntax:
call "PC_WIN_LOAD_PBMP" using     printer-handle 
                     by reference bmpfilename 
                     by reference bmp-id 
                        returning status-code
Parameters:

printer-handle      pic x(2) comp-5.
bmpfilename         pic x(n).
bmp-id              pic x(2) comp-5.
status-code         See Key in the Preface
On Entry:

printer-handle The handle of the printer, returned when the printer was opened.
bmpfilename A null-terminated string containing the name of a Windows bitmap file.

On Exit:

bmp-id A unique id for the loaded bitmap.
status-code Printer status code:

0 Successful
3 Printer device not open
18 Failed to load bitmap
19 Invalid bitmap id given

Comments:

This routine is available only in the Windows environment.

Example:
     call "PC_WIN_LOAD_PBMP" using printer-handle 
                by reference "c:windowswinlogo.bmp" & x"00" 
                by reference bmp-id 
                   returning printer-retcode 
     end-call
See also:

PC_WIN_FREE_PBMP
PC_WIN_WRITE_PBMP


PC_WIN_OPEN_PRINTER

Opens a printer channel.

Syntax:
call "PC_WIN_OPEN_PRINTER" using     printer-handle 
                           returning status-code
Parameters:

printer-handle      pic x(2) comp-5.
status-code         See Key in the Preface
On Entry:

None

On Exit:

printer-handle The handle of the printer.
status-code Printer status code:

0 Successful
1 Could not open printer device
5 Failed to open file
9 No default printer found. Select a printer from Windows Control Panel.
24 User pressed Cancel on the printer setup dialog or the font selection dialog.

Comments:

This routine is available only in the Windows environment.


PC_WIN_OPEN_PRINTER_EXT

Opens a printer channel, giving it a document name and displaying the printer-options dialog box.

Syntax:
call "PC_WIN_OPEN_PRINTER_EXT" using   printer-handle       
                                 doc-name 
                              by value options size 2 
                             returning status-code
Parameters:

printer-handle      pic x(2) comp-5.
doc-name            pic x(m).
options             numeric literal.
status-code         See Key in the Preface
On Entry:

doc-name The document name to be displayed. The name must be null-terminated.
options A set of bits to set printer options:

bit 3 Print in landscape orientation
bit 2 Print in portrait orientation
bit 1 Display a font dialog box, so you can select the default font for the document
bit 0 Display a printer control dialog box, so you can set up the printer

Bits 2 and 3 cannot be used with bit 0 set.

On Exit:

printer-handle The handle of the printer.
status-code Printer status code:

0 Successful
1 Could not open printer device
9 No default printer found. Select a printer from Windows Control Panel.
10 No commdlg.dll found
24 User pressed Cancel on the printer setup dialog or the font selection dialog.

Comments:

This routine is available only in the Windows environment.


PC_WIN_PRINT_FILE

Sends the specified file to the printer.

Syntax:
call "PC_WIN_PRINT_FILE" using     filename 
                         returning status-code
Parameters:

filename            pic x(n).
status-code         See Key in the Preface
On Entry:

filename The name of the file to be printed. The name must be space- or null-terminated.

On Exit:

status-code Printer status code:

0 Successful
1 Could not open printer device
3 Printer device not open
4 Out of memory while printing
5 Failed to open file
6 Disk full while spooling file
7 Print job aborted. No file spooled to Print Manager
9 No default printer found. Select a printer from Windows Control Panel.
11 Write failure

Comments:

This routine is available only in the Windows environment.

Example:

To print out the file c:autoexec.bat:

     call "PC_WIN_PRINT_FILE" 
               using by reference "c:autoexec.bat" & x"00"


PC_WIN_PRINT_FILE_EXT

Sends the specified file to the printer, giving it a document name and displaying the printer-options dialog box.

Syntax:
call "PC_WIN_PRINT_FILE_EXT" using     filename             
                           doc-name 
                              by value options size 2 
                             returning status-code
Parameters:

filename            pic x(n).
doc-name            pic x(m).
options             numeric literal.
status-code         See Key in the Preface
On Entry:

filename The name of the file to be printed. The name must be space- or null-terminated.
doc-name The document name to be displayed. The name must be null-terminated.
options A set of bits to set printer options:

bit 3 Print in landscape orientation
bit 2 Print in portrait orientation
bit 1 Display a font dialog box, so you can select the default font for the document
bit 0 Display a printer control dialog box, so you can set up the printer

Bits 2 and 3 cannot be used with bit 0 set.

On Exit:

status-code Printer status code:

0 Successful
1 Could not open printer device
4 Out of memory while printing
5 Failed to open file
6 Disk full while spooling file
7 Print job aborted, no file spooled to Print Manager
8 Printer information structure badly constructed
9 No default printer found. Select a printer from Windows Control Panel.
10 No commdlg.dll found. Should be in Windows system directory.
11 Write failure

Comments:

This routine is available only in the Windows environment.

Example:

To print out the file c:config.sys in landscape:

     call "PC_WIN_PRINT_FILE_EXT" 
               using by reference "c:config.sys" & x"00" 
                     by reference "My Config.sys" & x"00" 
                     by value 8 size 2


PC_WIN_PRINTER_CONTROL

Sends a print command to a printer.

Syntax:
call "PC_WIN_PRINTER_CONTROL" using    printer-handle 
                        by value print-command size 2 
                             returning status-code
Parameters:

printer-handle      pic x(2) comp-5.
print-command       numeric literal.
status-code         See Key in the Preface
On Entry:

printer-handle The handle of the printer returned when the printer was opened.
print-command The command to send to the printer:

1 Abort printing of the document and close the printer
2 Throw a page
3 Flush the print buffers

On Exit:

status-code Printer status code:

0 Successful
2 Bad printer control code given
3 Printer device not open
4 Out of memory while printing
6 Disk full while spooling file
7 Print job aborted, no file spooled to Print Manager
11 Write failure

Comments:

This routine is available only in the Windows environment.

You must open the printer before using this routine.


PC_WIN_PRINTER_INFO

Returns a Windows device handle (HDC) and other information that can be used to enhance the printing of a document by calling Windows API directly

Syntax:
call "PC_WIN_PRINTER_INFO" using  printer-handle            
                       printer-info-struct 
                        returning status-code
Parameters:

printer-handle          pic x(2) comp-5.
printer-info-struct     Group item containing:
    pi-struct-size          pic x(2) comp-5.
    win-printer-hdc         pic 9(handle-size) comp-5 value 0.
    printer-orientation     pic xx comp-5 value 0.
    printer-char-info.      Group item containing:
        printer-rows            pic xx comp-5 value 0.
        printer-cols            pic xx comp-5 value 0.
        printer-rows-left       pic xx comp-5 value 0.  printer-graphics-info.     Group item containing:
        printer-max-horz        pic S9(handle-size) comp-5.
        printer-max-vert        pic S9(handle-size) comp-5.
        printer-curX            pic S9(handle-size) comp-5.
        printer-curY            pic S9(handle-size) comp-5.
status-code                 See Key in the Preface
On Entry:

printer-handle The handle of the printer returned when the printer was opened.
pi-struct-size The size of the structure.

On Exit:

win-printer-hdc Windows device handle.
printer-orientation Orientation of the printout:

1 Portrait
2 Landscape
printer-rows Total number of rows on the current page, in the current font
printer-cols Average number of columns in the current font (in a monospaced font this is the exact number)
printer-rows-left Number of rows left on the current page, in the current font
printer-max-horz Maximum value of graphics co-ordinate available in the horizontal axis
printer-max-vert Maximum value of graphics co-ordinate available in the vertical axis
printer-curX X coordinate, in graphics co-ordinates
printer-curY Y coordinate, in graphics co-ordinates
status-code Printer status code:

0 Successful
3 Printer device not open
4 Out of memory while printing
7 Print job aborted, no file spooled to Print Manager
8 Printer information structure badly constructed

Comments:

This routine is available only in the Windows environment.

You must open the printer before using this routine.

handle-size has the values:

16-bit COBOL system 4
32-bit COBOL system 8

For portability between 16-bit and 32-bit systems, you can set handle-size using a 78-level item. For example, with the 32-bit system:

 78 handle-size          value 8.
Example:

To draw an ellipse in a document:

     move printer-struct-size to pi-strct-size 
     call "PC_WIN_PRINTER_INFO" using 
                                 by reference printer-handle, 
                                 by reference printer-info-strct 
     call WINAPI "Ellipse" using by value windows-printer-Hdc 
                                 by value box-topX 
                                 by value box-topY 
                                 by value box-botX 
                                 by value box-botY


PC_WIN_SET_PCOLOR

Sets the color on the printer.

Syntax:
call "PC_WIN_SET_PCOLOR" using     printer-handle 
                          by value fore-or-back 
                          by value color-red 
                          by value color-green 
                          by value color-blue 
                         returning status-code
Parameters:

printer-handle      pic x(2) comp-5.
fore-or-back        pic x comp-5.
color-red           pic x(2) comp-5.
color-green         pic x(2) comp-5.
color-blue          pic x(2) comp-5.
status-code         See Key in the Preface
On Entry:

printer-handle The handle of the printer, returned when the printer was opened.
fore-or-back Whether to set foreground or background:

1 foreground
2 background
color-red Value between 0 and 255; intensity of red
color-green Value between 0 and 255; intensity of green
color-blue Value between 0 and 255; intensity of blue

On Exit:

status-code No status codes are returned by this routine.

Comments:

This routine is available only in the Windows environment.

You must open the printer before using this routine.

You specify the color you want by combinations of values showing the intensity of the three primary colors. For example, to get the colors in the following table, you set the RGB values as shown:

Color           Red     Green   Blue 
-----           ---     -----   ---- 
Red             255     0       0 
Yellow          255     255     0 
Green           0       255     0 
Cyan            0       255     255 
Blue            0       255     255 
Magenta         255     0       255 
White           255     255     255 
Black           0       0       0

Some other, more unusual, colors are:

Dark orange     255     140     0 
Navy blue       0       0       128 
Violet          238     120     238 
Beige           245     245     220

If your printer does not support color, it is up to the printer device driver to interpret these values. For example, some perform gray-shading; others choose either black or white for each color.


PC_WIN_SET_PDEFAULT

Set the default printer for all PC_WIN printer routines.

Syntax:
call "PC_WIN_SET_PDEFAULT" using     deflt-printer 
                           returning status-code
Parameters:

deflt-printer       pic x(n).
status-code         See Key in the Preface
On Entry:

deflt-printer A null-terminated string specifying the default printer. If no name is specified (that is, the first character of the string is null) then the default printer is reset.

On Exit:

status-code Printer status code:

0 Successful
17 Failed to find default printer

Comments:

This routine is available only in the Windows environment.

Example:
     call "PC_WIN_SET_PDEFAULT" using "Local PostScript Printer" 
                                      & x"00" 
                            returning printer-retcode 
     end-call


PC_WIN_SET_PDEF_FONT

Sets the font globally before the printer is opened. You can select a different font for a printer using the PC_WIN_PRINT_FILE_EXT function.

Syntax:
call "PC_WIN_SET_PDEF_FONT" using     FontFamilyName 
                            by value  FontSize
                            returning status-code
Parameters:

FontFamilyName      pic x(n). (zero terminated string)
FontSize            Numeric literal or pic x(2) comp-5.
status-code         See Key in the Preface
On Entry:

FontFamilyName The family name of the font to be used, such as Courier, Times, Symbol.
FontSize Point size of the font

On Exit:

None

Comments:

This routine is available only in the Windows environment.

You must open the printer before using this routine.

Example:

To select the font Courier New with point size 8 as the default printer font:

   call "PC_WIN_SET_PDEF_FONT" 
                 using by reference z"Courier New" 
                       by value 8 size 2 
                    returning Printer-Status-Code 
           end-call
   call "PC_WIN_PRINT_FILE_EXT" 
                 using by reference z"c:\config.sys" 
                       by reference z"My CONFIG.SYS" 
                       by value 0 size 2 
           end-call


PC_WIN_SET_PFONT

Sets the font on the printer.

Syntax:
call "PC_WIN_SET_PFONT" using     printer-handle            
                       FontTypeFace
                         by value FontSize
                         by value FontStyle 
                        returning status-code
Parameters:

printer-handle      pic x(2) comp-5.
FontTypeFace        pic x(n).
FontSize            pic x(2) comp-5.
FontStyle           pic x(2) comp-5.
status-code         See Key in the Preface
On Entry:

printer-handle The handle of the printer, returned when the printer was opened.
FontTypeFace Name of the font, for example: Times New Roman. Must be null-terminated. You can select any TrueType font and any font installed on the printer.
FontSize Point size of the font
FontStyle Set of bits showing the style of the font:

bit 3 Bold
bit 2 Strikeout
bit 1 Underline
bit 0 Italic

On Exit:

status-key Printer status code:

0 Successful
3 Printer device not open
4 Out of memory while printing
5 Disk full while spooling file
7 Print job aborted, no file spooled to Print Manager
12 No fonts found usable with this printer
13 The font requested does not exist

Comments:

This routine is available only in the Windows environment.

You must open the printer before using this routine.

Example:

To select the font Courier New with pointsize 8 in bold italic:

     call "PC_WIN_SET_PFONT" 
               using by reference printer-handle 
                     by reference "Courier New" & x"00" 
                     by value 8 size 2 
                     by value 9 size 2


PC_WIN_WRITE_PBMP

Write a loaded bitmap to a printer at a specified position with a given size.

Syntax:
call "PC_WIN_WRITE_PBMP" using     printer-handle 
                      by reference bmp-id 
                          by value bmp-row 
                          by value bmp-col 
                          by value bmp-width 
                          by value bmp-height 
                         returning status-code
Parameters:

printer-handle      pic x(2) comp-5.
bmp-id              pic x(2) comp-5.
bmp-row             pic x(2) comp-5.
bmp-col             pic x(2) comp-5.
bmp-width           pic x(2) comp-5.
bmp-height          pic x(2) comp-5.
status-code         See Key in the Preface
On Entry:

printer-handle The handle of the printer, returned when the printer was opened.
bmp-id The unique identifier of the bitmap to print.
bmp-row, bmp-col The position to print the bitmap.
bmp-width, bmp-height The size of the bitmap to print.

On Exit:

status-code Printer status code:

0 Successful
3 Printer device not open
4 Out of memory while printing
5 Disk full while spooling file
7 Print job aborted, no file spooled to Print Manager
11 Write failure
21 Failed to print bitmap

Comments:

This routine is available only in the Windows environment.

This routine works with PostScript and HP PCL printers. It is not supported on HP Deskjet or dot matrix printers.

Example:
     call "PC_WIN_WRITE_PBMP" using printer-handle 
                              by reference bmp-id-logo 
                                 by value  7 size 2 
                                 by value  5 size 2 
                                 by value 25 size 2 
                                 by value 15 size 2 
                              returning printer-retcode 
     end-call
See also:

PC_WIN_FREE_PBMP
PC_WIN_LOAD_PBMP


PC_WIN_WRITE_PRINTER

Writes a record to the printer.

Syntax:
call "PC_WIN_WRITE_PRINTER" using    printer-handle         
                             print-buffer 
                     by value print-buffer-len size 2 
                            returning status-code
Parameters:

printer-handle      pic x(2) comp-5.
print-buffer        pic x(n).
print-buffer-len    numeric literal.

status-code         See Key in the Preface
On Entry:

printer-handle The handle of the printer returned when the printer was opened.
printer-buffer The record to be sent to the printer.
printer-buffer-len The length of the record to be sent to the printer.

On Exit:

status-code Printer status code:

0 Successful
2 Bad printer control code given
3 Printer device not open
4 Out of memory while printing
5 Disk full while spooling file
7 Print job aborted, no file spooled to Print Manager
11 Write failure

Comments:

This routine is available only in the Windows environment.

You must open the printer before using this routine.

Example:
     call "PC_WIN_WRITE_PRINTER" 
               using by reference printer-handle 
                     by reference "Hello World" 
                     by value 11 size 2.


PC_WIN_YIELD

Processes all outstanding Windows messages that have been sent to an application that is running but does not yield to Windows.

Syntax:
call "PC_WIN_YIELD"
Parameters:

None

Comments:

This routine is available only in the Windows environment.

This routine is useful in a COBOL program that is linked with lcoboldw and does a lot of in-memory processing.



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

PreviousPresentation Manager Applications (32-bit) Microsoft Windows NT ApplicationsNext"