#include <windows.h>
#include "demo.h"
#include "animate.h"

HANDLE hInst;                       //current instance
HANDLE hwndMain;                    //handle to main window

BOOL InitApplication(HANDLE hInstance);
BOOL InitInstance(HANDLE hInstance, int nCmdShow);
BOOL FAR PASCAL About(HWND hDlg, unsigned message, WORD wParam, LONG lParam);
long FAR PASCAL MainWndProc(HWND hWnd, UINT message, WPARAM wParam,
                            LPARAM lParam);


/****************************************************************************
    FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int)
    PURPOSE: calls initialization function, processes message loop
****************************************************************************/
int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance,
                   LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;

    if (!hPrevInstance)                  //Other instances of app running?
        if (!InitApplication(hInstance)) //Initialize shared things
            return (FALSE);              //Exits if unable to initialize
        //Perform initializations that apply to a specific instance
    if (!InitInstance(hInstance, nCmdShow))
        return (FALSE);
        //Acquire and dispatch messages until a WM_QUIT message is received.
    while (GetMessage(&msg,        //message structure
            NULL,                  //handle of window receiving the message
            NULL,                  //lowest message to examine
            NULL))                 //highest message to examine
    {
        TranslateMessage(&msg);    //Translates virtual key codes
        DispatchMessage(&msg);     //Dispatches message to window
    } //End while (not a quit message)
    return (msg.wParam);           //Returns the value from PostQuitMessage
} //End function (WinMain)
/****************************************************************************
    FUNCTION: InitApplication(HANDLE)
    PURPOSE: Initializes window data and registers window class
****************************************************************************/
BOOL InitApplication(HANDLE hInstance)
{
WNDCLASS  wc;

        //Fill in window class structure with parameters that describe the
        //main window.
    wc.style = NULL;                    //Class style(s).
    wc.lpfnWndProc = MainWndProc;       //Function to retrieve messages for
                                        //windows of this class.
    wc.cbClsExtra = 0;                  //No per-class extra data.
    wc.cbWndExtra = 0;                  //No per-window extra data.
    wc.hInstance = hInstance;           //Application that owns the class.
    wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(DEMO));
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName  = "DEMOMenu";	 /* Name of menu resource in .RC file. */
    wc.lpszClassName = "AnimateWClass"; //Name used in call to CreateWindow.

        //Register the window class and return success/failure code.
    return (RegisterClass(&wc));
} //End function (InitApplication)

HANDLE ThreadHand;
    static char Instructions[] = 
        "               This is the BOUNDS_CHECKER32/NT demo.  Click on Start to see "
    	"our fearless mascots engage in a very dangerous activity, almost "
	"as dangerous as WIN32 programming without BOUNDS_CHECKER32/NT."
        "               This is the BOUNDS_CHECKER32/NT demo.";







#ifdef one












DWORD ThreadFunc(HANDLE hInstance)
{
    HWND hEdit;
    int Count;

    hEdit = CreateWindow(
        "EDIT",
	Instructions,
	WS_CHILD | WS_VISIBLE | WS_BORDER,
	200, 5,
	250, 30,
	hwndMain,
	101,
	hInstance,
	NULL
        );

    UpdateWindow(hEdit);
    ShowWindow(hEdit, SW_SHOW);

    Count = 0;
    do
    {
        Sleep(100);
	Count++;
	if (Count > strlen(Instructions)-37) Count = 16;
	SetWindowText(hEdit, Instructions[Count]);
	UpdateWindow(hEdit);
    } while (1);

    MessageBox(NULL, "Box", "Message", MB_OK);

    return 0;
}












#else










DWORD ThreadFunc(HANDLE hInstance)
{
    HWND hEdit;
    int Count;

    hEdit = CreateWindow(
        "EDIT",
	Instructions,
	WS_CHILD | WS_VISIBLE | WS_BORDER,
	200, 5,
	250, 30,
	hwndMain,
	101,
	hInstance,
	NULL
        );

    UpdateWindow(hEdit);
    ShowWindow(hEdit, SW_SHOW);

    Count = 0;
    do
    {
        Sleep(100);
	Count++;
	if (Count > strlen(Instructions)-37) Count = 16;
	SetWindowText(hEdit, &Instructions[Count]);
	UpdateWindow(hEdit);
    } while (1);

    MessageBox(NULL, "Box", "Message", MB_OK);

    return 0;
}











#endif










/****************************************************************************
    FUNCTION:  InitInstance(HANDLE, int)
    PURPOSE:  Saves instance handle and creates main window
****************************************************************************/
BOOL InitInstance(HANDLE hInstance, int nCmdShow)
{
    HWND hWnd;
    DWORD ThreadId;


#if defined(one) || defined(two)
    if (MessageBox(NULL, "Warning -- This program is intended "
        "to demonstrate the error catching ability of BOUNDS-CHECKER32/NT.  "
        "When run without BOUNDS-CHECKER32/NT, this program will terminate "
        "with a processor exception.", 
        "BCHK32/NT Demo", MB_ICONHAND | MB_OKCANCEL) == IDCANCEL)
    {
        ExitProcess(0);
    }
        
#endif

        //Save the instance handle in static variable, which will be used in
        //many subsequence calls from this application to Windows.
    hInst = hInstance;
        //Create a main window for this application instance.
    hWnd = hwndMain = CreateWindow(
        "AnimateWClass",                // See RegisterClass() call.
	"Nu-Mega Technologies Demo",	// Text for window title bar.
        WS_OVERLAPPEDWINDOW|WS_CLIPCHILDREN,            // Window style.
        CW_USEDEFAULT,                  // Default horizontal position.
        CW_USEDEFAULT,                  // Default vertical position.
	500,				// Default width.
	230,				// Default height.
        NULL,                           // Overlapped windows have no parent.
        NULL,                           // Use the window class menu.
        hInstance,                      // This instance owns this window.
        NULL                            // Pointer not needed.
    );
        //If window could not be created, return "failure"
    if (!hWnd)
        return (FALSE);
        //Make the window visible; update its client area; and return "success"
    ShowWindow(hWnd, nCmdShow);  //Show the window
    UpdateWindow(hWnd);          //Sends WM_PAINT message


    ThreadHand = CreateThread(NULL, 4096, (LPTHREAD_START_ROUTINE)ThreadFunc, NULL, hInstance, &ThreadId);

    return (TRUE);               //Returns the value from PostQuitMessage
} //End function (InitInstance)










#if defined(three)










/****************************************************************************
    FUNCTION: PaintBmp(LONG)
    PURPOSE:  Processes messages
****************************************************************************/

VOID PaintBmp(HWND hWnd, LPSTR lpBitMap, int x, int y)
{

HDC hDC, hdcMemory;				 //
HBITMAP hbmpMyBitmap, hbmpOld;
BITMAP bm;

		    hbmpMyBitmap = LoadBitmap(hInst, lpBitMap);
		    GetObject(hbmpMyBitmap, sizeof(BITMAP), &bm);

		    hDC = GetDC(hWnd);
		    hdcMemory = CreateCompatibleDC(hDC);
		    hbmpOld = SelectObject(hdcMemory, hbmpMyBitmap);

		    BitBlt(hDC, x, y, bm.bmWidth, bm.bmHeight, hdcMemory, 0, 0, SRCCOPY);
		    SelectObject(hdcMemory, hbmpOld);

		    DeleteDC(hdcMemory);
		    ReleaseDC(hWnd, hDC);
}










#elif defined(one) || defined(two)










/****************************************************************************
    FUNCTION: PaintBmp(LONG)
    PURPOSE:  Processes messages
****************************************************************************/

VOID PaintBmp(HWND hWnd, LPSTR lpBitMap, int x, int y)
{

HDC hDC, hdcMemory;				 //
HBITMAP hbmpMyBitmap, hbmpOld;
BITMAP bm;

		    hbmpMyBitmap = LoadBitmap(hInst, lpBitMap);
		    GetObject(hbmpMyBitmap, sizeof(BITMAP), &bm);

		    hDC = GetDC(hWnd);
		    hdcMemory = CreateCompatibleDC(hDC);
		    hbmpOld = SelectObject(hdcMemory, hbmpMyBitmap);

		    BitBlt(hDC, x, y, bm.bmWidth, bm.bmHeight, hdcMemory, 0, 0, SRCCOPY);
		    SelectObject(hdcMemory, hbmpOld);

		    DeleteObject(hbmpMyBitmap);
		    DeleteDC(hdcMemory);
		    ReleaseDC(hWnd, hDC);
}










#endif
#if defined(one) || defined(two)










/****************************************************************************
    FUNCTION: MainWndProc(HWND, unsigned, WORD, LONG)
    PURPOSE:  Processes messages
****************************************************************************/
HANIMATION hAnimation;
WORD wFrameCount = 0;
//USER DEFINED SECTION - CHANGE THE FILENAME AND NUMBER OF FRAMES TO MATCH
//YOUR OWN ANIMATION
char gszFrameFile[] = "arrow.bmp";
BOOL Repeat = FALSE;
BOOL NoError = TRUE;
#define MAXFRAMES  15
long FAR PASCAL MainWndProc(HWND hWnd, UINT message, WPARAM wParam,
                            LPARAM lParam)
{
FARPROC lpProcAbout;
static RECT rtDest;                   //Where to play the frames
HDC hDC;					 //
int Temp;
char NextCount[16] = {0x10,0x0F,0x0E,0x0D,0x0C,0x0B,0x0A,0x9,0x8,0x7,0x6,0x5,0x4,0x3,0x2,0x1};
char Xmessage[11];


    Temp = NextCount[1];
    switch (message)
    {
        case WM_COMMAND:
            switch (wParam) {
                case IDM_ABOUT:
                    lpProcAbout = MakeProcInstance(About, hInst);
                    DialogBox(hInst,                 //current instance
                        "AboutBox",                  //resource to use
                        hWnd,                        //parent handle
                        lpProcAbout);                //About() instance address
                    FreeProcInstance(lpProcAbout);
                    break;
		case IDM_START:
		    //Set the frame rate to 10 frames/second
		    //	  SetTimer (1234, 1, 100, NULL);
			  SetTimer (hWnd, 1, 100, NULL);
		    if (wFrameCount != 0)
			{
			  wFrameCount = 0;
			  PaintBmp(hWnd, "Pshoot", 0, 0);
			  PaintBmp(hWnd, "Papple", 268, 36);
			  anDisplayFrame (hAnimation, hDC=GetDC(hWnd), wFrameCount, 50,
			     64 - FRAMEHEIGHT);
			  ReleaseDC (hWnd, hDC);
			}
		    break;
		case IDM_REPEAT:
			if (Repeat)
				Repeat = FALSE;
			else
				Repeat = TRUE;
			break;
                default:
                    return (DefWindowProc(hWnd, message, wParam, lParam));
            } //End switch (wParam)
            break;
        case WM_CREATE:
                //Window dimensions
            GetClientRect (hWnd, (LPRECT)&rtDest);
            if ((hAnimation = anInit (gszFrameFile, MAXFRAMES))==NULL)
            {   MessageBox(hWnd, "Error loading animation","",MB_ICONEXCLAMATION);
                break;
            } //End if (failed to initialize animation)
            break;
        case WM_DESTROY:
                //clean up
	    TerminateThread(ThreadHand, 0);
            anClose (hAnimation);
            PostQuitMessage(0);
            break;
        case WM_TIMER:
                //Display the next frame in the animation
	    if (wFrameCount == 7)
	    strcpy(Xmessage,"Animation error, Stopping");
	    if (wFrameCount == MAXFRAMES-1)
		{
		    PaintBmp(hWnd, "Parrow", 268, 36);
		    PaintBmp(hWnd, "Pshoot", 0, 0);
		    if (Repeat == FALSE)
			{
			   KillTimer (hWnd, 1);
			}
		    else
			{
			   PostMessage (hWnd, WM_COMMAND, IDM_START, 0);
			}
		 } // end if
	    else
		 {
		if (NoError)
			{
	    if (anDisplayFrame (hAnimation, hDC=GetDC(hWnd), wFrameCount, 60,
			     64 - FRAMEHEIGHT) < 0)
	    {
			   KillTimer (hWnd, 1);
			   NoError = FALSE;
			   MessageBox(hWnd, Xmessage,"",MB_ICONEXCLAMATION);
            } //End if (animation error)
            ReleaseDC (hWnd, hDC);
	      Temp = (MAXFRAMES - wFrameCount);
	    wFrameCount = NextCount[Temp];
			} //endif noerror
		  } // end of else
            break;
	case WM_PAINT:
		    PaintBmp(hWnd, "Pshoot", 0, 0);
		    PaintBmp(hWnd, "Papple", 268, 36);
		    anDisplayFrame (hAnimation, hDC=GetDC(hWnd), wFrameCount, 50,
		       64 - FRAMEHEIGHT);
		    ReleaseDC (hWnd, hDC);
		    DefWindowProc(hWnd, message, wParam, lParam);
	    break;
        default:
            return (DefWindowProc(hWnd, message, wParam, lParam));
    } //End switch (message)
    return (NULL);
} //End function (MainWndProc)










#elif defined(three)










/****************************************************************************
    FUNCTION: MainWndProc(HWND, unsigned, WORD, LONG)
    PURPOSE:  Processes messages
****************************************************************************/
HANIMATION hAnimation;
WORD wFrameCount = 0;
//USER DEFINED SECTION - CHANGE THE FILENAME AND NUMBER OF FRAMES TO MATCH
//YOUR OWN ANIMATION
char gszFrameFile[] = "arrow.bmp";
BOOL Repeat = FALSE;
BOOL NoError = TRUE;
#define MAXFRAMES  15

long FAR PASCAL MainWndProc(HWND hWnd, UINT message, WPARAM wParam,
                            LPARAM lParam)
{
FARPROC lpProcAbout;
static RECT rtDest;                   //Where to play the frames
HDC hDC;					 //
int Temp;
char Xmessage[11];
char NextCount[16] = {0x10,0x0F,0x0E,0x0D,0x0C,0x0B,0x0A,0x9,0x8,0x7,0x6,0x5,0x4,0x3,0x2,0x1};

    Temp = NextCount[1];
    switch (message)
    {
        case WM_COMMAND:
            switch (wParam) {
                case IDM_ABOUT:
                    lpProcAbout = MakeProcInstance(About, hInst);
                    DialogBox(hInst,                 //current instance
                        "AboutBox",                  //resource to use
                        hWnd,                        //parent handle
                        lpProcAbout);                //About() instance address
                    FreeProcInstance(lpProcAbout);
                    break;
		case IDM_START:
		    //Set the frame rate to 10 frames/second
		    //	  SetTimer (1234, 1, 100, NULL);
			  SetTimer (hWnd, 1, 100, NULL);
		    if (wFrameCount != 0)
			{
			  wFrameCount = 0;
			  PaintBmp(hWnd, "Pshoot", 0, 0);
			  PaintBmp(hWnd, "Papple", 268, 36);
			  anDisplayFrame (hAnimation, hDC=GetDC(hWnd), wFrameCount, 50,
			     64 - FRAMEHEIGHT);
			  ReleaseDC (hWnd, hDC);
			}
		    break;
		case IDM_REPEAT:
			if (Repeat)
				Repeat = FALSE;
			else
				Repeat = TRUE;
			break;
                default:
                    return (DefWindowProc(hWnd, message, wParam, lParam));
            } //End switch (wParam)
            break;
        case WM_CREATE:
                //Window dimensions
            GetClientRect (hWnd, (LPRECT)&rtDest);
            if ((hAnimation = anInit (gszFrameFile, MAXFRAMES))==NULL)
            {   MessageBox(hWnd, "Error loading animation","",MB_ICONEXCLAMATION);
                break;
            } //End if (failed to initialize animation)
            break;
        case WM_DESTROY:
                //clean up
	    TerminateThread(ThreadHand, 0);
            anClose (hAnimation);
            PostQuitMessage(0);
            break;
        case WM_TIMER:
                //Display the next frame in the animation
	    if (wFrameCount == MAXFRAMES-1)
		{
		    PaintBmp(hWnd, "Parrow", 268, 36);
		    PaintBmp(hWnd, "Pshoot", 0, 0);
		    if (Repeat == FALSE)
			{
			   KillTimer (hWnd, 1);
			}
		    else
			{
			   PostMessage (hWnd, WM_COMMAND, IDM_START, 0);
			}
		 } // end if
	    else
		 {
		if (NoError)
			{
	    if (anDisplayFrame (hAnimation, hDC=GetDC(hWnd), wFrameCount, 60,
			     64 - FRAMEHEIGHT) < 0)
	    {
			   KillTimer (hWnd, 1);
			   NoError = FALSE;
			   MessageBox(hWnd, Xmessage,"",MB_ICONEXCLAMATION);
            } //End if (animation error)
            ReleaseDC (hWnd, hDC);
	      Temp = (MAXFRAMES - wFrameCount);
	    wFrameCount = NextCount[Temp];
			} //endif noerror
		  } // end of else
            break;
	case WM_PAINT:
		    DefWindowProc(hWnd, message, wParam, lParam);
		    PaintBmp(hWnd, "Pshoot", 0, 0);
		    PaintBmp(hWnd, "Papple", 268, 36);
		    anDisplayFrame (hAnimation, hDC=GetDC(hWnd), wFrameCount, 50,
		       64 - FRAMEHEIGHT);
		    ReleaseDC (hWnd, hDC);
	    break;
        default:
            return (DefWindowProc(hWnd, message, wParam, lParam));
    } //End switch (message)
    return (NULL);
} //End function (MainWndProc)










#endif










/****************************************************************************
    FUNCTION: About(HWND, unsigned, WORD, LONG)
    PURPOSE:  Processes messages for "About" dialog box
****************************************************************************/
BOOL FAR PASCAL About(HWND hDlg, unsigned message, WORD wParam, LONG lParam)
{
    switch (message) {
        case WM_INITDIALOG:                   //message: initialize dialog box
            return (TRUE);
        case WM_COMMAND:                      //message: received a command
            if (wParam == IDOK                //"OK" box selected?
                || wParam == IDCANCEL) {      //System menu close command?
                EndDialog(hDlg, TRUE);        //Exits the dialog box
                return (TRUE);
            } //End if (OK button)
            break;
    } //end switch (on message)
    return (FALSE);
} //End fucntion (About)
