contents.gifindex.gifprev1.gifnext1.gif

M.2.6 Using the SDK

This section describes how to use ACUCOBOL-GT for Windows in conjunction with the Windows Software Development Kit (SDK).

You can use the SDK to build applications that make use of the full range of facilities available under Windows. For example, you can use the SDK to add dialog boxes to your application or to perform dynamic data exchange with another application. In order to use the SDK, you must have the following:

gt490000.gif Microsoft Visual C++ version 1.5 (to develop for Windows 3.1)

gt490000.gif Microsoft Visual C++ version 6.0 (to develop for Windows 95/98 and Windows NT)

You may also use other development tools that are compatible with these tools.

Generally speaking, you make use of the SDK by writing various C subroutines that call the SDK. You then build a new runtime that contains these C subroutines, and you make calls to these routines from your COBOL application. You can also use this procedure to call code produced by code generators.

The remainder of this section assumes you are familiar with C and the Windows SDK.

Building a new runtime

Appendix C in this manual covers the details of writing C subroutines and passing parameters between those routines and COBOL. You may use any of the interface methods described there to call your C routines.

After you've written your routines, you'll need to link them into the runtime system. This process builds a new "wrun16.exe" that contains your routines.

In order to build a new runtime, you must have Microsoft Visual C++ properly installed. The files that you need to rebuild the runtime can be found in the "library" subdirectory off the main ACUCOBOL-GT directory. Change to that directory and type:

NMAKE /F WRUN16.MAK

If everything is installed correctly, you should see the steps occurring as a new runtime system is built, and you should end up with a new "wrun16.exe" file.

Important tips before you rebuild the runtime

You may add your C routines directly to the "sub.c" or "mswinsub.c" files provided with ACUCOBOL-GT. More likely, you'll want to create your own files that hold your routines. If you do this, add the names of your files to the line labeled "SUBS=" in the "wrun16.mak" file. Note that you actually add the name of the corresponding ".obj" file, not the ".c" source file.

Note that ACUCOBOL-GT for Windows is a large-model program. This is unusual for Windows programs and may require some coding changes to programs designed for the small or medium models. Also, note that Windows will not run multiple instances of a program if it has more than one data segment. Because this is the default for large-model programs, you must declare all your global data as "_near" in order to produce a program with a single data segment. For example, consider the following variable declarations:

static int   i1, i2;
char         *ptr;

These will produce additional data segments in a large-model program. To prevent this, declare them as:

static int   _near i1, _near i2;
char         * _near ptr;

Note that the "_near" comes after the "*" in the second declaration: "_near *ptr" is a pointer to a near object, "* _near ptr" is a pointer to a far object where "ptr" is located in the near data segment. Only global data must be declared "_near"; data declared in a function does not need to be.

For additional information about the "_near" keyword, see the Microsoft C documentation.

The file "mswinsub.c" contains useful declarations that you may want to use in your C subroutines. In particular, you will find variables for the "task", "instance", and "main window" handles used by ACUCOBOL-GT. Also, you will find a start-up routine to which you can add your initialization code.

User interface approaches

You can use the SDK for many things that don't directly affect the user interface. For example, you can add dynamic data exchange with another application using the SDK. If you want to add user-interface code, however, then you must decide whether to build your user interface using a mix of COBOL and C, or whether to use C alone. This decision affects how your code will interact with the runtime system.

Using C only-no COBOL

If you build your interface entirely in C, then you have complete flexibility in how the interface will work. In this case, you will either want to run the runtime system with the "-b" command-line option, or set the configuration variable "NO-CONSOLE" to "1". When you do this, the runtime won't create its own application window. Instead, your C code must build its own window. When you take this approach, you may not use ACCEPT or DISPLAY verbs in your COBOL program (except for those that don't interact with the screen or keyboard). This approach also works well with a user interface created by a code-generating tool.

Using C and COBOL

If you want to use COBOL in conjunction with C, you must take care to cooperate with the runtime system in how the screen is displayed.

There are some cases in which you don't need to worry about the runtime system, because Windows will manage everything. Generally speaking, this occurs when your C code displays data in its own window. For example, you can display and accept data from a dialog box without interacting with the runtime system (all you need is the handle of the runtime's window, which you have in "mswinsub.c").

In other cases, you'll need to cooperate with the runtime's message handler. For example, if you want to display a graphical object in the main application window, you must monitor "paint" messages to the runtime system and draw your object when appropriate. The general technique for doing this is called "subclassing". When you subclass a window, you instruct Windows to pass all of its messages to your own message handler. Typically, your message handler acts on one or more messages and then passes all the messages to the original message handler. For detailed instructions on subclassing, see any Windows programming text. The following is an example of a typical case.

Suppose that you want to intercept messages to the runtime system and pass them to a routine called "MyMsgHandler". To do so, you would first declare "MyMsgHandler" as a function designed to be called from Windows:

LRESULT __export CALLBACK MyMsgHandler( HWND, UINT, WPARAM, LPARAM );

Next, in a separate C subroutine that you call after the COBOL program has created the main application window, you would get the address of the ACUCOBOL-GT message handler and then direct Windows to send messages to your handler instead. The code reads like this:

FARPROC lpfnMyMsgHandler, lpfnAcuWndProc;

lpfnMyMsgHandler = MakeProcInstance((FARPROC) MyMsgHandler, hAcuInstance );
lpfnAcuWndProc = (FARPROC) GetWindowLong( hAcuWnd, GWL_WNDPROC );
SetWindowLong( hAcuWnd, GWL_WNDPROC, (long) lpfnMyMsgHandler );

At this point, all messages that Windows would normally direct to the ACUCOBOL-GT main window procedure will instead be received by "MyMsgHandler".

Your message handler should intercept and act on the messages it cares about. At the end, it should then pass each message on to the original message handler and return the result. This is usually done with a line that reads like this:

return CallWindowProc( lpfnAcuWndProc, hWnd, iMsg, wParam, lParam );

For reference, ACUCOBOL-GT for Windows currently acts on the following messages:

WM_ACTIVATE

WM_ACTIVATEAPP

WM_CHAR

WM_CLOSE

WM_COMMAND

WM_CREATE

WM_CTLCOLOR

WM_CTLCOLORBTN

WM_CTLCOLOREDIT

WM_CTLCOLORLG

WM_CTLCOLORLISTBOX

WM_CTLCOLORMSGBOX

WM_CTLCOLORSCROLLBAR

WM_CTLCOLORSTATIC

WM_DESTROY

WM_DRAWITEM

WM_ENDSESSION

WM_ERASEBKGND

WM_GETMINMAXINFO

WM_HSCROLL

WM_INITMENU

WM_INITMENUPOPUP

WM_KEYDOWN

WM_KILLFOCUS

WM_LBUTTONDBLCLK

WM_LBUTTONDOWN

WM_LBUTTONUP

WM_MBUTTONDBLCLK

WM_MBUTTONDOWN

WM_MBUTTONUP

WM_MEASUREITEM

WM_MOUSEMOVE

WM_NCLBUTTONDBLCLK

WM_NCLBUTTONDOWN

WM_NCPAINT

WM_PAINT

WM_PALETTECHANGED

WM_QUERYDRAGICON

WM_QUERYENDSESSION

WM_QUERYNEWPALETTE

WM_RBUTTONDBLCLK

WM_RBUTTONDOWN

WM_RBUTTONUP

WM_SETCURSOR

WM_SETFOCUS

WM_SIZE

WM_SIZING

WM_SYSCHAR

WM_SYSCOLORCHANGED

WM_SYSCOMMAND

WM_TIMER

WM_VSCROLL

See the SDK documentation for details about these messages.