/* mapmode1.cpp    changing mapping mode of a device context */

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

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpszCmdLine,
    int nCmdShow)
{
    HWND        hWnd ;      /* the window's "handle" */
    MSG         msg ;       /* a message structure */
    WNDCLASS    wndclass ;  /* window class structure */
    char        cBuf [128] ;/* character buffer */

        wndclass.style          = CS_HREDRAW | CS_VREDRAW ;
        wndclass.lpfnWndProc    = WndProc ;
        wndclass.cbClsExtra     = 0 ;
        wndclass.cbWndExtra     = 0 ;
        wndclass.hInstance      = hInstance ;
        wndclass.hIcon          = NULL ;
        wndclass.hCursor        = LoadCursor (NULL, IDC_ARROW) ;
        wndclass.hbrBackground  = GetStockObject (WHITE_BRUSH) ;
        wndclass.lpszMenuName   = "MYMENU" ;
        wndclass.lpszClassName  = "MyClass" ;
                        /* register the window class */
        if (!RegisterClass (&wndclass))
            return 0 ;

    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)
{
    PAINTSTRUCT     ps ;
    char            cBuf [128] ;
    static  int     nMapMode = IDM_TEXT ;
    HANDLE          hInstance ;
    
    switch (wMessage)       /* process windows messages */
    {
        case WM_COMMAND:
            switch (LOWORD(wParam))     /* menu items */
            {
                case IDM_LOMETRIC:
                    hInstance = (HINSTANCE)GetWindowLong (hWnd, GWL_HINSTANCE) ;
                    LoadString (hInstance, S_LOMETRIC, cBuf, sizeof (cBuf)) ;
                    SetWindowText (hWnd, cBuf) ;
                    nMapMode = IDM_LOMETRIC ;
                    InvalidateRect (hWnd, NULL, TRUE) ; /* force WM_PAINT */
                    break ;
                case IDM_LOENGLISH:
                    hInstance = (HINSTANCE)GetWindowLong (hWnd, GWL_HINSTANCE) ;
                    LoadString (hInstance, S_LOENGLISH, cBuf, sizeof (cBuf)) ;
                    SetWindowText (hWnd, cBuf) ;
                    nMapMode = IDM_LOENGLISH ;
                    InvalidateRect (hWnd, NULL, TRUE) ; /* force WM_PAINT */
                    break ;
                case IDM_TEXT:
                    hInstance = (HINSTANCE)GetWindowLong (hWnd, GWL_HINSTANCE) ;
                    LoadString (hInstance, S_TEXT, cBuf, sizeof (cBuf)) ;
                    SetWindowText (hWnd, cBuf) ;
                    nMapMode = IDM_TEXT ;
                    InvalidateRect (hWnd, NULL, TRUE) ; /* force WM_PAINT */
                    break ;
                case IDM_QUIT:                  /* "Quit" menu item */
                    DestroyWindow (hWnd) ;      /* destroy window, */
                    break ;                     /* terminating application */
            }
            break ;

        case WM_PAINT:
            BeginPaint (hWnd, &ps) ;
            switch (nMapMode)       /* set mapping mode of dc */
            {
                case IDM_TEXT:
                    SetMapMode (ps.hdc, MM_TEXT) ;
                    break ;
                case IDM_LOMETRIC:
                    SetMapMode (ps.hdc, MM_LOMETRIC) ;
                    break ;
                case IDM_LOENGLISH:
                    SetMapMode (ps.hdc, MM_LOENGLISH) ;
                    break ;
            }
                /* set background painting mode to transparent */
            SetBkMode (ps.hdc, TRANSPARENT) ;
                /* move window origin down/right by (100,100) pixels */
            SetViewportOrgEx (ps.hdc, 100, 100, NULL) ;
            MoveToEx (ps.hdc, 0, -40, NULL) ;  /* paint a cross for... */
            LineTo (ps.hdc, 0, 40) ;           /* the logical coord...*/
            MoveToEx (ps.hdc, -40, 0, NULL) ;  /* system origin. */
            LineTo (ps.hdc, 40, 0) ;
                /* output text and recangle at same logical location, */
                /* but the mapping mode will be different */
            Rectangle (ps.hdc, 50, 50, 200, 100) ;  
                /* load text string from resource data */
            hInstance = (HINSTANCE)GetWindowLong (hWnd, GWL_HINSTANCE) ;
            LoadString (hInstance, S_OUTTEXT, cBuf, sizeof (cBuf)) ;
            TextOut (ps.hdc, 50, 50, cBuf, lstrlen (cBuf)) ;
            EndPaint (hWnd, &ps) ;
            break ;

        case WM_DESTROY:                    /* stop application */
            PostQuitMessage (0) ;
            break ;

        default:        /* default windows message processing */
            return (DefWindowProc (hWnd, wMessage, wParam, lParam)) ;
    }
    return (0) ;
}