/* bitmap3.c   demonstration of 15 raster operation codes */

#include <windows.h>
#include "bitmap3.h"

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 */
    char        cBuf [128] ;

        wndclass.style          = CS_HREDRAW | CS_VREDRAW ;
        wndclass.lpfnWndProc    = WndProc ;
        wndclass.cbClsExtra     = 0 ;
        wndclass.cbWndExtra     = 0 ;
        wndclass.hInstance      = hInstance ;
        wndclass.hIcon          = LoadIcon (NULL, NULL) ;
        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 ;

        /* get program caption from string table resource */
    LoadString (hInstance, S_PROGRAMCAPTION, cBuf, sizeof (cBuf)) ;
    
    hWnd = CreateWindow ("MyClass", cBuf, WS_OVERLAPPEDWINDOW, 
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 
        NULL, NULL, hInstance, NULL) ;
    ShowWindow (hWnd, nCmdShow) ;   /* display the window */    
    UpdateWindow (hWnd) ;

    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, hMemDC ;
    HBITMAP         hBitmap ;
    HBRUSH          hBrush, hOldBrush ;
    HANDLE          hInstance ;
    PAINTSTRUCT     ps ;
    static int      nXclient, nYclient ;
    static DWORD    dwRasterOp [15] = {BLACKNESS, DSTINVERT, MERGECOPY, 
        MERGEPAINT, NOTSRCCOPY, NOTSRCERASE, PATCOPY, PATINVERT, PATPAINT, 
        SRCAND, SRCCOPY, SRCERASE, SRCINVERT, SRCPAINT, WHITENESS} ;
        /* these are predefined Windows rasterop constants */
    int i, j ;
    
    switch (wMessage)       /* process windows messages */
    {
        case WM_COMMAND:
            switch (LOWORD(wParam))
            {
                case IDM_SHOW:  /* paint color striped bitmap 15 times */
                                                                /* using a blue hatched brush */
                    hInstance = (HINSTANCE)GetWindowLong (hWnd, GWL_HINSTANCE) ;
                    hBitmap = LoadBitmap (hInstance, "COLORSBMP") ;
                    hDC = GetDC (hWnd) ;
                    SelectObject (hDC, GetStockObject (ANSI_VAR_FONT)) ;
                    hBrush = CreateHatchBrush(HS_DIAGCROSS, RGB (0,0,255)) ;
                    hOldBrush = (HBRUSH)SelectObject (hDC, hBrush) ;
                    hMemDC = CreateCompatibleDC (hDC) ;
                    SelectObject (hMemDC, hBitmap) ;  /*colors.bmp*/
                    for (i = 0 ; i < 5 ; i++)
                    {
                        for (j = 0 ; j < 3 ; j++)
                        {
                            BitBlt (hDC, 90 * i, 100 * j, 32, 32, 
                                hMemDC, 0, 0, dwRasterOp [i + (5*j)] ) ;
                            StringAtPoint (hDC, hInstance, 90 * i, 
                                50 + (100 * j),
                                S_BLACKNESS + i + (5 * j)) ;
                        }
                    }
                    SelectObject (hDC, hOldBrush) ;
                    DeleteObject (hBrush) ;
                    DeleteDC (hMemDC) ;
                    ReleaseDC (hWnd, hDC) ;
                    DeleteObject (hBitmap) ;
                    break ;
                case IDM_QUIT:              /* Quit menu item */
                    DestroyWindow (hWnd) ;  /* destroy window, */
                    break ;     /* terminating application */
                default:        /* otherwise, let Windows process it */
                    return (DefWindowProc (hWnd, wMessage, wParam, lParam)) ;
            }
            break ;
        case WM_SIZE:
            nXclient = LOWORD (lParam) ;
            nYclient = HIWORD (lParam) ;
            break ;
        case WM_PAINT:   /* paint brick pattern on whole client area */
            BeginPaint (hWnd, &ps) ;
            hInstance = (HINSTANCE)GetWindowLong (hWnd, GWL_HINSTANCE) ;
            hBitmap = LoadBitmap (hInstance, "BRICKBRUSH") ;
            hBrush = CreatePatternBrush (hBitmap) ;
            hOldBrush = (HBRUSH)SelectObject (ps.hdc, hBrush) ;
            PatBlt (ps.hdc, 0, 0, nXclient, nYclient, PATCOPY) ;
            SelectObject (ps.hdc, hOldBrush) ;
            DeleteObject (hBrush) ;
            EndPaint (hWnd, &ps) ;
            DeleteObject (hBitmap) ;
            break ;
        case WM_DESTROY:    /* stop application */
            PostQuitMessage (0) ;
            break ;
        default:        /* default windows message processing */
            return (DefWindowProc (hWnd, wMessage, wParam, lParam)) ;
    }
    return (0) ;
}

/* display a string table entry at an X,Y location on a DC */

void StringAtPoint (HDC hDC, HINSTANCE hInstance, int nX, int nY, int nString) 
{
    char    cBuf [128] ;
                        /* get string from string table resource */
    LoadString (hInstance, nString, cBuf, sizeof (cBuf)) ;
    TextOut (hDC, nX, nY, cBuf, lstrlen (cBuf)) ;
}