3.2.2 Strict Type-Checking

The Windows 3.1 header file (WINDOWS.H) includes various features for detecting problems when compiling an application. These features, which are provided by the STRICT option, make application development faster and easier.

You define STRICT before the include statement for the header file. STRICT causes the various types and function prototypes in WINDOWS.H to be declared with very strict type-checking. For example, once STRICT is defined, it is impossible to pass a window handle to a function that requires a device-context handle without generating a compiler error.

3.2.2.1 Features of the STRICT Option

Specific features provided by the STRICT option include:

Strict handle type-checking

Proper declaration of certain parameter and return value types

Fully prototyped type definitions for callback function types

Proper declaration of polymorphic parameters and return values (for example, wParam and lParam message parameters)

Proper use of the const keyword for pointer parameters and structure members when the pointer is read-only

Type declarations for many of the Windows functions and callback functions have changed. Nonetheless, unless you define STRICT, the new declarations for Windows 3.1 are fully compatible with the old declarations for Windows 3.0. WINDOWS.H for Windows 3.1 can, therefore, be used to compile Windows 3.0 applications without modifications.

3.2.2.2 Compiling with the STRICT Option

In general, the STRICT option is most useful with newly developed code or with code that is being maintained or changed regularly. Code that has already been written and tested, and is not changing very much over time, will generally not benefit as much from STRICT. If you find that stable code generates lots of run-time parameter validation errors when run with Windows 3.1, you will find STRICT very valuable as you go through the code to clean up those errors.

The following procedures will ensure that your application conforms to STRICT type-checking:

Use new handle and parameter types. In particular, replace HANDLE with appropriate handle types and use WPARAM and LPARAM with all message parameters.

Use new return type and parameter types for windows and dialog box procedures and callback functions.

Declare all your functions with full prototypes. Place these prototypes in a include file and include it with each source file.

Cast function pointers to the proper type rather than to FARPROC type. This is especially important with the MakeProcInstance function.

Take special care with HMODULE and HINSTANCE types. There are a few Windows functions that return or accept only HMODULE types.

Use the MAKELPARAM macro instead of the MAKELONG macro when building LPARAM parameters out of two words. Also, use the MAKELRESULT macro instead of MAKELONG when building LRESULT return values.

Cast the handle or near pointer to a WORD type in order to prevent getting the data segment value in the high word of the value when casting a handle or near pointer value to LRESULT or LPARAM.

Cast a far pointer, LPARAM or LRESULT, to a DWORD type and then to the desired type when you cast the far pointer to a handle or near pointer. This prevents “segment lost in conversion” warnings.

Make sure you have the following lines, in the given order, in each source file:

#define STRICT
#include <windows.h>

Compile your source to use the highest level of error checking. Treat any warnings as errors and correct your sources to eliminate the warning messages.

Link and run the application to ensure that it executes without errors.