Developing 16-bit Windows programs

Stony Brook Modula-2 allows you to take advantage of all of Windows capabilities,including:

Recommended Books

Windows is a large and complex programming environment consisting of hundredsof different functions.  This section deals with issues specific to developingWindows programs with Stony Brook Modula-2.  To learn to use the Windows programmingenvironment you will need to acquire a book on the subject. A good source of informationon this subject is:

Programming Windows, Version 3, by Charles Petzold, published by Microsoft Press

Building DLLs

The Windows API

Although using the runtime library to program for Windows is possible, you willnot be writing true Windows applications.  In order to develop applicationsthat provide your users with the menus, dialogs, windows and other graphical elementsthey will be expecting you will need to use the Windows Application Programming Interface(API).

Note: The Windows Null value is not the same as the Modula-2 NIL value. You must use Null from the Windows Definition file for the Windows API.

The Windows API is provided in definition modules in the runtime library.  Youcan call Windows API functions in the same way you call run time library functions.

Many of the API calls have been altered from their original C style to a stylethat is more natural for the Modula-2 programming language. The parameter that havebeen converted are pointer parameters. The Modula-2 langauge in many ways does notneed such parameters and Stony Brook Modula-2 takes this a bit further. The parametersare either value or VAR parameters depending on the function usage of the parameter.

String Parameters. LPSTR, LPCSTR, LPTSTR, LPCTSTR, LPWSTR, LPCWSTR are pointersto characters. In the Modula-2 API definitions these where converted to ARRAY OFCHAR parameters without the implicit high bound. However, the Win32 API restrictionthat strings be NULL terminated still applies, so take care that strings you passare indeed NULL terminated.

RECORD type parameters. Pointers to RECORD types have been converted to valueor VAR parameters. This can be done because our compiler always passes RECORD typesby reference, even for value parameters.

ARRAY type parameters. Pointers to ARRAY types have been converted to value orVAR parameters. This can be done because our compiler always passes ARRAY types byreference, even for value parameters.

Pointers to scalar types. In these cases the API call is doing exactly what theModula-2 VAR parameter accomplishes. The VAR parameter is a cleaner and type safemechanism.

Here is a list of the Windows API files provided and what they contain :

COMMDLG Common dialog procedures.
LZEXPAND Interface to file compression and expansion.
PRINT Interface to printing.
SHELLAPI Interface to the operating system user interface shell program(s)
STRESS An interface to the stress api to exercise memory management.
Windows All of the Windows API calls.
WINX This is a conversion of WindowsX.h. This provides some functions to encapsulate features that are non portable or not strongly typed. It provides strongly typed versions of some of the more loosely typed API calls.

WINX also contains some strongly typed constants, and some NIL variables for M2modified parameters such as RECORD and ARRAY OF parameters.  These NIL variablesexist because Windows often provides optional behaviors on API functions when a NILpointer is passed.  In Modula-2, since these have been mapped to structuresand arrays, a clean way was needed to access these optional behaviors.  Forexample, if you wanted to  call an API that required a NIL string be passedyou would call the function as:


Linker Definition Files

A default linker definition file is provided for Windows programs.  The fileis named DEFAULTW.EDF and is used if no other definition file is specified.  Alinker definition file is also provided for building Windows DLL's.  See TheLinker Reference

Windows is very sensitive to most of the options in these files and as such onlyadvanced users should modify them.

Exception Handlers on Exports

Procedures which are marked with the EXPORT attribute will automatically generatean exception handler if you do not supply one.  The exception handler will terminatethe program if it is activated.  This is to avoid the situation of an exceptionpropagating to other programs.  We strongly recommend that you provide an explicitexception handler on all exported procedures and handle any exceptions in a way thatbest suits your program (Returning an error code for example).

Exported procedures are actually generated as two separate procedures.  Theprocedure you write becomes a shell which is the actual exported procedure.  Thecode which is generated for the procedure is actually put into a special proceduregenerated by the compiler along with the exception handler.  This process isentirely automatic.

Important Variables

The information that Windows provides when an application is run is made availableby the following four variables which exist in WINX.  For information on theirusage please consult your Windows reference manuals.

Instance : HINSTANCE;

PrevInstance : HINSTANCE;

CmdShow : UINT;

CmdLine : LPSTR;

Name Clashes

Windows contains symbols that collide with Modula-2 pervasive symbols. The symbolsin the API files have been renamed as follows.

Smart CallBacks

The linker's Smart Callbacks option eliminates the need to call MakeProcInstanceinside your programs.  Note that Smart Callbacks cannot be used with DLLs.

Startup Code

The entry point for Windows programs is in a file called winstart.asm.  Theentry point procedure is Winstart which calls the BEGIN block in your program module. The public symbol given  to the BEGIN  block is WinMain.

A DLL's entry point is in a file called libentry.asm.  The entry point iscalled LibEntry.  LibEntry calls the DLL's main BEGIN block which is given thepublic symbol name LibMain.  DLLs also define a WEP(Windows Exit Procedure)in libentry.asm that calls the Modula-2 termination code.

All of the programs initialization code is called automatically.


Under Windows 95/98/Me, Windows 16-bit applications can not be debugged with theStony Brook Debugger.  This is due to operating system limitations.  Applicationscan be debugged when running under the Windows NT operating system.  If youmust debug 16-bit applications under Windows 9x, you can select the CodeView debugtype and use any CodeView 4.x debugger which works under Windows 9x.

Using Resources

Put the compiler resource directive intoyour program source. The environment uses this directive to track a dependency betweenthe source file with the directive and the resource file. The resource file willbe linked when the source file with the directive is a part of the program.