Programming the Win32 SDK

From Higher Intellect Wiki
Jump to: navigation, search

               ***********************************************
               *       A beginners guide to programming      *
               *               the Win32 SDK.                *
               *              By Stephen Haunts              *
               *                                             *
               *                  PART 1                     *
               *        T H E   B A R E   B O N E S          *
               ***********************************************

This document serves as a basic introduction to Win32 programming.  If your
interested in games delevopment with DirectX then you will probable write
your programs in a different style to what is explained here for the purposes
of speed.  But even so, you still need to know the basics.  Before you can
get a good grasp of windows programming with the Win32 it is recommended
that you have a fairly strong understanding of writting  DOS applications
in C and/or C++.

Although this document covers the bare bones of Win32 programming it is quite
a heavy read if your not familiar with this system.  It may take a while to
get a good grasp of the underlying system behind Win32.  The method of programming
is quite different to that of DOS based programming in C.  The bit that throws
most people is the idea of message maps ect.

The some people that the Win32 ways look quite alien and un C like sometimes.
But don't worry.  If I can learn Win32 then you can.

This document builds up a simple windows style hello world program to illustrate
the basic concepts to Win32 programming (The source code for this programm will
be bolted on at the end).

I will not cover menus and other resources in this document because I dont
want to confuse the issue.  You have to get a grasp of the basics first.
Resources and possiby DirectX will come in different documents.  Hell I may
even make a series of programming articals relating to different aspects
of windows development.  What do you think?

If you have any constructive comments about this document (spelling mistakes
aswell) then please mail me at the following address:
       S.B.B.Haunts@herts.ac.uk

PLEASE NO FLAMING.  I GET QUITE NASTY IF  PEOPLE FLAME ME FOR SOME STUPID
PETTY REASON WITHOUT GIVING A FULL EXPLAINATION.

Why Did I Write This Document ?
-------------------------------

Good question.  I my self am personnaly learning to program in windows.  I feel
the best way to get complicated issues to stick in my head are to write short
notes on them.  Because I havn't really found any decent resources on the net
for beginners in Win32 I decided to write up my notes and publish them for you
all to view/download/print for free.  Arn't I nice :-)

Who The Hell Am I ?
-------------------

My name is Stephen Haunts and I am 20 years old.  I am currently studying for
a BSc Hons Degree in Computer Science at the University of hertfordshire.  I
have just completed my 2nd year of studies and am about to start my 1 years
industry placement, for whome I will be working for Argonaut Software (those
of Star Wing fame on the Super Nintendo console).

I have always been a DOS programmer on the PC but my job requires me to train
up in Windows programming and DirectX.

OK Here we go folks, have fun :-)

Intoduction to windows programming 'WinHello'
---------------------------------------------

Traditionally the introductory program has always been a hello world message.
Under dos such a program could be written in only a few lines but under
windows you are looking at more like a 100 lines of code 'OUCH.' Thats even
worse than a hello world program in assembler :-).

When you are working on a large project though the total size of you windows
program may actually end up being less than that of a DOS program (lines of
code that is).

The WinMain Procedure
---------------------

Just as every do DOS C program has a procedure called main at its heart, every
windows program has a similar entry point with the title WinMain (and, yes,
this title is case sensative).  Also, just as a DOS C program may include
provisions within the main procedure declaration to retrieve command-line
parameters, the WinMain declaration includes a similar provision in the
lpszCmdParam parameter, even though command-line parameters are rarely used
under windows.

However, unlike in DOS programming, the declarations used for WinMain are
not optional and must be declared exactly in the order and form shown,
regardless of whether each specific argument will be used or ingored.

Also note that the reserved word PASCAL is used in al exported function declarations,
indicating to the compiler that Pascal rather than C ordering is used for
all arguments(values) pused onto the stack.  While C commonly uses inverted
ordering, placing the least-significant bytes first on the stack, windows
ises pascal ordering which, like Unix, places the most-significant bytes
first.

Here is the declaration used for WinMain:

        int PASCAL WinMain ( HANDLE hInstance,
                             HANDLE hPrevInstance,
                             LPSTR  lpszCmdParam,
                             int    nCmdShow )

Of the four calling arguments, the first two are of primary importance.
The data type HANDLE refers to a 32-bit, unsigned value;  the hInstance and
hPrevInstance are unique identifiers supplied by windowsNT and 95 systems.

Inlike DOS applications where where only one program (TSRs excepted) is active
at a time, multitasking systems require unique identification, not only for
each application, but also for each instance of an application of an application
that may be executing.  Ergo, the hInstance and hPrevInstance parameters are
assigned only when an application instance becomes active.  they provide
equivalents of the "task ID" and "process ID" values common in other
multitasking environments.

The hPrevInstance (previous instance) identifier is the hInstance identifier
previously assigned to the most recent instance of an application that is
already excuting.  If there is no previous instance of the application
currrently running, which is frequently the case, this argument will by
null(0).  The reason for this second process identifier will be demonstrated
presently.

The third prameter, lpszCmdParam, is a long (FAR) pointer to a null-terminated
(ASCIIZ) string containing any command-line parameters passed to the program
instance.

The fourth calling parameter, nCmdShow, is simply an integer argument indicating
whether the newly launched application will be displayed as a normal window
or initially displayed as an icon.

Next, following the procedure declaration itself, a brief list of local
variable declarations appears.

        {
                static char szAppName[] = "WinHello";
                HWND        hwnd;
                MSG         msg;
                WNDCLASS    wc;

The data types used in the declaration will be covered in more detail later
in the document.  Here is a quike rundown:

        * HWND identifies a window handle

        * MSG identifies a message value

        * WNDCLASS refers to a recford structure used to pass a number of
          values relevant to the application's main window.


Registering a Window Class
--------------------------

The first task accomplished within the WinMain procedure depends on the
hPrecInstance argument passed.  If a previous instance of this application is
already active, there's no need to register the window class a second time.
But it's more likely, of course, that this is the first instance of the app-
lication (hPrevinstance is null) and, therefore, the window class definitions
must be assigned and the window class registered.

The wc srtructure is defined in Windows.H (which must be included in all
windows applications).  Of the WNDCLASS record fields, the second of the
fields can usually remain unchanged from one application to another

The first field is the window-style specification.  In this example, it is
assigned two style flag values combined by ORing bitwise.  These flags are
defined in windows.h as 16-bit constants and shall be explained later.

Here the CS_HREDRAW and CS_VREDRAW flags indicate that the following windows
should be redrawn completely anytime the horizontal or vertical size changes.
Thus, for the WinHello demo, if the window size changes, the window display
is completely redrawn, with the hello message string recentered in the new
display.

        if (! hPrevInstance )
        {
                wc.style        = CS_HREDRAW | CS_VREDRAW;
                cs.lpfnWndProc  = WndProc;

The second field in the WNDCLASS structure, lpfnWndProc, is a pointer to the
exported procedure WndProc, in this example - which will handle all windows
messages for this application.  The type prefix lpfn identifies this field
as a "long pointer to function." But realize that these prefic conventions
are provided for the beifit of the programmer.  Tey are not absaolutes, nor do
these designations place any contraints on the compiler.

The next two record fields are integers, which are resereved to specify extra
information about the class or window styles.  Commonly, neither is required
and, by default, both are initialized as zeros (0).  Incidentally, the
cb_ prefix stands for count of bytes.

                wc.cbClsExtra   = 0;
                wc.cbWndExtra   = 0;
                wc.hInstance    = hInstance;

The next field, hInstance, is simply the recipient of the hInstance argument
passed by windows when the program is initially called.  This is also one field
assignment that can be considered constant for all applications.

The next three data fields currently assign default values for the
application's icon, cursor, and background color and pattern.

                wc.hIcon         = LoadIcon( NULL, IDI_APPLICATION );
                wc.hCursor       = LoadCursor( Null, IDC_ARROW );
                wc.hbrBackground = GetStockObject( WHITE_BRUSH );

The default IDI_APPLICATION specification for the icon assigns the pre-
defined image of a white square with a black border.  The IDC_ARROW cursor
assigns the stock cursor graphic of a slanted arrow.

In the third asignment, the hbrBackground field contains the background
colour and pattern used for the application's client region.  The hbr stands
for handle to brush, where "brush" refers to a pixel patterm used to fill or
paint an area.

Next, since this application does not have a menu assigned, the menu name is
entered as a null value.  The class name (lpszClassName) is assigned the null-
terminated (ASCIIZ) string defined previously.

                wc.lpszMenuName         = NULL;
                wc.lpszClassName        = szAppName;
                RegisterClass( &wc );
        }

And last within this conditional subprocess, the RegisterClass function is
called with the wc structure passed as a paramater (by address) to register
this window class definition with the NT/95 operating system.

Creating an Application Window
------------------------------

While the previous step, registering a window class, has defined char-
acteristics that are common to all instances of the application, this is not
yet created the application window itself.  Instead, unlike the RegisterClass
function call, which is called only once, every instance of the application
must call the CreateWindow function to produce the actual window display.

The handle to the application window that is returned by the CreateWindow
function will be used later as an argument in other function calls as a
unique itentifier for the actual window belonging to the application instance.
But, while many properties of the application class have already been defined,
other properties have already been defined, other properties specific to this
instance of the application have not; they are passed now as parameters to
the CreateWindow function.

        hWnd = CreateWindow(
                  szAppName,                  // window class name
                  "Hello, World - NT Style",  // window caption
                  WS_OVERLAPPEDWINDOW,        // window style
                  CW_USERDEFAULT,             // initial X position
                  CW_USERDEFAULT,             // initial Y position
                  CW_USERDEFAULT,             // initial X size
                  CW_USERDEFAULT,             // initial Y size

The first two parameters passed are the application class name - the same
ASCIIZ string that was used when the class was registered - and the app-
lication's initial window aption.  If you don't want a caption, then pass
this as null.

The third parameter defines the window style, generically, is passed as
WS_OVERlAPPEDWINDOW, a value that is a combination of individual flags
defined in windows.h.

The fourth through seventh parameter established the applicaiton window's
initial position and size.  They can be passed as explicit values or, more
often, as CW_USERDEFAULT.  This parameter instructs windows to use the
default values for an overlapped window, positioning each successive
overlapped window at a stepped horizontal and vertical offset from the upper-
left corner of the screen.

The next parameter is passed as null for the simple reason that this application
is not associated with a parent window.  Alternatively, if this window were to
be called as a shild process belonging to another aplication, the parent's
window hadle would be passed as a parameter here.

                  NULL,                       // parent window handle
                  NULL,                       // window menu handle

The ninth parameter using in calling the CreateWindow function is also passed
as null, directing the appliation to use the default system menu.  Note,
however that the menu in question is the windows fram's pull-down menu (upper
-left icon on most window frames), not the menu (or toolbar), which is defined
as an application resource and assigned during application class registration.

The tenth calling parameter, which can never be passed as null, is the same
instance handle originally supplied by the NT/95 system.

                  hInstance,                  // program instance handle
                  NULL  );                    // creation parameters

The final parameter, again null in this example, may in other cases provide
a pointer to additional data for use either by the application window or by
some subsequent process.  In most examples, however, this will be an empty
(null) argument.

Now, after CreateWindow has been called, the application window has been
created internally in NT/95 "world view" but does not yet appear on the
actual screen display.  Therefore, the next step is to call the ShowWindow
function, passing as parameters the hwnd value returned by CreateWindow and
the nCmdShow argument supplied when Winmain was initially called.

                  ShowWindow( hwnd, nCmdShow );
                  UpdateWindow( hwnd );

The ShowWindow function, however, contrary to what you might assume, does only
a portion of the task of creating (painting) the window display.  It is
principally responsible for creating the window frame, caption bar, menu
bar, and minimize/maximize buttons.  But what this function does not create
is the client window area -the display area specific to the application
itself.  Therefore, one more function call is necessary before the window
display is complete: a call to the UpdateWindow function with the hwnd window
handle as an argument (which actually posts a WM_PAINT message to the
application instructing it to repaint its own window area- a process that
will be discussed in a moment.

The Message-Handling Loop
-------------------------

Windows creates and manages a seperate message queue for each active windows
program instance.  Thus, when and keyboard or mouse event occurs, windows
translates this event into a message value.  This value is placed in the
application's message queue. where it waits until it is retrieved by the
applicationsinstance, which is precisely the purpose of the message-handling
loop.

The message handling loop begins by calling the GetMessage function to retrieve
messages from the application instance's message queue.  As long as the message
retrieved is not a WM_QUIT message (0x0012), GetMessage will return a TRUE
(nonzero) result.  The actual message value is returned in the msg structure
which was passed by address.

                while( GetMessage( &msg, NULL, 0, 0) )
                {

The syntax for the GetMessage function is defined as:

        BOOL GetMessage( lpMsg, HWND, wMsgFilterMin, wMsgFilterMax )

In most cases, only the first parameter is actually used (to return the
message itself).  The remaining three parameters are usually passed as null
or zero.

The initial parameter is a pointer to a message structure to receive the
message information retrieved and, subsequently, to pass this data on though
to the TranslateMessage and DispatchMessage functions.  And, obviously, without
this parameter, there would be little point in calling the GetMessage function
at all.

The third and fourth parameters provide filter capabilities, restricting the
message types returned.  When both parameters are passed as 0, no filtering
occurs.  Alternatively, constants such as WM_KEYFIRST and WM_KEYLASY could be
passed as filter values to restrict message retrieval to keyboard events or,
by using WM_MOUSEFIRST and WM_MOUSELAST, to retrieve only mouse-related
messages.

filters and window selection aside, however, the GetMessage function (together
with the PeekMessage and WaitMessage functions) has another important char-
acteristic.

Conventionally, loop statements monopolize the system until terminated, thus
preempting or preventing other operations for the duration of the loop.   And,
in other circumstances -remember this as a caution -even under windows, loop
operations can tie up system resources.

The GetMessage function, however, has the ability to preemp the loop operation
to yield control to other applications when no messages are available for the
current application, or when WM_PAINT or WM_TIMER messages directed to other
tasks are available.  Thus, it can give other applications their share of CPU
time to execute.

For the present, when the aplication recieved an event messsage (other than
WM_QUIT), the message value is passed.  First, it goes to the windows Translate-
Message function for and keystroke translation that may be specific to the
application.  Then it is passed to the DispatchMessage handler, where the message
information is passed to the next appropriate message-handling procedure (back
to windows, either for immediate handling or, indirectly, for forwarding to the
exported WndProc procedure).

                TranslateMessage( &msg );
                DispatchMessage( &msg );
             }

Finally, when the message-processing loop terminates, the wParam argument from
the final message retrieved is, in turn, returned to the calling application
-the NT/95 desktop itself.

             return msg.wParam;
           }

Messages and Event-Driven Programming
-------------------------------------

In its simplest form, message driven programming (also known as event driven
programming) is a process by which various subprocesses and/ or applications
communicate.  In windows, messages are the process used by windows itself to
manage a multitasking system and to share keyboard, mouse, and other
resources by distributing information to applications, application instances,
and processes within an application.

Thus, under windows, instead of applications recieving information directly
from the keyboard or the mouse driver, the NT/95 operating system intercepts
all input information, packaging this information using the MSG message
structure and then forwarding the prepared messages to the appropriate recipients.
In turn, the recipient aplications use TranslateMessage for application-specific
interpretation (particularly accelerator key assignments)  before calling
DispatchMessage to forward individual traffic items to their appropriate handlers.

Furthor more, the process descipbed is not limited to keyboard and mouse events.
Instead, this includes all input devices (including ports), as well as messages
generated by application and child subprocesses, windows timers, or, quite
frequently by windows itself.

Abstract descriptions, however, provide only a theoretical outline without
really illustrating how these processes function.

The Message Record Structure
----------------------------

The MSG (message structure) record type is defined in WinUser.h as

        typedef struct tagMSG
        {
                HWND    hwnd;
                UINT    message;
                WPARAM  wParam;
                LPARAM  lParam;
                DWORD   time;
                POINT   pt;
        } MSG, *PMSG, NEAR *NPMSG, FAR *LPMSG;

The POINT data type is defined in WinDef.h as:

        typedef struct tagPOINT
        {
                int     x;
                int     y;
        } POINT, *PPOINT, NEAR *NPPOINT, FAR *LPPOINT;

The message-event fields are used as:

- hWnd: The handler of the specific window to which the message is directed.
        Please note that each application is itself composed of a series of
        seperate windows.  These windows include the frame, the caption bar,
        the system menu, and minimize and maximize buttome, as well as the
        application's main display window.  Normally, only messages directed
        to the client window will be forwarded, by the DispatchMessage proc',
        to the application's WndProc procedure.  Messages directed to other
        application windows are generally handled indirectly by NT/95, even
        though this may result, in turn, in further messages being sent to
        the client window.

- message: A 16bit value identifying the message.  Constants corresponding to
           all message values are provided though windows.h and begin with the
           WM_ prefix (which stands for windows message). For example, a mouse
           button event message might be identified by the constant WM_LBUTTON.

- wParam:  A 32bit (double word) message parameter. The value format and meaning
           depend on the primary event message type.  Variously, the wParam
           argument might convey a coordinate point pair, use the low word value
           to identify a secondary message type, provde some other type of data, of
           be ignored entirely.  In many cases, the wParam value will be treated as
           two seperate word values with different functions.

- lParam:  A 32bit (long) message parameter.  The value and meaning of this parameter
           depend on the primary event message type.  Variously, the lParam argument
           might provide a pointer to a string or record structure; break down as a
           group of word, byte, or flag values; or, quite frequently, be completely
           unused.

- time:    The double word time value identifies the time the message was placed in the
           message queue.

- pt:      This field contains the mouse coordinates at the time the message was
           placed in the message queue (irrespective of the message-event type
           or origin).

Note that these last two fields are not passed to the WndProc procedure.
Instead, these two fields are used only by NT/95, principally to resolve any
conflict over the order of events and, of course, to determine where a specific
event should be addressed.

The WndProc Procedure
---------------------

The WndProc procedure is the point where each application actually begins to function.
Remember, the WndProc procedure recieves messages indirectly from the NT/95 operating
system, but the WndProc procedure determines the application's response to the
messages received.

Previously, when the application window class was registered, the address of
the WndProc subroutine wassed to windows as:

        wc.lpfnWndProc = WndProc;

And, given this address, windows calls WndProc directly, passing event messages
in the form of four parameters, as:

        long FAR PASCAL WndProc( HWND hwnd,
                                 UINT msg,
                                 UINT wParam,
                                 LONG lPARAM )

The four calling parameters received correspond to the first four fields of the
message structure described above, beginning with the hwnd parameter.
identifying the window to which the message is directed.  Since most applications
have only one client window that will be addressed thus, this parameter may
seem superfuous.  This parameter will, however, frequently be needed as an
argument for use by other processes.

At the present, it's the second calling parameter, msg, that is immediately
crucial and identifies the window event message.  The third and fourth parameters,
wParam and lParam, provide amplifying information to accompany the window
event message.

Typically, the WndProc procedure does relatively little or nothing itself
outside the switch...case responding to the msg parameter.  In the hello program
demo, local response is provided for only two event messages: the WM_PAINT
and WM_DESTROY messages.  All other event messages handled are by default
(by the NT/95 operating systems).

The first of these two, WM_PAINT, is a message that is generally not issued
directly.  It will be issued indirectly anytime an application window is
created, moved, resized, restored from an icon, uncovered by a change in some
other application window, or something else has occured -in this or in some
other application- to invalidate the client area of the present application.

The DOS equivalent of the Hello program would consist principally of a print
statement, possibly with an optional clear screen statement.  For the windows
version, however, there are differences for two main reasons:

        * Because the response to the WM_PAINT message is not a one-time
          occurance.

        * Because a bit more is accomplished than simply dumping the text
          to the screen.

The first requirement, before anything can be written to the client window, is
for the application to retrieve a handle (hdc) to the device context (the output
device or, in this example, the screen).  After the screen update is finished,
this handle will be released by calling the endpaint function.

        switch( msg )
        {
                case WM_PAINT:
                        hdc = BeginPaint( hwnd, &ps );
                        GetClientRect( hwnd, &rect );

After retrieving the device context handle, the GetClientRect procedure is called
to retrieve the rect structure with coordinates describing the client window.
The rect structure consists of four fields, which report coordinates for the client
window.  However, the coordinates reported are relative to the client window
itself.  Therefore, the left and top fields are returned as zeros, and the right
and bottom fields return the current width and hight of the client window
(reported in pixels).

Once the window coordinates have been retreived, the rect structure can be used
as an argument in the next step to specify the region where the actual message
will be drawn.

                DrawText( hdc, "Hello World", -1, &rect,
                        DT_SINGLELINE | DT_CENTRE | DT_VCENTER );

Since print statements, per se, cannot be used in windows (because they are
unsuited for a graphics display environment), the DrawText function is used
instead.  DrawText begins with the hdc argument providing access to the active
display, followed by the string (text) to be drawn.

The third parameter, -1, indicates that the string argument is a null-terminated
string.  Alternatively, this parameter could be a value specifying the string
length, with the second parameter an indirect reference to a character array.

The fourth argument is the address of the rect structure, identifying an area
where the string will be drawn.  The fifth argument is a combination of flags
that set alignment and ristrict the text drawn to a single display line.

Last, the EndPaint function is called, again with the client window handle and
the paint structure (ps) as argument.  This function releases the device context
and validates the now-restored client area, and incidentally, completes the
response to the WM_PAINT message.

                EndPaint( hwnd, &ps );
                return( 0 );

The second application message requiring a local resonse is the WM_DESTROY
message, which is issued when the application is ready to close.  This message
can be generated via several channels.  For this example though it is issued
only if/when the system menu close option is selected.

                case WM_DESTROY:
                        PostQuitMessage(0);
                        break;

The WM_DESTROY message is issued to give the application an opportunity to do
any necessary cleanup before shutting down.  Therefore, as circumstances demand
the application response at this point could include provisions for calling a
dialog box to requiest confirmation, for closing/saving files, or for any other
final tasks required for a smooth exit.

Finally (unless, of course, termination is to be aborted), the WN_DESTROY
response is completed by calling the PostQuitMessage function, which in turn,
places a WM_QUIT message in the application's message queue to terminate the
message loop in WinMain.

Explicit handling has been provided for only two of the messages that might be
sent to this application.  Provisions are also required to return to windows
for procesing all mssages that have not been explicitly handled here, as a
default case.

        default:                // is msg unprocessed
           return(              //   return to windows
             DefWindowProc( hwnd, msg, wParam, lParam ) );
       }
       return( NULL );
    }

This default provision returns the message -precisely as it was originally
received- to windows, then also returns the results from DefWindowProc to the
windows calling process.  This final provision should be considered standard
for all WndPoc message-handler procedures.

For a windows program the .C source code is only a part of the story.  In most
cases, the application will also incorporate an .H header file and, almost
always, a .RES resource file.

Here is the complete source code for the hello world program.  You can just
cut out the program from this document and compile it straght off.  The code
should work under any windows compiler with the Win32 libraries.  I have only
tested the code so far under Microsoft Visual C v4.

8<-----------------Cut-out-this-code-and-compile-it--------------------------

//===================================//
//            Hello.C                //
//           HELLO WORLD             //
//===================================//

#include <windows.h>

long APIENTRY WndProc( HWND hwnd,   UINT msg,
                       UINT wParam, LONG lParam )
{
   HDC         hdc;
   PAINTSTRUCT ps;
   RECT        rect;

   switch( msg )
   {
      case WM_PAINT:
         hdc = BeginPaint( hwnd, &ps );
         GetClientRect( hwnd, &rect );
         DrawText( hdc, "Hello, World! Muddy Funsters", -1, &rect,
                   DT_SINGLELINE | DT_CENTER | DT_VCENTER );
         EndPaint( hwnd, &ps );
         return( 0 );

      case WM_DESTROY:			// message: window being destroyed 
         PostQuitMessage(0);
         break;

      default:						// if msg unproccessed,
                                                        // return to Windows
         return( DefWindowProc( hwnd, msg, wParam, lParam ) );
   }
   return TRUE;
}

int APIENTRY WinMain( HANDLE hInstance,    HANDLE hPrevInstance,
                      LPSTR  lpszCmdParam, int    nCmdShow )
{
   static char szAppName[] = "WinHello";
   HWND        hwnd;
   MSG         msg;
   WNDCLASS    wc;

   if( ! hPrevInstance )
   {
      wc.style         = CS_HREDRAW | CS_VREDRAW;
      wc.lpfnWndProc   = WndProc;
      wc.cbClsExtra    = 0;
      wc.cbWndExtra    = 0;
      wc.hInstance     = hInstance;
      wc.hIcon         = LoadIcon( NULL, IDI_APPLICATION );
      wc.hCursor       = LoadCursor( NULL, IDC_ARROW );
      wc.hbrBackground = GetStockObject( WHITE_BRUSH );
      wc.lpszMenuName  = NULL;
      wc.lpszClassName = szAppName;
      RegisterClass( &wc );
   }
   hwnd = CreateWindow(
      szAppName,                                   // window class name       
      "Muddy Funster Software",                    // window caption          
      WS_OVERLAPPEDWINDOW,                         // window style            
      100,                                         // initial X position      
      100,                                         // initial Y position      
      400,                                         // initial X size          
      200,                                         // initial Y size          
      NULL,                                        // parent window handle    
      NULL,                                        // window menu handle      
      hInstance,                                   // program instance handle 
      NULL  );                                     // creation parameters     
   ShowWindow( hwnd, nCmdShow );
   UpdateWindow( hwnd );


   while( GetMessage( &msg, NULL, 0, 0 ) )
   {
      TranslateMessage( &msg );
      DispatchMessage( &msg );
   }
   return msg.wParam;
}

8<--------------------------------------------------------------------------

Windows Conventions and Data Types
----------------------------------

This following section describes some windows NT/95 conventions for naming,
as well as some of the windows data types, data structures, and handle
identifiers.

Variable Names and Hungarian Notation
-------------------------------------

As programs have become more complex in terms both of size and of the proliferation
of data types, many programmers have adopted a variable-naming convention, which is
commonly fered to as Hungarian notation (named in honor of Microsoft programmer,
Charles Simonyi).

Using Hungarian notation, variable names begin with one or more lowercase
letters, which denote the variable type, thus providing an inherent identification.
For example, the prefix h is used to identify a handle, as in hWnd or hDlg,
refering to a window and dialog handles, respectively.  In like fasion, the
prefix lpsz identifies a long pointer to a null-terminated (ASCIIZ) string.

The followng table summarizes the Hungarian notation conventions.  These aren't
cast in stone though,  you can come up with variations.

             ----------------------------------------------------
             |  PREFIX   |            DATA TYPE                 |
             |-----------+--------------------------------------|
             |    d      | boolean                              |
             |    by     | byte or unsigned char                |
             |    c      | char                                 |
             |    cx/cy  | short used as size                   |
             |    dw     | DWORD, double word or unsigned long  |
             |    fn     | function                             |
             |    h      | handle                               |
             |    i      | int                                  |
             |    l      | long                                 |
             |    n      | short int                            |
             |    s      | string                               |
             |    sz     | ASCIIZ null-terminated string        |
             |    w      | WORD unsigned int                    |
             |    x,y    | short used as coordinates            |
             |--------------------------------------------------|

Predefined Constants
--------------------

Windows also uses an exclusive list of predefined constants, which are used as
messages, flag values, and other operational parameters.  These constants
values are always uppercase, and most include a two or three letter prefix set
off by an underscore.  Here are some examples.

                CS_HREDRAW      CS_VREDRAW      CW_USERDEFAULT

                DT_CENTER       DT_SINGLELINE   DT_VCENTER

                IDC_ARROW       IDI_APPLICATION WM_DESTROY

                WM_PAINT        WS_OVERLAPPEDWINDOW

In the case of constant identifiers, the prefixes indicate the general category
or the constant.  The table below shows the meaning of the prefixes.

             ----------------------------------------------------
             |  PREFIX   |            CATEGORY                  |
             |-----------+--------------------------------------|
             |    CS     | Class style                          |
             |    CW     | Create window                        |
             |    DT     | Draw text                            |
             |    IDC    | Cursor ID                            |
             |    IDI    | Icon ID                              |
             |    WM     | Window message                       |
             |    WS     | Window style                         |
             ----------------------------------------------------

Data Types
----------

Windows also uses a wide variety of new data types and type identifiers, most
of which are defined in either the WinDef.h or WinUser.H header files.

             ------------------------------------------------------
             | DATA TYPE |            MEANING                     |
             |-----------+----------------------------------------|
             |  FAR      | Same as far                            |
             |  PASCAL   | Same as pascal                         |
             |  WORD     | Unsigned integer (16 bits)             |
             |  UINT     | unsigned integer, same as word         |
             |  DWORD    | double word, unsigned long int (32bits)|
             |  LONG     | signed long pointer to character string|
             |  LPSTR    | long (far) pointer to character string |
             ------------------------------------------------------

Data Structures
---------------

Similarly, windows adds a variety of new data structures.  Again, most are
defined in either WinDef.h or WinUser.h.  

      ---------------------------------------------------------------
      | STRUCTURE    | EXAMPLE |          MEANING                   |
      |--------------+---------+------------------------------------|
      | MSG          |  msg    | Message structure                  |
      | PAINTSTRUCT  |  ps     | Paint structure                    |
      | PT           |  pt     | Point structure (mouse position)   |
      | RECT         |  rect   | Rectangle struc',2 coordinate pairs|
      | WNDCLASS     |  wc     | Window class structure             |
      ---------------------------------------------------------------


Handle Identifiers
------------------

In like fasion, a variety of handles are defined for use with different
windows elements.  Like constants, the handle types use all uppercase. The
following table shows a few examples.

      ----------------------------------------------------------------
      | HANDLE TYPE  | EXAMPLES    |          MEANING                |
      |--------------+-------------+---------------------------------|
      | HANDLE       |hnd or hdl   | Generic handle                  |
      | HWND         |hwnd or hWnd | Window handle                   |
      | HDC          |hdc or hDC   | Device context handle (CRT)     |
      | HBRUSH       |hbr or hBrush| Paint brush handle              |
      | HPEN         |hpen or hPen | Drawing pen handle              |
      ----------------------------------------------------------------


Share your opinion