/* winapp2.cpp -- illustrates some basic Win32 API programming concepts */
/* Has a menu; draws a circle or rectangle; responds to mouse/keyboard input */
/* Be sure to set Project | Properties | Configuration Properties | General | Character Set: */
/* to "Use Multi-Byte Character Set" */
#include <windows.h>
#include "resource.h"
LRESULT CALLBACK WndProc (HWND hWnd, UINT wMessage,
                                    WPARAM wParam, LPARAM lParam);
int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                          LPSTR lpszCmdLine, int nCmdShow)
{
    HWND        hWnd;      /* the window's "handle" */
    MSG         msg;       /* a message structure */
    WNDCLASS    wndclass;  /* window class structure */
    wndclass.style          = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc    = WndProc;
    wndclass.cbClsExtra     = 0;
    wndclass.cbWndExtra     = 0;
    wndclass.hInstance      = hInstance;
    wndclass.hIcon          = LoadIcon (hInstance, "MYICON");
    wndclass.hCursor        = LoadCursor (NULL, IDC_ARROW);
    wndclass.hbrBackground  = (HBRUSH)GetStockObject (WHITE_BRUSH);
    wndclass.lpszMenuName   = "MYMENU";
    wndclass.lpszClassName  = "MyClass";
    /* register the window class */
    if (!RegisterClass (&wndclass))
        return 0;
    /* create the window */
    hWnd = CreateWindow ("MyClass","Second Window App", WS_OVERLAPPEDWINDOW, 
        100, 50, 400, 200, NULL, NULL, hInstance, NULL);
    ShowWindow (hWnd, nCmdShow);   /* display the window */    
    UpdateWindow (hWnd);           /* update window's client area */
    
    while (GetMessage (&msg, NULL, 0, 0))   /* message loop */
    {
        TranslateMessage (&msg);   /* translate keyboard messages */
        DispatchMessage (&msg);    /* send message to WndProc() */
    }
    return (msg.wParam);
}
LRESULT CALLBACK WndProc (HWND hWnd, UINT wMessage,
                                    WPARAM wParam, LPARAM lParam)
{
    HDC             hDC;             /* the device context handle */
    HPEN            hPen, hOldPen;   /* some drawing objects */
    HBRUSH          hBrush, hOldBrush;
    int             nXpos, nYpos;    /* mouse position */ 
    char            cBuf[]="   ";
    
    switch (wMessage)                 /* process Windows messages */
    {
    case WM_COMMAND:
        switch (LOWORD(wParam))        /* menu item selected */
        {
        case IDM_CIRCLE:
            /* draw a blue-bordered magenta-crosshatched circle */
            hDC = GetDC(hWnd);                 /* get a DC for painting */
            hPen = CreatePen (PS_SOLID, 3, RGB (0,0,255));  /* blue pen */                 
            hBrush = CreateHatchBrush (HS_DIAGCROSS, RGB (255,0,255));
            hOldPen = (HPEN)SelectObject (hDC,hPen);      /* select into DC & */ 
            hOldBrush = (HBRUSH)SelectObject (hDC, hBrush); /* save old object */
            Ellipse (hDC, 100, 30, 180, 110);       /* draw circle */
            SelectObject (hDC, hOldBrush);          /* displace brush */
            DeleteObject (hBrush);                  /* delete brush */
            SelectObject (hDC, hOldPen);            /* same for pen */
            DeleteObject (hPen);
            ReleaseDC (hWnd, hDC);   /* release the DC to end painting */
            break;
        case IDM_RECTANGLE:          
            /* draw a red-bordered, cyan-filled rectangle */
            hDC = GetDC (hWnd);                /* get a DC for painting */
            hPen = CreatePen (PS_SOLID, 3, RGB (255,0,0));   /* red pen */
            hBrush = CreateSolidBrush (RGB (0,255,255));  /* cyan brush */
            hOldPen = (HPEN)SelectObject (hDC,hPen);      /* select into DC & */    
            hOldBrush = (HBRUSH)SelectObject (hDC, hBrush); /* save old object */ 
            Rectangle (hDC, 15, 15, 80, 60);        /* draw rectangle */
            SelectObject (hDC, hOldBrush);          /* displace new brush */
            DeleteObject (hBrush);                  /* delete it from DC */
            SelectObject (hDC, hOldPen);            /* same for pen */ 
            DeleteObject (hPen);
            ReleaseDC(hWnd, hDC);                   /* get rid of DC */
            break;
        case IDM_CLEAR:      /* clear screen by forcing WM_PAINT */
            InvalidateRect (hWnd, NULL, TRUE);
            break;
        case IDM_QUIT:
            DestroyWindow (hWnd);  /* destroy window, */
            break;                 /* terminating application */
        }
        break;
        
    case WM_LBUTTONDOWN:           /* left mouse button depressed */
        nXpos = LOWORD (lParam);   /* in window's client area. */
        nYpos = HIWORD (lParam);   /* draw an L at spot */
        hDC = GetDC (hWnd);
        TextOut (hDC, nXpos, nYpos, "L", 1);
        ReleaseDC (hWnd, hDC);
        break;
    case WM_RBUTTONDOWN:           /* right mouse button depressed */
        nXpos = LOWORD (lParam);   /* in window's client area. */
        nYpos = HIWORD (lParam);   /* draw an R at spot */
        hDC = GetDC (hWnd);
        TextOut (hDC, nXpos, nYpos, "R", 1);
        ReleaseDC (hWnd, hDC);
        break;
    case WM_CHAR:                  /* keyboard character entered */            
        hDC = GetDC (hWnd);        /* display in upper left corner */  
        cBuf[0] = (char) wParam;
        TextOut (hDC, 0, 0, cBuf, strlen(cBuf));
        ReleaseDC (hWnd, hDC);
        break;
    case WM_DESTROY:               /* stop application */
        PostQuitMessage (0);
        break;
    default:                 /* default Windows message processing */
        return DefWindowProc (hWnd, wMessage, wParam, lParam);
    }
    
    return (0);
}