/*--------------------------------------------------------
   HELLOWIN.C -- Displays "Hello, Windows" in client area
                 (c) Charles Petzold, 1992
  --------------------------------------------------------*/

#include <stdio.h>
#include <windows.h>
#include "macros.h"         /* Allocation Macros                */
#include <stdarg.h>         /* For error() function             */
#include <stdlib.h>         /* For memory allocation functions  */

#define DEBUG               /* To use heap check macro versions */
BOOL error(char *format, ...); /* The error message box function */

HWND hwndMain;      // main window handle

long FAR PASCAL _export WndProc (HWND, UINT, UINT, LONG) ;

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

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = NULL ;
          wndclass.lpszClassName = szAppName ;

          RegisterClass (&wndclass) ;
      }

     hwndMain = hwnd = CreateWindow (szAppName, // window class name
            "The Hello Program",             // window caption
                    WS_OVERLAPPEDWINDOW,     // window style
                    CW_USEDEFAULT,           // initial x position
                    CW_USEDEFAULT,           // initial y position
                    CW_USEDEFAULT,           // initial x size
                    CW_USEDEFAULT,           // 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 ;
     }

long FAR PASCAL _export WndProc (HWND hwnd, UINT message, UINT wParam,
                                                          LONG lParam)
     {
     HDC         hdc ;
     PAINTSTRUCT ps ;
     RECT    rect ;

     typedef char bigbuf[10000];    /* type definition for MALLOC macro  */
     bigbuf *bufp[10];              /* Store pointers returned by MALLOC */

     int i;
     
     switch (message)
          {
          case WM_PAINT:
           hdc = BeginPaint (hwnd, &ps) ;

               GetClientRect (hwnd, &rect) ;

           DrawText (hdc, "Hello, Windows!", -1, &rect,
             DT_SINGLELINE | DT_CENTER | DT_VCENTER) ;

           EndPaint (hwnd, &ps) ;
               return 0 ;

          case WM_RBUTTONDOWN:
                for (i = 0; i < 10; i++)
                {
                    error ("Going for %u", 10000 * (i+1));
                    MALLOC(bufp[i], bigbuf);
                }            


          case WM_DESTROY:
               PostQuitMessage (0) ;
               return 0 ;
          }

     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }


//
// =========== Sample error() function ==========================
//
// error() has the same types of arguments as printf() does -- to make 
// constructing of error messages easier

BOOL error(char *format, ...)
{
        va_list ap;
        char    buf [256];

        extern HWND hwndMain;       // main window handle

        
        va_start(ap, format);
        vsprintf (buf, format, ap);
        va_end(ap);

        if (MessageBox (hwndMain, buf, "Fatal error",
            MB_ICONEXCLAMATION | MB_RETRYCANCEL) == IDCANCEL)
        {                               // under Windows, exit() won't 
            DestroyWindow (hwndMain);   // destroy the window, so we have to 
            exit (1);                   // do that manually
        }
                
        return TRUE;
}
