



bool	WinInFocus = false;	// Флаг того, что окно эмулятора находится в фокусе


bool	Leds[3] = {0, 0, 0}; // Массив состояний лампочек клавиатуры
bool	PrevLeds[3] = {0, 0, 0}; // Массив предыдущего состояния лампочек клавиатуры
bool	SysLeds[3];			// Масссив сохраненного состояния лампочек клавиатуры системы



//*********************************************************************************
//
//					Функция управления лампочками клавиатуры
//
//*********************************************************************************
void LedsTranslate(bool *Leds, bool *PLeds)
{
	bool b;

//-------------------------------------------------------------- NumLock
													
	if (Leds[0] ^ PLeds[0])										// Если текущее состояние клавиши иное, то
	{

		keybd_event(VK_NUMLOCK, 0, KEYEVENTF_EXTENDEDKEY | 0, 0);				// Нажать и отпустить клавишу
		keybd_event(VK_NUMLOCK, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);	//
	}

//-------------------------------------------------------------- CapsLock

	if (Leds[1] ^ PLeds[1])										// Если текущее состояние клавиши иное, то
	{

		keybd_event(VK_CAPITAL, 0, KEYEVENTF_EXTENDEDKEY | 0, 0);				// Нажать и отпустить клавишу
		keybd_event(VK_CAPITAL, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);	//
	}

//-------------------------------------------------------------- ScrollLock
												
	if (Leds[2] ^ PLeds[2])										// Если текущее состояние клавиши иное, то
	{

		keybd_event(VK_SCROLL, 0, KEYEVENTF_EXTENDEDKEY | 0, 0);				// Нажать и отпустить клавишу
		keybd_event(VK_SCROLL, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);	//
	}

}





//*********************************************************************************
//
//	 Функция копирования состояния лампочек клавиатуры из одного массива в другой
//
//*********************************************************************************
void CopyLeds(bool *SLeds, bool *DLeds)
{
	DLeds[0] = SLeds[0];
	DLeds[1] = SLeds[1];
	DLeds[2] = SLeds[2];

}



//*********************************************************************************
//
//				Сохранить состояние лампочек клавиатуры в массиве
//
//*********************************************************************************
void SaveLeds(bool *Leds)
{
	Leds[0] = bool(GetKeyState(VK_NUMLOCK) & 0x01);				// Leds[0] - состояние NumLock
	Leds[1] = bool(GetKeyState(VK_CAPITAL) & 0x01);				// Leds[1] - состояние CapsLock
	Leds[2] = bool(GetKeyState(VK_SCROLL) & 0x01);				// Leds[2] - состояние ScrollLock

}



//*********************************************************************************
//
//				Сохранить состояние лампочек клавиатуры в массиве
//
//*********************************************************************************
void SaveLeds(bool *Leds)
{
	Leds[0] = bool(GetKeyState(VK_NUMLOCK) & 0x01);				// Leds[0] - состояние NumLock
	Leds[1] = bool(GetKeyState(VK_CAPITAL) & 0x01);				// Leds[1] - состояние CapsLock
	Leds[2] = bool(GetKeyState(VK_SCROLL) & 0x01);				// Leds[2] - состояние ScrollLock

}

//*********************************************************************************
//
//					Обработчик глобального хука клавиатуры
//						  (отдельный поток и колбек)
//
//*********************************************************************************
LRESULT CALLBACK KeyboardHook(int nCode, WPARAM wParam, LPARAM lParam)
{
	UINT8 vkCode, diCode, flags;
	KBDLLHOOKSTRUCT *lp = (KBDLLHOOKSTRUCT*)lParam;
	
//	printf("Hook action\n");

	if (WinInFocus)												// Если окно находится в фокусе
	{
		vkCode = UINT8(lp->vkCode);								// Получить виртуальный код клавиши
		flags = UINT8(lp->flags);								// Получить флаги

		if ((nCode == HC_ACTION) &&								// Если произошло изменение состояния клавиши,
			(flags & 0x10))										// и оно было просимулированно, то
																// выход с передачей параметров в следующий хук
			return CallNextHookEx(hhKeyboardHook, nCode, wParam, lParam);	


		if (nCode == HC_ACTION)									// Если произошло изменение состояние клавиши, то
		{
			if (flags & 0x01)									// Получить код клавиши в формате DirectInput
				diCode = HookScanTabDK[vkCode];					// по таблице HookScanTab[], если код с основной
			else												// клавиатуры, и по таблице HookScanTabDK[],
				diCode = HookScanTab[vkCode];					// если код с дополнительной клавиатуры

//			printf("vkCode = 0x%02X, scanCode = 0x%02X, flags = 0x%02X, diCode = 0x%02X\n", vkCode, lp->scanCode, flags, diCode);

			HookKeyboard[diCode] = (flags ^ 0x80) & 0x80;		// Устанавливаем код нажатия/отжатия в таблице
																// клавиатуры
			
			if ((vkCode == VK_CAPITAL) ||						// Если была нажата клавиша CapsLock, или
				(vkCode == VK_NUMLOCK) ||						// NumLock или ScrollLock, то не передаем
				(vkCode == VK_SCROLL))							// информацию следующему хуку (не меняем
				return (1);										// состояние лампочки)
		}

	}

	return CallNextHookEx(hhKeyboardHook, nCode, wParam, lParam);
}



//*********************************************************************************
//
//					Инициализация при получении окном фокуса
//
//*********************************************************************************
void WSetFocus(void)
{
//	printf("Set focus\n");
	
	if (WinInFocus)					// Если уже находились в фокусе, то выйти
		return;						//

	SaveLeds(SysLeds);				// Сохранить состояние лампочек клавиатуры системы

	WinInFocus = true;				// Установить флаг фокуса

	SaveLeds(PrevLeds);				// Сохранить текущее состояние лампочек клавиатуры
									// (необходимо выполнять после установки флага WinInFocus,
									// т.к. это гарантирует, что нажатие на клавиатуру уже
									// не сможет изменить состояние лампочек)

	LedsTranslate(Leds, PrevLeds);	// Вывести состояние лампочек клавиатуры эмулятора
	CopyLeds(Leds, PrevLeds);		// Запомнить состояние лампочек эмулятора

}



//*********************************************************************************
//
//					Инициализация при потерe окном фокуса
//
//*********************************************************************************
void WKillFocus(void)
{
//	printf("Kill focus\n");

	LedsTranslate(SysLeds, Leds);	// Вывести сохраненное состояние лампочек клавиатуры системы

	WinInFocus = false;				// Сбросить флаг фокуса
}




//---------------------------------------------------------- Индикация состояний Floppy-дисков лампочками клавиатуры

	Leds[0] = Floppy[0].Motor && Floppy[0].Mode;			// Если мотор включен и чтение или запись,
	Leds[1] = Floppy[1].Motor && Floppy[1].Mode;			// то лампочка соответствующего дисковода горит


//Собственно трансляция состояния лампочек

	if (WinInFocus)
	{
		LedsTranslate(Leds, PrevLeds);
		CopyLeds(Leds, PrevLeds);
	}


