/* menu2.cpp   graphics menu items, and changing the menu structure */

#include <windows.h>
#include "resource.h"
#include "menu2.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 */

        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  = (HBRUSH)GetStockObject (WHITE_BRUSH) ;
        wndclass.lpszMenuName   = NULL ;    /* no class menu */
        wndclass.lpszClassName  = "MyClass" ;
                        /* register the window class */
        if (!RegisterClass (&wndclass))
            return 0 ;

    hWnd = CreateWindow ("MyClass", "Menu Example 2", 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)
{
    static HBITMAP  hCut, hPaste, hArr ;
    HMENU           hMenu, hSubmenu ;
    HINSTANCE          hInstance ;
    HCURSOR         hCursor ;
    static BOOL     bAddedItems = FALSE, bSelTwoOn = FALSE ;
    static int      nCursor = ARROWCURSOR ;

    switch (wMessage)       /* process windows messages */
    {
        case WM_CREATE:     /* program starting--create menu from scratch */

                /* create a main menu and a popup menu - initially empty */
            hMenu = CreateMenu () ;
            hSubmenu = CreatePopupMenu () ;

                /* get bitmap handles from resource data */
            hInstance = (HINSTANCE)GetWindowLong (hWnd, GWL_HINSTANCE) ;
            hCut = LoadBitmap (hInstance, "CUTBMP") ;
            hPaste = LoadBitmap (hInstance, "PASTEBMP") ; 
            hArr = LoadBitmap (hInstance, "ARROWBMP") ;

                /* add to bitmap items to the popup menu */
            AppendMenu (hSubmenu, MF_BITMAP, IDM_CUT, (LPSTR) hCut) ;
            AppendMenu (hSubmenu, MF_BITMAP, IDM_PASTE, (LPSTR) hPaste) ;
            AppendMenu (hSubmenu, MF_BITMAP, IDM_ARROW, (LPSTR) hArr) ;

                /* create the first entry on the main menu, attach popup */
            AppendMenu (hMenu, MF_POPUP, (UINT)hSubmenu, "&Tools") ;

                /* add other text items to main menu */
            AppendMenu (hMenu, MF_STRING, IDM_ADD, "&Add Menu Items") ;
            AppendMenu (hMenu, MF_STRING, IDM_QUIT, "&Quit") ;
            AppendMenu (hMenu, MF_STRING, IDM_HELP, "&Help") ;

                /* attach menu to window */
            SetMenu (hWnd, hMenu) ;
            break;

        case WM_COMMAND:
            switch (LOWORD(wParam))
            {

                case IDM_ADD:       /* add new text items to menu as popup*/
                    if (!bAddedItems)
                    {
                        hMenu = GetMenu (hWnd) ;    /* get menu handle */

                            /* create new popup menu */
                        hSubmenu = CreatePopupMenu () ;

                            /* insert popup into in front of IDM_ADD */
                        InsertMenu (hMenu, IDM_ADD, MF_BYCOMMAND | MF_POPUP,
                            (UINT)hSubmenu, "Added &Popup Menu") ;

                            /* now put in two text menu items under popup */
                        AppendMenu (hSubmenu, MF_STRING | MF_CHECKED,
                            IDM_SEL1, "New Selection &1,toggles next item") ;
                        AppendMenu (hSubmenu, MF_STRING | MF_GRAYED,
                            IDM_SEL2, "New Selection &2, beeps if active") ;

                        bSelTwoOn = FALSE ;     /* keep track if on or off*/

                            /* now put in the Delete popup item */                    
                        AppendMenu (hSubmenu, MF_STRING, IDM_REMOVE,
                            "&Delete this entire popup menu.") ;

                            /*gray the "Add" menu item, as can't add twice*/
                        EnableMenuItem (hMenu, IDM_ADD,
                            MF_BYCOMMAND | MF_GRAYED) ;

                        bAddedItems = TRUE ;  /* new menu is active */

                        DrawMenuBar (hWnd) ;    /* redraw menu bar */
                    }
                    break ;

                case IDM_REMOVE:    /* menu item that removes a popup menu*/
                    hMenu = GetMenu (hWnd) ;    /* get menu handle */
                    if (bAddedItems)            /* if the popup exists */
                    {                           /* delete entire popup */
                        DeleteMenu (hMenu, 1, MF_BYPOSITION) ;
                            /* activate the "Add" menu item, can add again*/
                        EnableMenuItem (hMenu, IDM_ADD,
                            MF_BYCOMMAND | MF_ENABLED) ;
                        DrawMenuBar (hWnd) ;    /* redraw menu bar */
                        bAddedItems = FALSE ;
                    }
                    break ;

                case IDM_SEL1:      /* ID of first added menu item */
                        /* toggle item SEL2 on/off */
                    bSelTwoOn = (bSelTwoOn ? FALSE : TRUE) ;
                    hMenu = GetMenu (hWnd) ;    /* get menu handle */
                    if (bSelTwoOn)  /* ungray sel 2, uncheck sel 1 */
                    {
                        EnableMenuItem (hMenu, IDM_SEL2,
                            MF_BYCOMMAND | MF_ENABLED) ;
                        CheckMenuItem (hMenu, IDM_SEL1,
                            MF_BYCOMMAND | MF_UNCHECKED) ;
                    }
                    else            /* gray sel 2, check sel 1 */
                    {
                        EnableMenuItem (hMenu, IDM_SEL2,
                            MF_BYCOMMAND | MF_GRAYED) ;
                        CheckMenuItem (hMenu, IDM_SEL1,
                            MF_BYCOMMAND | MF_CHECKED) ;
                    }
                    break ;

                case IDM_SEL2:      /* ID of second added menu item */
                    MessageBeep (0) ;   /* just beep to prove it's active */
                    break ;

                case IDM_CUT:       /* ID of scissors bitmap menu item */
                    nCursor = CUTCURSOR ;
                    break ;

                case IDM_PASTE:
                    nCursor = GLUECURSOR ;
                    break ;

                case IDM_ARROW:
                    nCursor = ARROWCURSOR ;
                    break ;

                case IDM_HELP:
                    MessageBox (hWnd, "Try selecting any menu item.",
                        "Not much help", MB_OK) ;
                    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_SETCURSOR:              /* time to change cursor shape */
            hInstance = (HINSTANCE)GetWindowLong (hWnd, GWL_HINSTANCE) ;
            switch (nCursor)
            {
                case ARROWCURSOR:
                    hCursor = LoadCursor (NULL, IDC_ARROW) ;
                    break ;
                case CUTCURSOR:
                    hCursor = LoadCursor (hInstance, "CUTCUR") ;
                    break ;
                case GLUECURSOR:
                    hCursor = LoadCursor (hInstance, "GLUECUR") ;
                    break ;
            }
            SetCursor (hCursor) ;
            break ;

        case WM_DESTROY:                /* stop application */
            DeleteObject (hPaste) ;     /* remove bitmap data from memory */
                  DeleteObject (hCut) ;
                   DeleteObject (hArr) ;
            PostQuitMessage (0) ;
            break ;

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

    return (0) ;
}