#define MODE_WIN
HWND gblHWnd;
unsigned char touches[256];
int rouletteSouris=0;
BOOL DoubleBuffer=FALSE, curseur=1, occupe=0;
#define ModeConsole()		(DoubleBuffer=0)
#define ModeGraphique()		(DoubleBuffer=1)

#include <wingraph/graphlib.h>

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow);

DWORD ThreadID;
HANDLE hThread;
BOOL quitte=0;					//Forcé de quitter :)

#define arret	(quitte=1)

void main(void);

int affiniteParDefaut=1, affiniteSystemeParDefaut;

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
	MSG msg;

 	// TODO: Place code here.
	MyRegisterClass(hInstance);

	// Perform application initialization:
	if (!InitInstance (hInstance, nCmdShow)) 
	{
		return FALSE;
	}

	InitUltra();
//	GdiSetBatchLimit(1);
//	GetProcessAffinityMask(GetCurrentProcess(),&affiniteParDefaut,&affiniteSystemeParDefaut);
//	SetProcessAffinityMask(GetCurrentProcess(),1);
	PatBlt(hdcConsole,0,0,LARG,HAUT,BLACKNESS);
	hThread = CreateThread(	(LPSECURITY_ATTRIBUTES)NULL,
							(DWORD)0,
							(LPTHREAD_START_ROUTINE)main,
							(LPVOID)NULL,
							(DWORD)0,
							(LPDWORD)&ThreadID
						  );

	// Main message loop:
	while (GetMessage(&msg, NULL, 0, 0) && !quitte) 
	{
/*		if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
		{*/
			TranslateMessage(&msg);
			DispatchMessage(&msg);
//		}
	}
	PostQuitMessage(0);
	return msg.wParam;
}

HINSTANCE hInst;

//
//  FUNCTION: MyRegisterClass()
//
//  PURPOSE: Registers the window class.
//
//  COMMENTS:
//
//    This function and its usage is only necessary if you want this code
//    to be compatible with Win32 systems prior to the 'RegisterClassEx'
//    function that was added to Windows 95. It is important to call this function
//    so that the application will get 'well formed' small icons associated
//    with it.
//

ATOM MyRegisterClass(HINSTANCE hInstance)
{
	WNDCLASSEX wcex;

	wcex.cbSize = sizeof(WNDCLASSEX); 

	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= (WNDPROC)WndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon			= NULL;
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszMenuName	= NULL;
	wcex.lpszClassName	= "WinLib";
	wcex.hIconSm		= NULL;

	return RegisterClassEx(&wcex);
}

//
//   FUNCTION: InitInstance(HANDLE, int)
//
//   PURPOSE: Saves instance handle and creates main window
//
//   COMMENTS:
//
//        In this function, we save the instance handle in a global variable and
//        create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   HWND hWnd;

   hInst = hInstance; // Store instance handle in our global variable

	hWnd = CreateWindow("WinLib", "Programme WinGraph", WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX,
		CW_USEDEFAULT, 0, LARG, HAUT, NULL, NULL, hInstance, NULL);

   if (!hWnd)
   {
      return FALSE;
   }

   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);
   gblHWnd=hWnd;

   return TRUE;
}

void DessCurseur(int i)		{
	switch (curseur)		{
		case 1:
			if ((i/500)&1)
				InverseCadre(texteX,texteY+HAUT_CAR-4,LARG_CAR-1,2);
			break;
		case 2:
			if ((i/500)&1)
				InverseCadre(texteX,texteY,LARG_CAR-1,10);
			break;
		case 3:
			if ((i/200)&1)
				InverseCadre(texteX,texteY,LARG_CAR-1,10);
			break;
	}
}

#define WM_MOUSEWHEEL                   0x020A

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;
	static int fenX, fenY, termine=0;
	PAINTSTRUCT ps;
	HDC hdc;
	RECT rect;
	int k, timer=0;
	DWORD code;
	CRITICAL_SECTION cs;

	occupe=0;
	switch (message) 
	{
/*		case WM_MOUSEMOVE:
			xSouris = LOWORD(lParam);
			ySouris = HIWORD(lParam);
			break;*/
		case WM_TIMER:
			GetExitCodeThread(hThread,&code);
			if (code!=STILL_ACTIVE)		{
				if (!termine)		{
					AfficheEcran();
					SetWindowText(gblHWnd,"Terminé. Appuyez sur une touche/cliquez pour continuer.");
				}
				termine=1;
				if (keybhit())
					DestroyWindow(hWnd);
			}
			if (!hdcImage || !hbm)
				break;
			if (!DoubleBuffer && !occupe)		{
				int i=GetTickCount();
				InitializeCriticalSection(&cs);
				EnterCriticalSection(&cs);
				SuspendThread(hThread);
				DessCurseur(i);
				AfficheEcran();
				DessCurseur(i);
				ResumeThread(hThread);
				LeaveCriticalSection(&cs);
				DeleteCriticalSection(&cs);
			}
			break;
		case WM_CREATE:
			GetClientRect(hWnd, &rect);
			fenX=LARG+LARG-rect.right;
			fenY=HAUT+HAUT-rect.bottom;
			SetWindowPos(hWnd,HWND_TOP,0,0,fenX,fenY,SWP_NOMOVE|SWP_NOZORDER);
			SetTimer(hWnd,1,10,NULL);
			break;
		case WM_CHAR:
			k= (UCHAR) wParam;
			if (k>=0 && k<256)
				pushkey(k);
			break;
		case WM_KEYDOWN:
			k=(int) wParam;
			if (k>=0 && k<256)
				touches[k]=1;
			break;
		case WM_KEYUP:
			k=(int) wParam;
			if (k>=0 && k<256)
				touches[k]=0;
			break;
		case WM_COMMAND:
			wmId    = LOWORD(wParam); 
			wmEvent = HIWORD(wParam); 
			// Parse the menu selections:
			switch (wmId)
			{
				default:
				   return DefWindowProc(hWnd, message, wParam, lParam);
			}
			break;
		case WM_LBUTTONDOWN:
			touches[T_SOURIS_GAUCHE]=1;
			break;
		case WM_LBUTTONUP:
			touches[T_SOURIS_GAUCHE]=0;
			break;
		case WM_RBUTTONDOWN:
			touches[T_SOURIS_DROIT]=1;
			break;
		case WM_RBUTTONUP:
			touches[T_SOURIS_DROIT]=0;
			break;
		case WM_MBUTTONDOWN:
			touches[T_SOURIS_MILIEU]=1;
			break;
		case WM_MBUTTONUP:
			touches[T_SOURIS_MILIEU]=0;
			break;
		case WM_MOUSEWHEEL :
			rouletteSouris-=(short) HIWORD(wParam);
			break;
		case WM_ERASEBKGND:
			break;
		case WM_PAINT:
			hdc = BeginPaint(hWnd, &ps);
			// TODO: Add any drawing code here...
/*			if (!DoubleBuffer && !occupe)			{
				SuspendThread(hThread);
				InitializeCriticalSection(&cs);
				EnterCriticalSection(&cs);
				AfficheEcran();
				ResumeThread(hThread);
				LeaveCriticalSection(&cs);
				DeleteCriticalSection(&cs);
			}*/
//			GetClientRect(hWnd, &rt);
			EndPaint(hWnd, &ps);
			break;
		case WM_DESTROY:
		case WM_CLOSE:
			hdcConsole=0;
			quitte=1;
			PostQuitMessage(0);
			break;
		default:
			ResumeThread(hThread);
			return DefWindowProc(hWnd, message, wParam, lParam);
   }
   return 0;
}
