    /****************************************************************************/
    /*                                                                          */
    /*                 Copyright (c) Microsoft Corp.  1987, 1990                */
    /*                           All Rights Reserved                            */
    /*                                                                          */
    /****************************************************************************/
    /****************************** Module Header *******************************
    * Module Name: viewwp.c
    *
    * Contains routines that handle the View window.
    *
    * History:
    *
    * 07/17/91 -  - Created.
    *
    ****************************************************************************/
    
    #include "imagedit.h"
    #include "dialogs.h"

	 #include <windowsx.h>
    
    /*
     * Style of the view window. */
    #define VIEWSTYLE       (WS_POPUP | WS_CLIPSIBLINGS | WS_CAPTION | WS_SYSMENU)
    
    
    STATICFN VOID NEAR ViewChar(UINT uiChar);
    
    
    static INT gViewBackMargin;     // Margin of background within view window.
    
    
    
    /****************************************************************************
    * ViewCreate
    *
    * This function creates the View window.
    *
    * History:
    *
    ****************************************************************************/
    
    VOID ViewCreate(VOID)
    {
        INT x;
        INT y;
        INT cxDummy;
        INT cyDummy;
        RECT rc;
        BOOL fMaximized;
    
        gViewBackMargin = GetSystemMetrics(SM_CXVSCROLL) / 2;
    
        /*
         * Get the saved position of the Toolbox.  Note that we throw away
         * the size fields, because we will calculate the required size
         * later based on the image size.
         */
        if (!ReadWindowPos(szViewPos, &x, &y, &cxDummy, &cyDummy, &fMaximized)) {
            /*
             * The previous position of the View window couldn't be found.
             * Position the window to the right side of the editor, just
             * below the Toolbox.
             */
            if (ghwndToolbox) {
                GetWindowRect(ghwndToolbox, &rc);
                x = rc.left;
                y = rc.bottom + (2 * PALETTEMARGIN);
            }
            else {
                /*
                 * Last resort.  Position it in the upper left corner
                 * of the screen if the Toolbox cannot be found.  This
                 * is unlikely because if the previous position of the
                 * View window could not be found, this implies that
                 * the editor has not been run before on this machine.
                 * If this is true, the toolbox will come up by default
                 * before this routine is called.  But just in case...
                 */
                x = 2 * PALETTEMARGIN;
                y = 2 * PALETTEMARGIN;
            }
        }
    
        if (!(ghwndView = CreateWindow(szViewClass, NULL, VIEWSTYLE,
                x, y, 0, 0, ghwndMain, NULL, ghInst, NULL)))
            return;
    }
    
    
    
    /****************************************************************************
    * ViewShow
    *
    * This function shows or hides the view window.
    *
    * History:
    *
    ****************************************************************************/
    
    VOID ViewShow(
        BOOL fShow)
    {
        if (fShow) {
            /*
             * Only show it if there is an image to display!
             */
            if (gpImageCur)
                ShowWindow(ghwndView, SW_SHOWNA);
        }
        else {
            ShowWindow(ghwndView, SW_HIDE);
        }
    }
    
    
    
    /****************************************************************************
    * ViewUpdate
    *
    * This function updates the view window.  It should be called any time that
    * the image changes (is drawn upon).
    *
    * History:
    *
    ****************************************************************************/
    
    VOID ViewUpdate(VOID)
    {
        InvalidateRect(ghwndView, NULL, TRUE);
    
        /*
         * Update the workspace window also, because it must always
         * match the state of the View window.
         */
        WorkUpdate();
    }
    
    
    
    /****************************************************************************
    * ViewReset
    *
    * This function resets the view window, sizing it to fit a new
    * image.  It should be called any time that the current image
    * is changed to another one.
    *
    * History:
    *
    ****************************************************************************/
    
    VOID ViewReset(VOID)
    {
        RECT rc;
        RECT rcT;
    
        GetWindowRect(ghwndView, &rc);
    
        rcT.left = 0;
        rcT.top = 0;
        rcT.right = PALETTEMARGIN + gViewBackMargin +
                gpImageCur->cx + gViewBackMargin + PALETTEMARGIN;
        rcT.bottom = PALETTEMARGIN + gViewBackMargin +
                gpImageCur->cy + gViewBackMargin + PALETTEMARGIN;
        AdjustWindowRect(&rcT, VIEWSTYLE, FALSE);
    
        rc.right = rc.left + (rcT.right - rcT.left);
        rc.bottom = rc.top + (rcT.bottom - rcT.top);
        FitRectToScreen(&rc);
    
        SetWindowPos(ghwndView, NULL, rc.left, rc.top,
                rc.right - rc.left, rc.bottom - rc.top,
                SWP_NOACTIVATE | SWP_NOZORDER);
    
        /*
         * If the user wants it, show the View window now.
         */
        if (gfShowView)
            ViewShow(TRUE);
    
        ViewUpdate();
    
        /*
         * Clear out the propbar size and position fields, because they
         * probably show the wrong information now.
         */
        PropBarClearPos();
        PropBarClearSize();
    }
    
    
    
    /****************************************************************************
    * ViewWndProc
    *
    * This is the window procedure for the view window.
    *
    * History:
    *
    ****************************************************************************/
    
    WINDOWPROC ViewWndProc(
        HWND hwnd,
        UINT msg,
        WPARAM wParam,
        LPARAM lParam)
    {
        switch (msg) {
            case WM_CREATE:
                {
                    HMENU hmenu = GetSystemMenu(hwnd, FALSE);
    
                    RemoveMenu(hmenu, 7, MF_BYPOSITION);    // Second separator.
                    RemoveMenu(hmenu, 5, MF_BYPOSITION);    // First separator.
    
                    RemoveMenu(hmenu, SC_RESTORE, MF_BYCOMMAND);
                    RemoveMenu(hmenu, SC_SIZE, MF_BYCOMMAND);
                    RemoveMenu(hmenu, SC_MINIMIZE, MF_BYCOMMAND);
                    RemoveMenu(hmenu, SC_MAXIMIZE, MF_BYCOMMAND);
                    RemoveMenu(hmenu, SC_TASKLIST, MF_BYCOMMAND);
                }
    
                return 0;
    
            case  WM_PAINT:
                {
                    HDC hdc;
                    PAINTSTRUCT ps;
                    HBRUSH hbrOld;
                    RECT rc;
    
                    hdc = BeginPaint(hwnd, &ps);
    
                    /*
                     * The view window should not be showing if there
                     * is not an image to view!
                     */
                    if (gpImageCur) {
                        DrawMarginBorder(hwnd, hdc);
    
                        GetClientRect(hwnd, &rc);
                        hbrOld = SelectObject(hdc, ghbrScreen);
                        PatBlt(hdc, PALETTEMARGIN + 1, PALETTEMARGIN + 1,
                                rc.right - (PALETTEMARGIN * 2) - 2,
                                rc.bottom - (PALETTEMARGIN * 2) - 2,
                                PATCOPY);
                        SelectObject(hdc, hbrOld);
    
                        BitBlt(hdc, PALETTEMARGIN + gViewBackMargin,
                                PALETTEMARGIN + gViewBackMargin,
                                gcxImage, gcyImage, ghdcImage, 0, 0, SRCCOPY);
                    }
    
                    EndPaint(hwnd, &ps);
                }
    
                break;
    
            case WM_ACTIVATE:
                if (GET_WM_ACTIVATE_STATE(wParam, lParam))
                    gidCurrentDlg = DID_VIEW;
    
                break;
    
            case WM_LBUTTONDOWN:
                SetScreenColor(gargbCurrent[giColorLeft]);
                break;
    
            case WM_CHAR:
                ViewChar(wParam);
                break;
    
            case WM_CLOSE:
                /*
                 * The user closed the view window from the system menu.
                 * Hide the window (we don't actually destroy it so
                 * that it will appear in the same spot when they show
                 * it again).
                 */
                ViewShow(FALSE);
                gfShowView = FALSE;
                break;
    
            case WM_DESTROY:
                {
                    RECT rc;
    
                    /*
                     * Save the position of the toolbox.
                     */
                    GetWindowRect(hwnd, &rc);
                    WriteWindowPos(&rc, FALSE, szViewPos);
    
                    /*
                     * Null out the global window handle for the view window
                     * for safety's sake.
                     */
                    ghwndView = NULL;
                }
    
                break;
    
            default:
                return DefWindowProc(hwnd, msg, wParam, lParam);
        }
    
        return 0;
    }
    
    
    
    /************************************************************************
    * ViewChar
    *
    * Handles WM_CHAR messages for the view window.  Currently this just
    * includes the '+' and '-' keys, which are used to cycle through all
    * the possible screen colors.
    *
    * Arguments:
    *
    * History:
    *
    ************************************************************************/
    
    STATICFN VOID NEAR ViewChar(
        UINT uiChar)
    {
        INT i;
        INT iNext;
    
        switch (uiChar) {
            /*
             * Advance to the next screen color.
             */
            case '+':
                iNext = 0;
                for (i = 0; i < 16; i++) {
                    if (grgbScreen == gargbDefaultColor[i]) {
                        iNext = i + 1;
                        break;
                    }
                }
    
                if (iNext >= 16)
                    iNext = 0;
    
                SetScreenColor(gargbDefaultColor[iNext]);
    
                break;
    
            /*
             * Back up to the prior screen color.
             */
            case '-':
                iNext = 16 - 1;
                for (i = 0; i < 16; i++) {
                    if (grgbScreen == gargbDefaultColor[i]) {
                        iNext = i - 1;
                        break;
                    }
                }
    
                if (iNext < 0)
                    iNext = 16 - 1;
    
                SetScreenColor(gargbDefaultColor[iNext]);
    
                break;
        }
    }
    
    
    
    /****************************************************************************
    * ViewSetPixel
    *
    * This function colors a pixel in the View window directly.  It is
    * provided as an optimization when drawing a point.  The ghdcImage
    * bitmap must be updated as well or the image on the screen will
    * get out of synch with it.
    *
    * History:
    *
    ****************************************************************************/
    
    VOID ViewSetPixel(
        INT x,
        INT y,
        INT nBrushSize)
    {
        HDC hDC;
        HBRUSH hbrOld;
        INT Size;
        INT SizeX;
        INT SizeY;
    
        hDC = GetDC(ghwndView);
        hbrOld = SelectObject(hDC, ghbrDrawSolid);
        SizeX = x - nBrushSize / 2;
        SizeY = y - nBrushSize / 2;
        PatBlt(hDC, PALETTEMARGIN + gViewBackMargin + (SizeX >= 0 ? SizeX : 0),
                PALETTEMARGIN + gViewBackMargin + (SizeY >=  0 ? SizeY :  0),
                ((Size = gcxImage - SizeX) >= nBrushSize ?
                nBrushSize : Size),
                ((Size = gcyImage - SizeY) >= nBrushSize ?
                nBrushSize : Size), PATCOPY);
        SelectObject(hDC, hbrOld);
        ReleaseDC(ghwndView, hDC);
    }
    
    
    
    /****************************************************************************
    * DrawMarginBorder
    *
    *
    * History:
    *
    ****************************************************************************/
    
    VOID DrawMarginBorder(
        HWND hwnd,
        HDC hdc)
    {
        HBRUSH hbrOld;
        HPEN hpenOld;
        RECT rc;
    
        GetClientRect(hwnd, &rc);
        hpenOld = SelectObject(hdc, GetStockObject(BLACK_PEN));
        hbrOld = SelectObject(hdc, GetStockObject(NULL_BRUSH));
        Rectangle(hdc, PALETTEMARGIN, PALETTEMARGIN,
                rc.right - PALETTEMARGIN,
                rc.bottom - PALETTEMARGIN);
        SelectObject(hdc, hpenOld);
        SelectObject(hdc, hbrOld);
    }
    
    
    
    /****************************************************************************
    * DrawSunkenRect
    *
    *
    * History:
    *
    ****************************************************************************/
    
    VOID DrawSunkenRect(
        PRECT prc,
        HDC hdc)
    {
        HPEN hpenOld;
    
        hpenOld = SelectObject(hdc, hpenDarkGray);
        MoveToEx(hdc, prc->left, prc->top, NULL);
        LineTo(hdc, prc->right - 1, prc->top);
        MoveToEx(hdc, prc->left, prc->top, NULL);
        LineTo(hdc, prc->left, prc->bottom - 1);
    
        SelectObject(hdc, GetStockObject(WHITE_PEN));
        MoveToEx(hdc, prc->left + 1, prc->bottom - 1, NULL);
        LineTo(hdc, prc->right, prc->bottom - 1);
        MoveToEx(hdc, prc->right - 1, prc->top + 1, NULL);
        LineTo(hdc, prc->right - 1, prc->bottom - 1);
    
        SelectObject(hdc, hpenOld);
    }
