        Header File Organization
        ------------------------

This document describes the rules for public Windows 3.1 header files.  These
rules are designed to promote consistency, clarity, Win32 compatibility, ANSI
compatibility, motherhood, and apple pie a la mode.

In the past, windows.h has been fairly randomly organized: it wasn't very
easy to look in the file and figure out how constants, types, and functions
are related.  However, the new windows.h is much more rationally organized,
and it's now far easier to understand and modify.  In interests of
consistency, readability, and maintainability, it's important that all of our
public header files are consistently organized.

    *  Include a copyright banner at the top of the file.  Something like:

/*****************************************************************************\
*                                                                             *
* header.h -    Brief description of purpose of header file                   *
*                                                                             *
*               Version 3.10                                                  *                   *
*                                                                             *
*               Copyright (c) 1992, Microsoft Corp.  All rights reserved.     *
*                                                                             *
\*****************************************************************************/

       If this header file has been released before, the copyright date
       should be something like: 1985-1992.

    *  Arrange your header in functional groups, like windows.h.  Try to
       keep related types, structures, constants and functions as close
       together as possible in the header.  Separate functional groups
       within the header with a banner comment, as in windows.h.

    *  Within a functional group, general typedefs and constants should come
       first, followed by logically organized function prototypes.

    *  Constants or types used by only one or two functions should be
       declared near the function.

    *  Make sure that everything defined in the header file is included by
       default: don't require people to #define things to get certain
       definitions.

    *  If you do want to break up your header file, use the #define NOXXX
       convention used by windows.h.  Try not to have too many groups
       controled by NOXXX #defines, because they get confusing and hard to
       deal with.  Compiler speed and memory capacity is not the problem it
       once was, especially with precompiled headers.

    *  Constants designed to be ANDed or ORed should be defined in hex.
       The number of digits should reflect the data size: 2 for bytes,
       4 for words, and 8 for longs.  Long hex constants should have
       an appended L, e.g., 0x12345678L.

    *  Ordinal constants values (e.g., 1, 2, 3, 4) should be declared
       in decimal.

    *  Provide a comment on all #else's and #endif's that suggests its
       corresponding #ifdef: e.g.

            #ifdef FOO
            ...
            #else   /* FOO */

            #endif  /* !FOO */

    *  Precede the header file with #pragma pack(1), and terminate with
       #pragma pack().  This ensures that the structures declared in the
       header will be packed properly, regardless of what compiler packing
       options the user is using for his own code.  Because the Windows RC
       compiler chokes on #pragma statements in .rc files, it's a good idea
       to include this (and any other #pragmas) in an #ifndef RC_INVOKED.

            #ifndef RC_INVOKED
            #pragma pack(1)         /* Assume byte packing throughout */
            #endif  /* RC_INVOKED */

       and:

            #ifndef RC_INVOKED
            #pragma pack()          /* Revert to default packing */
            #endif  /* RC_INVOKED */

    *  Prevent multiple inclusion of your header file with the following
       construct:

            #ifndef _INC_MYHEADER
            #define _INC_MYHEADER

            ...body of header...

            #endif  /* _INC_MYHEADER */

       This is the convention used by the C runtimes.  For each header there
       is a #define that can be used to determine whether the header has
       already been included.



        Win32 Upward Compatibility
        --------------------------

Part of the goal of 3.1 is to provide a more unified API that will scale with
minimal pain to 32 bits in Win32.  To this end, there are a few things you
have to worry about in your headers (and in your code, but that's a different
story...)

In 32-bit Windows, almost all 16 bit parameters, return values, and field
types have been widened to 32 bits.  This allows us to generate much more
efficient code on the 386 and on RISC machines.

We need a way of declaring the quantities that will "float" to 32 bits in
32-bit Windows.  It turns out that the C language already provides for this
capability: the "int" type, for example, is 16 bits on 16 bit platforms, but
is 32 bits on 32 bit platforms.  "short" is always 16 bits on any platform,
"long" is always 32 bits, and "char" is always 8 bits.

So, functions and structures with "int" declarations are already portably
declared.  The problem, though is with the WORD type.  "WORD" has become an
industry-wide synonym for a 16 bit unsigned quantity.  But, it's also used
widely in Windows header files.

Enter the UINT type.  The new UINT type is typedef'd as "unsigned int": an
unsigned value that is 16 bits on 16 bit platforms, and floats to 32 bits on
32 bit platforms.  In the 3.1 headers, UINT is used in place of WORD wherever
the size of the return value, parameter, or field will change depending on
the platform.

This is a rule that applies to code you write too: on 32 bit platforms, use
of the UINT type rather than WORD will generate faster smaller code.  But be
careful of hard-coded size dependencies on WORD: be sure to use sizeof()
instead of constants, etc.

In some cases there may be structure fields whose size WON'T be changing in
32-bit windows, perhaps because the structure is used in a file format and
compatibility is required.  If you know ahead of time that this is the case,
be sure to use short and WORD to indicate 16 bit quantities across platforms.
There are a few of these exceptions with the 3.1 bitmap information
structures in windows.h.  If you don't know, then use UINT and int.

The new WPARAM, LPARAM, and LRESULT types, used for polymorphic or arbitrary
parameters and return values (e.g., the SendMessage() function), also provide
a useful degree of platform isolation.  The WPARAM type is similar to UINT in
that its size varies with the platform.  WPARAM should be used in function
parameter, return value, AND structure declarations, even though its size may
vary.  The use of these types indicates to the programmer that the value must
be cast and assigned to the proper type before use.

Hence, the following rules:

    *  Use int and UINT instead of short or WORD, UNLESS you know for sure
       that the quantity will remain 16 bits in 32-bit Windows.  The Windows
       HIWORD and LOWORD macros use WORD, for example.  Be sure to check your
       uses of short as well as WORD: there are probably a few lurking out
       there that should be changed to int.  Use int FAR* or UINT FAR* instead
       of LPINT or LPWORD.

    *  Use the LPARAM, WPARAM, and LRESULT types instead of WORD, LONG, or
       DWORD as appropriate.


        ANSI Compatibility
        ------------------

Public header files should be ANSI compliant so that people can take
advantage of the highest compiler warning levels possible.  This also helps
ensure that our header files work with a wider range of development tools.

    *  Don't define constants, typedefs, or functions named with a preceding
       underscore.  This violates the ANSI namespace conventions.  There are
       a few violations of this rule already in existence (e.g., _lread), but
       try not to create any new problems.  (The rules are actually more
       complicated than "don't use underscores", but you're safe if you keep
       away from them).

    *  Don't use "//" style comments in the header: these are convenient
       but non-ANSI, and warning level 4 complains.

    *  Always test your header file by compiling it with the -W4 compiler
       option to ensure that it's ANSI-compatible.

    *  Make sure that you have no identifier conflicts with the following
       C library header files (NOTE: This list may be incomplete.  It's
       a good start, though).

            assert.h
            ctype.h
            errno.h
            float.h
            limits.h
            locale.h
            math.h
            setjmp.h
            signal.h
            stdarg.h
            stddef.h
            stdio.h
            stdlib.h
            string.h
            time.h

    *  Structure declarations should be declared with the "tag" prefix, rather
       than a leading underscore, as shown below:

         typedef struct tagFOO
         {
            int i;
            UINT u;
         } FOO;

    *  Declare fully-prototyped typedefs for all callback functions.  By
       convention, the type name should be all caps and end in PROC. For
       example, the window procedure callback function typedef from windows.h:

        typedef LRESULT (CALLBACK* WNDPROC)(HWND, UINT, WPARAM, LPARAM);

        Windows 3.0 Backward Compatibility
        ----------------------------------

In order to allow users to develop applications with 3.1 headers that will
still run on 3.0, users can #define the WINVER constant to be equal to the
version number of Windows they are compiling against.  For 3.0, this would be
0x0300.  This constant should be used to ensure that new, non-3.0 compatible
features are not declared when the user is compiling a 3.0 application.  Keep
in mind that this version number is hex, not decimal (to be compatible with
the GetExpWinVer() API).

Some of you may own headers that are designed to work with windows 3.0 as
well as 3.1: in this case, you won't have some of the new 3.1 typedefs and
macros defined (e.g., UINT).  You can use #ifdef _INC_WINDOWS to determine
whether you've included the 3.1 windows.h.  Because yours may not be the only
header that will want to define certain types like UINT and LPCSTR, you
should #define these to be WORD and LPSTR, respectively, since you cannot
typedef something twice.  The other option, of course, is to have separate
3.0 and 3.1 versions of your header.

    *  New, non-3.0 compatible declarations and definitions should be inside
       #ifdef (WINVER >= 0x030a)/#endif so that the 3.1 headers can be used
       to create 3.0-compatible applications.

    *  If your header must be compatible with the 3.0 windows.h, use #ifdef
       _INC_WINDOWS around #definitions that define the missing types.  The
       3.0 windows.h file did not #define _INC_WINDOWS.
       Use #define rather than typedef to ensure that other headers can
       safely do the same thing.  Here's an example that will handle
       most of the common problems:

        #ifndef _INC_WINDOWS    /* If not included with 3.1 headers... */
        #define LPCSTR      LPSTR
        #define WINAPI      FAR PASCAL
        #define CALLBACK    FAR PASCAL
        #define UINT        WORD
        #define LPARAM      LONG
        #define WPARAM      WORD
        #define LRESULT     LONG
        #define HMODULE     HANDLE
        #define HINSTANCE   HANDLE
        #define HLOCAL      HANDLE
        #define HGLOBAL     HANDLE
        #endif  /* _INC_WINDOWS */

        C++ Compatibility
        -----------------

To be able to use functions declared in your header directly from C++, you
need to do one thing:

    *  Bracket the header file typedefs inside an extern "c" {} block,
       conditionally using the __cplusplus #define:
       Near the beginning of your header:

        #ifdef __cplusplus
        extern "C" {            /* Assume C declarations for C++ */
        #endif  /* __cplusplus */

       And at the end:

        #ifdef __cplusplus
        }
        #endif


        STRICT Compatibility and Windows 3.0 Backward Compatibility
        -----------------------------------------------------------

One of the most important features of STRICT is that handle types are no
longer defined as WORDs.  They are declared in such a way that will cause a
compiler error if you try to pass the wrong type of handle or a non-handle
value to a function, for example.  It's important that all of our handle
types be declared this way when the user #defines STRICT.

A number of new types and such have been defined in windows.h, such as
HINSTANCE, HGLOBAL, and HLOCAL, which should be used where appropriate in
place of the generic HANDLE type.  HANDLE should be used only in cases of
an arbitrary handle type.

The WPARAM, LPARAM, and LRESULT types should be used for arbitrary or
polymorphic parameters or return values. Typedefs exist for all callback
functions, which are used in place of FARPROC.

In most cases, functions declared with these types are fully 3.0 compatible
unless STRICT is #defined.  It may sometimes be necessary to use #ifdef
STRICT/#else/#endif to provide 3.0-compatible, non-STRICT declarations in
some cases.

    *  Use DECLARE_HANDLE() to declare handle types.  If you have polymorphic
       API parameters (or structure fields) that are designed to accept more
       than one type of handle (e.g., the GDI SelectObject function), there
       are a few tricks you can employ.  1) Declare a generic handle type
       like HGDIOBJ as void _near*, which will accept any handle type. The
       HANDLE type can be used for this purpose.  2) if the number of
       polymorphic types is small, and there are lots of cases where they can
       be used polymorphically, use DECLARE_HANDLE to declare one handle
       type, and typedef the rest to be the same as the first one (e.g,
       HMODULE and HINSTANCE in windows.h).

    *  Structure and function declarations should use the appropriate STRICT
       type, rather than the generic HANDLE,

    *  Declare arbitrarily or polymorphic types with LPARAM, WPARAM, and
       LRESULT instead of WORD, LONG, or DWORD.  This indicates to a
       programmer that these values should not be used directly, but should
       instead be cast and assigned to the proper type of value before use.

    *  Declare arbitrarily or polymorphic pointer types with void FAR*
       instead of LPSTR or BYTE FAR*.  The nice thing about the void FAR*
       type is that you can pass any type of pointer to it without having to
       cast first.

    *  If any of the above STRICT rules result in declarations that are
       not compatible with previously released versions of the header file,
       use #ifdef STRICT/#else/#endif to ensure that both declarations
       are present.

    *  Use WINAPI instead of FAR PASCAL for declaring APIs.  Use CALLBACK
       instead of FAR PASCAL in callback function typedefs.

    *  Be sure to use "const" where appropriate in your pointer parameters.
       If the pointer is read-only, then it should be const.  If the function
       writes through the pointer, it must not be const.  For const
       zero-terminated string pointers, use LPCSTR instead of LPSTR.

    *  Don't declare NPXXX or SPXXX pointer parameter types for new structures.
       (but don't remove them if they've already been defined in a shipped
       header).  Users are encouraged to use "*", const, _near, _far, and
       _huge explicitly where appropriate.  Now that our headers contain
       "const" pointer types, having LP, NP, and const pointer type variants
       for every structure would just clog the compiler up with typedefs.

    *  Spell out pointer declarations, rather than using the LPXXX type form.
       This allows for use of const and _huge where appropriate, without
       having to define lots of new typedefs:

             SetFoo(const FOO FAR* pfoo);
             GetFoo(FOO FAR* pfoo);

    *  Use parameter names in your API function prototypes.  This greatly
       contributes to the readability and usefulness of your header, at
       very little cost.  Make sure all your APIs and callback declarations
       are fully prototyped.  Use the same naming conventions as in our
       documentation (contact gregro or ralphw for a summary of those
       conventions).  NOTE: As of this writing, windows.h does not yet
       include function prototype names.
