Every Windows application must have a module-definition file. This file defines the name, code and data segments, memory requirements, and exported functions of the application. For a simple application, like Generic, you need at least the NAME, STACKSIZE, HEAPSIZE, EXETYPE, and EXPORTS statements. However, most applications include a complete definition of the module, as shown in the following example:
;module-definition file for Generic -- used by LINK.EXE
NAME Generic ; application's module name
DESCRIPTION 'Sample Microsoft Windows 3.1 Application'
EXETYPE WINDOWS ; required for all Windows apps
STUB 'WINSTUB.EXE' ; generates error message if app
; is run without Windows
CODE MOVEABLE DISCARDABLE ; code can be moved in memory and
; discarded/reloaded
; DATA must be MULTIPLE if program can be invoked more than once.
DATA MOVEABLE MULTIPLE
HEAPSIZE 1024
STACKSIZE 5120 ; recommended minimum for Windows applications
; All functions that will be called by any Windows function
; MUST be exported.
EXPORTS
MainWndProc @1 ; name of window-processing procedure
About @2 ; name of About processing procedure
The semicolon is the delimiter for comments in the module-definition file.
The NAME statement, which is required, defines the name of the application. Windows uses this name (in the example, Generic) to identify the application.
The DESCRIPTION statement is optional. In the example, it places the message “Sample Microsoft Windows 3.1 Application” in the application's executable file. This statement is useful for adding version control or copyright information to the file.
The EXETYPE statement is used to mark the executable file as a Windows executable file. For a Windows application, the module-definition file must contain the statement EXETYPE WINDOWS.
The STUB statement specifies another optional file that defines the executable “stub” to be placed at the beginning of the file. When a user tries to run the application without Windows, the stub is run instead. Most Windows applications use the WINSTUB.EXE executable file supplied with the SDK. WINSTUB.EXE displays a warning message and terminates the application if the user attempts to run the application without Windows. You can also supply your own executable stub.
The CODE statement defines the memory attributes of the application's code segment. In this example, the code segment contains the executable code that is generated when the GENERIC.C file is compiled. Generic is a small-model application with only one code segment, which is defined as MOVEABLE DISCARDABLE. If the application is not running and Windows requires additional space in memory, Windows can move the code segment to make room for other segments and can, if necessary, discard the segment. A discarded code segment is automatically reloaded on demand by Windows.
The DATA statement defines the memory requirements of the application's data segment. In this example, the data segment contains storage space for all the static variables declared in the GENERIC.C file. It also contains space for the program stack and local heap. The data segment, like the code segment, is defined as MOVEABLE. In addition, the MULTIPLE keyword directs Windows to create a new data segment for the application each time the user starts a new instance of the application. Although all instances share the same code segment, each has its own data segment. An application must have the MULTIPLE keyword if the user can run more than one copy of it at a time.
The HEAPSIZE statement defines the size, in bytes, of the application's local heap. Generic uses its heap to allocate a temporary structure used to register the window class, so it specifies 1024 bytes of storage. Applications that frequently use the local heap should specify larger amounts of memory.
The STACKSIZE statement defines the size, in bytes, of the application's stack. The stack is used for temporary storage of function arguments. Any application that calls its own local function must have a stack. Generic specifies 5120 bytes of stack storage, the recommended minimum for a Windows application.
The EXPORTS statement defines the names and ordinal values of the functions to be exported by the application. Generic exports its window procedure, MainWndProc, which has an ordinal value of 1 (this is an identifier; it could be any integer, but usually such values are assigned sequentially as the exports are listed). You must export all functions that Windows is to call (except WinMain). These functions, referred to as callback functions, include the following:
All window procedures
All dialog box procedures
Special callback functions, such as enumeration functions, that certain Windows API functions require
Any other function that is to be called from outside your application
For more information about callback functions, see Chapter 14, “C and Assembly Language.”
For more information about module-definition statements, see the Microsoft Windows Programmer's Reference, Volume 4.