/*
 * BCDEMO.C
 *
 * Main entry code for application.
 *
 * Copyright (c)1992-1994 Microsoft Corporation, All Right Reserved
 */

#include <windows.h>
#include <bttncur.h>
#include "bcdemo.h"


//Array of the possible button styles.
UINT        rguState[6]={COMMANDBUTTON_UP
                        , COMMANDBUTTON_MOUSEDOWN
                        , COMMANDBUTTON_DISABLED
                        , ATTRIBUTEBUTTON_DOWN
                        , ATTRIBUTEBUTTON_DOWNDISABLED
                        , ATTRIBUTEBUTTON_INDETERMINATE
                        };


//Strings describing the possible states for labelling button rows.
TCHAR *     rgpsz[6]={TEXT("Up"), TEXT("Mouse Down")
                     , TEXT("Disabled"), TEXT("Down")
                     , TEXT("Down Disabled"), TEXT("Indeterminate")
                     };


//More strings we'll use as labels.
TCHAR szStandard[]=TEXT("Standard Buttons");
TCHAR szApp[]=TEXT("App-defined Buttons");
TCHAR szMsg[]=TEXT("Down, Down Disabled, and  Indeterminate states are not\
 valid  on standard command buttons.");





/*
 * WinMain
 *
 * Purpose:
 *  Main entry point of application.
 */

int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hInstPrev
    , LPSTR pszCmdLine, int nCmdShow)
    {
    MSG         msg;
    BOOL        fSuccess=TRUE;
    PAPPVARS    pAV;

    //Attempt to allocate and initialize the application
    pAV=AppPAllocate(&fSuccess, hInst, hInstPrev, pszCmdLine
        , nCmdShow);

    if (NULL==pAV || !fSuccess)
        {
        AppPFree(pAV);
        return 0;
        }

    while (GetMessage(&msg, NULL, 0,0 ))
        {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
        }

    AppPFree(pAV);
    return msg.wParam;
    }





/*
 * BCDemoWndProc
 *
 * Purpose:
 *  Window class procedure.  Standard callback.
 */

LONG WINAPI BCDemoWndProc(HWND hWnd, UINT iMsg, WPARAM wParam
    , LPARAM lParam)
    {
    PAPPVARS    pAV;
    WORD        wID;
    WORD        wCode;
    HWND        hWndMsg;
    PAINTSTRUCT ps;
    RECT        rc;
    HBITMAP     hBmp;
    HPEN        hPen, hPenT;
    HCURSOR     hCur;
    int         i, j;
    int         x, y;

    hWndMsg=(HWND)(UINT)lParam;
    wID=LOWORD(wParam);
   #ifdef WIN32
    wCode=HIWORD(wParam);
   #else
    wCode=HIWORD(lParam);
   #endif

    pAV=(PAPPVARS)GetWindowLong(hWnd, 0);

    switch (iMsg)
        {
        case WM_NCCREATE:
            pAV=(PAPPVARS)((LONG)((LPCREATESTRUCT)lParam)
                ->lpCreateParams);
            SetWindowLong(hWnd, 0, (LONG)pAV);
            return (DefWindowProc(hWnd, iMsg, wParam, lParam));

        case WM_DESTROY:
            PostQuitMessage(0);
            break;


        case WM_PAINT:
            //Draw all the standard and app-defined buttons for show.
            BeginPaint(hWnd, &ps);
            GetClientRect(hWnd, &rc);

            //Draw labels on the rows.  The pen is for drawing lines.
            SetTextColor(ps.hdc, GetSysColor(COLOR_WINDOWTEXT));
            SetBkColor(ps.hdc, GetSysColor(COLOR_WINDOW));
            SetBkMode(ps.hdc, OPAQUE);

            TextOut(ps.hdc, 8, 0, szStandard, lstrlen(szStandard));

            x=(TOOLIMAGE_MAX+1)*(5+pAV->tdd.cxButton);
            TextOut(ps.hdc, x, 0, szApp, lstrlen(szApp));


            //Pen is for drawing lines.
            hPen=CreatePen(PS_SOLID, 1
                , GetSysColor(COLOR_WINDOWTEXT));
            hPenT=SelectObject (ps.hdc, hPen);

            //Draw a horizontal separator line between text & buttons
            MoveToEx(ps.hdc, 0, pAV->tdd.cyButton-4, NULL);
            LineTo(ps.hdc, rc.right-rc.left, pAV->tdd.cyButton-4);

            /*
             * Draw a vertical separator line between standard and
             * app buttons.
             */
            x-=2;
            y=pAV->tdd.cyButton+((5+pAV->tdd.cyButton)*6);

            MoveToEx(ps.hdc, x, 0, NULL);
            LineTo(ps.hdc, x, y);

            SelectObject(ps.hdc, hPenT);
            DeleteObject(hPen);


            /*
             * Final label--show a message stating that the three
             * attribute-only states are not available for standard
             * command buttons.  We use the x & y we calculated for
             * lines to position the text.
             */
            SetRect(&rc, 0, y-((5+pAV->tdd.cyButton)*3), x, y);
            DrawText(ps.hdc, szMsg, lstrlen(szMsg), &rc
                , DT_CENTER | DT_WORDBREAK);


            //Get the application-defined images.
            hBmp=LoadBitmap(pAV->hInst,MAKEINTRESOURCE(pAV->idrBmp));

            //Now start drawing buttons.
            for (i=0; i<6; i++)
                {
                y=pAV->tdd.cyButton+((5+pAV->tdd.cyButton)*i);

                for (j=TOOLIMAGE_MIN; j<=TOOLIMAGE_MAX; j++)
                    {
                    /*
                     * Draw a standard button (NULL in hBmp).  If
                     * we fail, like we're attempting to draw an
                     * unsupported state on a command button,
                     * nothing appears.
                     */
                    UIToolButtonDrawTDD(ps.hdc
                         , j*(5+pAV->tdd.cxButton) , y
                         , pAV->tdd.cxButton, pAV->tdd.cyButton
                         , NULL, 0, 0, j, rguState[i], &pAV->tdd);
                    }


                //Now draw two app-defined bitmaps in the same row.
                for (j=0; j<=1; j++)
                    {
                    /*
                     * Draw an application-defined button using
                     * indices 0 and 1 (a computer and a phone).
                     * Adding TOOLIMAGE_MAX+1 to j places these
                     * buttons at the ends of the existing rows of
                     * standard buttons.  These are 4 pixels larger
                     * in each direction over the standard size.
                     */
                    UIToolButtonDrawTDD(ps.hdc, (j+TOOLIMAGE_MAX+1)
                        *(5+pAV->tdd.cxButton), y
                        , pAV->tdd.cxButton+4 , pAV->tdd.cyButton+4
                        , hBmp , pAV->tdd.cxImage, pAV->tdd.cyImage
                        , j , rguState[i], &pAV->tdd);
                    }

                /*
                 * Label the row with the state it shows.
                 *
                 * TOOLIMAGE_MAX+3 is the number of buttons.  +5 on
                 * width provides some spacing.  +4 on position
                 * spaces the text from the buttons a little.
                 */

                x=8+(TOOLIMAGE_MAX+3)*(5+pAV->tdd.cxButton);
                TextOut(ps.hdc, x, y, rgpsz[i], lstrlen(rgpsz[i]));
                }

            EndPaint(hWnd, &ps);
            DeleteObject(hBmp);
            break;


        case WM_COMMAND:
            //Restore the original cursor.
            if (IDM_NORMALCURSOR==wID)
                {
                hCur=LoadCursor(NULL, IDC_ARROW);
               #ifdef WIN32
                SetClassLong(hWnd, GCL_HCURSOR, (LONG)hCur);
               #else
                SetClassWord(hWnd, GCW_HCURSOR, (UINT)hCur);
               #endif
                }

            //Set a cursor from BTTNCUR.DLL.
            if (wID >= IDC_NEWUICURSORMIN
                && wID <= IDC_NEWUICURSORMAX)
                {
                /*
                 * Retrieve a new cursor and set it as the class
                 * cursor of our main window.
                 */
                hCur=UICursorLoad((UINT)wID);

                if (NULL!=hCur)
                    {
                   #ifdef WIN32
                    SetClassLong(hWnd, GCL_HCURSOR, (LONG)hCur);
                   #else
                    SetClassWord(hWnd, GCW_HCURSOR, (UINT)hCur);
                   #endif
                    }
                }
            break;

        default:
            return (DefWindowProc(hWnd, iMsg, wParam, lParam));
        }

    return 0L;
    }
