2.6.1 Creating the C-Language Source File

The C-language source file contains the WinMain function, the MainWndProc window procedure, the About dialog box procedure, and the InitApplication and InitInstance initialization functions. Name the file GENERIC.C.

The contents of the GENERIC.C file look like this:

/******************************************************************
   PROGRAM: GENERIC.C

   PURPOSE: Generic template for Windows applications

   FUNCTIONS:

        WinMain - calls InitApplication, processes message loop
        InitApplication - initializes window data, registers window
        InitInstance - saves instance handle, creates main window
        MainWndProc - processes messages
        About - processes messages for About dialog box

   COMMENTS:

        Windows can have several copies of your application running
        at the same time. The variable hinstCurrent keeps track of
        which instance this application is so that processing will
        be to the correct window.

******************************************************************/




#define STRICT

#include <windows.h> /* required for all Windows applications   */
#include "generic.h" /* specific to this program                */

HINSTANCE hInst;     /* handle current instance                 */

/******************************************************************

    FUNCTION: WinMain(HINSTANCE, HINSTANCE, LPSTR, int)

    PURPOSE: Calls initialization function, processes message loop

    COMMENTS:

        Windows recognizes this function by name as the initial
        entry point for the program. This function calls the
        application initialization function, if no other instance
        of the program is running, and always calls the instance
        initialization function. It then executes a message
        retrieval and dispatch loop that is the top-level control
        structure for the remainder of execution. The loop is
        terminated when a WM_QUIT message is received, at which
        time this function exits the application instance by
        returning the value passed by PostQuitMessage.

        If this function must terminate before entering the message
        loop, it returns the conventional value NULL.

*******************************************************************/

int PASCAL WinMain(hinstCurrent, hinstPrevious, lpszCmdLine, nCmdShow)
HINSTANCE hinstCurrent;         /* handle of current instance     */
HINSTANCE hinstPrevious;        /* handle of previous instance    */
LPSTR lpszCmdLine;              /* address of command line        */
int nCmdShow;                   /* show-window type (open/icon)   */
{
    MSG msg;                    /* message                        */

    if (!hinstPrevious)        /* other instances of app running? */
        if (!InitApplication(hinstCurrent)) /* initialize shared  */
            return FALSE;       /* exits if unable to initialize  */

    /* Perform initializations that apply to a specific instance. */

    if (!InitInstance(hinstCurrent, nCmdShow))
        return FALSE;

    /*
     * Acquire and dispatch messages until a WM_QUIT message
     * is received.
     */

    while (GetMessage(&msg, /* message structure                  */
            NULL,       /* handle of window receiving the message */
            NULL,       /* lowest message to examine              */
            NULL))      /* highest message to examine             */
        {
        TranslateMessage(&msg);   /* translates virtual key codes */
        DispatchMessage(&msg);    /* dispatches message to window */

    }
    return (msg.wParam);          /* value from PostQuitMessage   */
}


/******************************************************************

    FUNCTION: InitApplication(HINSTANCE)

    PURPOSE: Initializes window data and registers window class

    COMMENTS:

        This function is called at initialization time only if
        no other instances of the application are running. This
        function performs initialization tasks that can be done
        once for any number of running instances.

        In this case, initialize a window class by filling out a
        structure of type WNDCLASS and calling the RegisterClass
        function. Since all instances of this application use
        the same window class, you need to do this only when the
        first instance is initialized.

*******************************************************************/

BOOL InitApplication(hinstCurrent)
HINSTANCE hinstCurrent;  /* handle of current instance            */
{
    WNDCLASS  wc;

    /*
     *  Fill in window-class structure with parameters that
     *  describe the main window.
     */

    wc.style = NULL;               /* class style(s)              */
    wc.lpfnWndProc = MainWndProc;  /* window procedure            */
                                   /* for windows of this class   */

    wc.cbClsExtra = 0;             /* no per-class extra data     */
    wc.cbWndExtra = 0;             /* no per-window extra data    */



    wc.hInstance = hinstCurrent;   /* application that owns class */
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName =  "GenericMenu";   /* menu name in .RC file  */
    wc.lpszClassName = "GenericWClass"; /* name in CreateWindow   */

    /* Register the window class and return success/failure code. */

    return (RegisterClass(&wc));
}

/******************************************************************
    FUNCTION:  InitInstance(HINSTANCE, int)

    PURPOSE:  Saves the instance handle and creates a main window

    COMMENTS:

        This function is called at initialization time for every
        instance of this application. This function performs
        initialization tasks that cannot be shared by multiple
        instances.

        In this case, save the instance handle in a static variable
        and create and display the main window.

*******************************************************************/

BOOL InitInstance(hinstCurrent, nCmdShow)
HINSTANCE hinstCurrent; /* handle of current instance             */
int nCmdShow;           /* param for first ShowWindow call        */
{
    HWND hWnd;          /* handle of main window                  */

    /*
     * Save the instance handle in a static variable, which will be
     * used in subsequent calls from this application to Windows.
     */

    hInst = hinstCurrent;

    /* Create a main window for this application instance.        */










    hWnd = CreateWindow(
        "GenericWClass",                /* see RegisterClass call */
        "Generic Sample Application",   /* text for title bar     */
        WS_OVERLAPPEDWINDOW,            /* window style           */
        CW_USEDEFAULT,                  /* default horz position  */
        CW_USEDEFAULT,                  /* default vert position  */
        CW_USEDEFAULT,                  /* default width          */
        CW_USEDEFAULT,                  /* default height         */
        NULL,                /* overlapped windows have no parent */
        NULL,                /* use window class menu             */
        hinstCurrent,        /* this instance owns this window    */
        NULL                 /* pointer not needed                */
    );


    /* If the window could not be created, return "failure."      */

    if (hWnd == NULL)
        return FALSE;

    /*
     * Make the window visible, update its client area, and
     * return "success."
     */

    ShowWindow(hWnd, nCmdShow);  /* shows window                  */
    UpdateWindow(hWnd);          /* sends WM_PAINT message        */
    return TRUE;
}

/******************************************************************
    FUNCTION: MainWndProc(HWND, UINT, WPARAM, LPARAM)

    PURPOSE:  Processes messages

    MESSAGES:

        WM_COMMAND    - application menu (About dialog box)
        WM_DESTROY    - destroy window

    COMMENTS:

        To process the IDM_ABOUT message, call MakeProcInstance
        to get the current instance address of the About procedure.
        Then call DialogBox, which will create the dialog box
        according to the information in your GENERIC.RC file and
        turn control over to the About procedure. When it returns,
        free the instance address.

*******************************************************************/




LRESULT FAR PASCAL MainWndProc(hWnd, message, wParam, lParam)
HWND hWnd;      /* window handle                                  */
UINT message;   /* type of message                                */
WPARAM wParam;  /* additional information                         */
LPARAM lParam;  /* additional information                         */
{
    FARPROC lpProcAbout; /* pointer to the "About" function       */
    switch (message) {
        case WM_COMMAND: /* message: command from a menu          */
            if (wParam == IDM_ABOUT) {
                lpProcAbout =
                    MakeProcInstance((FARPROC) About, hInst);

                DialogBox(hInst, /* handle of current instance    */
                    "AboutBox",  /* resource to use               */
                    hWnd,        /* parent handle                 */
                    (DLGPROC) lpProcAbout); /* instance address   */

                FreeProcInstance(lpProcAbout);
                break;
            }
            else               /* let Windows process it          */
                return (DefWindowProc(hWnd, message, wParam, lParam));

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

        default:        /* passes it on if unprocessed            */
            return (DefWindowProc(hWnd, message, wParam, lParam));
    }
    return NULL;
}

/******************************************************************

    FUNCTION: About(HWND, WORD, WPARAM, LPARAM)

    PURPOSE:  Processes messages for About dialog box

    MESSAGES:

        WM_INITDIALOG - initialize dialog box
        WM_COMMAND    - Input received

    COMMENTS:

        No initialization is needed for this particular dialog
        box, but TRUE must be returned to Windows.

        Wait for user to click OK; then close the dialog box.

*******************************************************************/

BOOL FAR PASCAL About(hDlg, message, wParam, lParam)
HWND hDlg;        /* handle of dialog box window                  */
WORD message;     /* type of message                              */
WPARAM wParam;    /* message-specific information                 */
LPARAM lParam;
{
    switch (message) {
        case WM_INITDIALOG:     /* message: initialize dialog box */
            return TRUE;

        case WM_COMMAND:                    /* received a command */
            if (wParam == IDOK              /* OK box selected?   */
                || wParam == IDCANCEL) {    /* Close command?     */
                EndDialog(hDlg, TRUE);      /* exits dialog box   */
                return TRUE;
            }
            break;
    }
    return FALSE;                    /* did not process a message */
}