Exemplo n.º 1
0
std::wstring cil::CILKeyboardState::ToUnicode( CIL_KEY key )
{
	std::wstring out;
	int scan;
	WCHAR buff[32];
	UINT size = 32;

	scan = MapVirtualKeyEx(key, 0, m_keyboardLayout);
	int numChars = ToUnicodeEx(key, scan, m_keys, buff, size, 0, m_keyboardLayout);

	if (numChars == 1)
	{
		out.push_back(buff[0]);
	}
	else if (numChars > 1)
	{
		WCHAR* pTemp = new WCHAR[numChars + 1];
		memcpy(pTemp, buff, numChars * sizeof(WCHAR));
		pTemp[numChars] = L'\0';

		out += std::wstring(pTemp);
	}

	return out;
}
Exemplo n.º 2
0
UINT TranslateToUnicode (WORD *uVKey, LPBYTE GlobalKeyStates){

	BYTE KeyStates[256];
	UINT USvk = 0;

	GetKeyboardState(KeyStates);
	KeyStates[VK_CONTROL] = KeyStates[VK_MENU ] = KeyStates[VK_LMENU] = KeyStates[VK_RMENU] = 0;
	if (!klf.layout.trackCaps)
		KeyStates[VK_CAPITAL] = 0;

 	WCHAR TransedChar = NULL;
	UINT ScanCode = MapVirtualKey(*uVKey, MAPVK_VK_TO_VSC);

	if (!ScanCode)
		return false;

	if (klf.layout.posBased==true && GetKeyboardLayout(0) != (HKL)0x04090409){
		USvk = ScancodeToVirtualkey(ScanCode);
		if (USvk != *uVKey && USvk <= 255){
			GlobalKeyStates[USvk] = KeyStates[USvk] = KeyStates[*uVKey];
			GlobalKeyStates[*uVKey] = KeyStates[*uVKey] = 0x00;
			*uVKey = USvk;
		}
	}else { USvk = *uVKey ; }

	int Return = ToUnicodeEx(*uVKey, ScanCode, KeyStates, &TransedChar, 1, 0, hkl);

	if (!Return) return false;

	if (TransedChar > 33 || TransedChar < 126)
		*uVKey = TransedChar;
	else {return false;}

	return USvk;
}
Exemplo n.º 3
0
GHOST_EventKey* GHOST_SystemWin32::processKeyEvent(GHOST_IWindow *window, RAWINPUT const& raw)
{
	int keyDown=0;
	char vk;
	GHOST_SystemWin32 * system = (GHOST_SystemWin32 *)getSystem();
	GHOST_TKey key = system->hardKey(window, raw, &keyDown, &vk);
	GHOST_EventKey* event;

	if (key != GHOST_kKeyUnknown) {
		char utf8_char[6] = {0} ;

		wchar_t utf16[2]={0};
		BYTE state[256];
		GetKeyboardState((PBYTE)state);  

		if(ToUnicodeEx(vk, 0, state, utf16, 2, 0, system->m_keylayout))
			WideCharToMultiByte(CP_UTF8, 0, 
									(wchar_t*)utf16, 1,
									(LPSTR) utf8_char, 5,
									NULL,NULL); else *utf8_char = 0;

		if(!keyDown) utf8_char[0] = '\0';
		
		event = new GHOST_EventKey(system->getMilliSeconds(), keyDown ? GHOST_kEventKeyDown: GHOST_kEventKeyUp, window, key, (*utf8_char & 0x80)?'?':*utf8_char, utf8_char);
		
#ifdef GHOST_DEBUG
		std::cout << ascii << std::endl;
#endif
	}
	else {
		event = 0;
	}
	return event;
}
Exemplo n.º 4
0
	MyGUI::Char translateWin32Text(MyGUI::KeyCode kc)
	{
		static WCHAR deadKey = 0;

		BYTE keyState[256];
		HKL  layout = GetKeyboardLayout(0);
		if ( GetKeyboardState(keyState) == 0 )
			return 0;

		int code = *((int*)&kc);
		unsigned int vk = MapVirtualKeyEx((UINT)code, 3, layout);
		if ( vk == 0 )
			return 0;

		WCHAR buff[3] = { 0, 0, 0 };
		int ascii = ToUnicodeEx(vk, (UINT)code, keyState, buff, 3, 0, layout);
		if (ascii == 1 && deadKey != '\0' )
		{
			// A dead key is stored and we have just converted a character key
			// Combine the two into a single character
			WCHAR wcBuff[3] = { buff[0], deadKey, '\0' };
			WCHAR out[3];

			deadKey = '\0';
			if (FoldStringW(MAP_PRECOMPOSED, (LPWSTR)wcBuff, 3, (LPWSTR)out, 3))
				return out[0];
		}
		else if (ascii == 1)
		{
			// We have a single character
			deadKey = '\0';
			return buff[0];
		}
		else if (ascii == 2)
		{
			// Convert a non-combining diacritical mark into a combining diacritical mark
			// Combining versions range from 0x300 to 0x36F; only 5 (for French) have been mapped below
			// http://www.fileformat.info/info/unicode/block/combining_diacritical_marks/images.htm
			switch (buff[0])
			{
			case 0x5E: // Circumflex accent: ?				deadKey = 0x302;
				break;
			case 0x60: // Grave accent: ?				deadKey = 0x300;
				break;
			case 0xA8: // Diaeresis: ?				deadKey = 0x308;
				break;
			case 0xB4: // Acute accent: ?				deadKey = 0x301;
				break;
			case 0xB8: // Cedilla: ?				deadKey = 0x327;
				break;
			default:
				deadKey = buff[0];
				break;
			}
		}

		return 0;
	}
Exemplo n.º 5
0
/*
 * @implemented
 */
int WINAPI
ToUnicode(UINT wVirtKey,
          UINT wScanCode,
          CONST BYTE *lpKeyState,
          LPWSTR pwszBuff,
          int cchBuff,
          UINT wFlags)
{
    return ToUnicodeEx(wVirtKey, wScanCode, lpKeyState, pwszBuff, cchBuff,
                       wFlags, 0);
}
Keyboard::Press KeyboardWinAPI::getPress (WPARAM wParam, LPARAM scan_code)
{
        Keyboard::Press r;
        BYTE state[256] = {0};

        WCHAR buf[1024] = {0};
        int ret = ToUnicodeEx(wParam, scan_code, state,
                              buf, sizeof(buf)/sizeof(*buf),
                              0, GetKeyboardLayout(0));

        bool dead = false;
        if (ret==-1) {
                /* The specified virtual key is a dead-key character (accent or diacritic).
                 * This value is returned regardless of the keyboard layout, even if several
                 * characters have been typed and are stored in the keyboard state. If possible,
                 * even with Unicode keyboard layouts, the function has written a spacing
                 * version of the dead-key character to the buffer specified by pwszBuff.
                 * For example, the function writes the character SPACING ACUTE (0x00B4),
                 * rather than the character NON_SPACING ACUTE (0x0301). */

                // We still want to allow this key to be bound to things, so provide the spacing char as the key.
                ret = 1;
                dead = true; // for debug output
        }
        if (ret<0 || ret>=sizeof(buf)/sizeof(*buf)) {
                CERR << "ToUnicodeEx returned out of range: " << ret << std::endl;
                ret = 0;
        }
        if (ret>1) {
                /* Two or more characters were written to the buffer specified by pwszBuff. The
                 * most common cause for this is that a dead-key character (accent or diacritic)
                 * stored in the keyboard layout could not be combined with the specified virtual
                 * key to form a single character. */
                // No idea what this means but I think I should ignore anything from the 'previous' key
                // HACK: this may break if buf contains surrogate pairs!
                buf[0] = buf[ret-1];
                ret = 1;
        }

        buf[ret] = 0;
        if (verbose) {
                std::stringstream ss;
                ss << "[";
                for (int i=0 ; i<ret ; ++i) {
                        ss << (i==0 ? " " : ", ") << std::hex << "0x" << ((int)buf[i]) << std::dec;
                }
                ss << " ]";
                if (dead) ss << "!";
                CLOG << ss.str() << std::endl;
        }

        return utf16_to_utf8(buf);
}
Exemplo n.º 7
0
QString keyboardHook::vkCodeToText(DWORD vkCode, DWORD scanCode)
{
    BYTE keyState[256] = {0};

    if (GetKeyboardState(keyState)) {
		wchar_t buffer[10];
        int result = ToUnicodeEx(vkCode, scanCode, keyState, buffer, _countof(buffer), 0, NULL);
        if (result)
            return QString::fromWCharArray(buffer);
    }
    return "";
}
Exemplo n.º 8
0
Arquivo: input.c Projeto: mikekap/wine
/****************************************************************************
 *		ToAsciiEx (USER32.@)
 */
INT WINAPI ToAsciiEx( UINT virtKey, UINT scanCode, const BYTE *lpKeyState,
                      LPWORD lpChar, UINT flags, HKL dwhkl )
{
    WCHAR uni_chars[2];
    INT ret, n_ret;

    ret = ToUnicodeEx(virtKey, scanCode, lpKeyState, uni_chars, 2, flags, dwhkl);
    if (ret < 0) n_ret = 1; /* FIXME: make ToUnicode return 2 for dead chars */
    else n_ret = ret;
    WideCharToMultiByte(CP_ACP, 0, uni_chars, n_ret, (LPSTR)lpChar, 2, NULL, NULL);
    return ret;
}
Exemplo n.º 9
0
LPTSTR GenerateLayoutString(HKL hklLayout)
{
	BYTE bState[256] = {0};

	LPTSTR ptszLayStr = (LPTSTR)mir_alloc(100 * sizeof(TCHAR));
	LPTSTR ptszTemp = (LPTSTR)mir_alloc(3 * sizeof(TCHAR));
	ptszTemp[0] = 0;

	DWORD i;
	for (i = 0; i < _tcslen(ptszKeybEng); i++) {
		SHORT shVirtualKey = VkKeyScanEx(ptszKeybEng[i], hklEng);
		UINT iScanCode = MapVirtualKeyEx(shVirtualKey & 0x00FF, 0, hklEng);

		for (DWORD j = 0; j < 256; j++)
			bState[j] = 0;

		if (shVirtualKey & 0x0100) bState[VK_SHIFT] = 0x80;
		if (shVirtualKey & 0x0200) bState[VK_CONTROL] = 0x80;
		if (shVirtualKey & 0x0400) bState[VK_MENU] = 0x80;

		shVirtualKey = MapVirtualKeyEx(iScanCode, 1, hklLayout);
		bState[shVirtualKey & 0x00FF] = 0x80;

		int iRes = ToUnicodeEx(shVirtualKey, iScanCode, bState, ptszTemp, 3, 0, hklLayout);
		// Защита от дэд-кеев
		if (iRes < 0)
			ToUnicodeEx(shVirtualKey, iScanCode, bState, ptszTemp, 3, 0, hklLayout);

		// Если нам вернули нулевой символ, или не вернули ничего, то присвоим "звоночек"
		if (ptszTemp[0] == 0)
			ptszLayStr[i] = 3;
		else
			ptszLayStr[i] = ptszTemp[0];
	}
	ptszLayStr[i] = 0;

	mir_free(ptszTemp);
	return ptszLayStr;
}
Exemplo n.º 10
0
wchar_t Keyboard::GetCurrentPressedChar(uint64_t lockID) const
{
	if(m_LockID != 0 && m_LockID != lockID)
	{
		return L'';
	}

	//ToUnicodeEx returns a key for ctrl + ANYKEY, we do not want any, so it if it is press, return no key
	if(m_CurrentKeyboardState[(uint32_t)AEKeys::LCTRL] & AE_INPUT_PRESS || m_CurrentKeyboardState[(uint32_t)AEKeys::RCTRL] & AE_INPUT_PRESS)
	{
		return L'';
	}

	//ToUnicodeEx returns a key for backspace, we do not want any, so it if it is press, return no key
	if(m_CurrentKeyboardState[(uint32_t)AEKeys::BACKSPACE] & AE_INPUT_PRESS)
	{
		return L'';
	}

	BYTE state[256];
	memset(state, 0, sizeof(BYTE) * 256);

	if (GetKeyboardState(state) == FALSE)
	{
		return L'';
	}

	//For Shift/Ctrl/Alt/Caps Keys we need to set them
	//0x80 = down 
	//0x01 = toggled (for Caps)
	state[VK_CAPITAL] = (BYTE)GetKeyState(VK_CAPITAL);
	state[VK_SHIFT] = (BYTE)GetKeyState(VK_SHIFT);

	for(uint32_t i = 0; i < AE_MAX_KEYS; ++i)
	{
		if(!(m_PreviousKeyboardState[i] & AE_INPUT_PRESS) && (m_CurrentKeyboardState[i] & AE_INPUT_PRESS))
		{
			uint32_t vk = (uint32_t)m_KeyMapVK[i];

			uint32_t scanCode = MapVirtualKeyEx(vk, MAPVK_VK_TO_VSC, m_KeyboardLayout);
			wchar_t result[] = { 0, 0 };

			if (ToUnicodeEx(vk, scanCode, state, result, 2, 0, m_KeyboardLayout) > 0)
			{
				return result[0];
			}
		}
	}

	return L'';
}
Exemplo n.º 11
0
GHOST_EventKey *GHOST_SystemWin32::processKeyEvent(GHOST_IWindow *window, RAWINPUT const& raw)
{
	int keyDown = 0;
	char vk;
	GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
	GHOST_TKey key = system->hardKey(window, raw, &keyDown, &vk);
	GHOST_EventKey *event;

	if (key != GHOST_kKeyUnknown) {
		char utf8_char[6] = {0};
		char ascii = 0;

		wchar_t utf16[3] = {0};
		BYTE state[256] = {0};
		int r;
		GetKeyboardState((PBYTE)state);

		// don't call ToUnicodeEx on dead keys as it clears the buffer and so won't allow diacritical composition.
		if (MapVirtualKeyW(vk,2) != 0) {
			// todo: ToUnicodeEx can respond with up to 4 utf16 chars (only 2 here). Could be up to 24 utf8 bytes.
			if ((r = ToUnicodeEx(vk, raw.data.keyboard.MakeCode, state, utf16, 2, 0, system->m_keylayout))) {
				if ((r > 0 && r < 3)) {
					utf16[r] = 0;
					conv_utf_16_to_8(utf16, utf8_char, 6);
				}
				else if (r == -1) {
					utf8_char[0] = '\0';
				}
			}
		}

		if (!keyDown) {
			utf8_char[0] = '\0';
			ascii = '\0';
		}
		else {
			ascii = utf8_char[0] & 0x80 ? '?' : utf8_char[0];
		}

		event = new GHOST_EventKey(system->getMilliSeconds(), keyDown ? GHOST_kEventKeyDown : GHOST_kEventKeyUp, window, key, ascii, utf8_char);
		
#ifdef GHOST_DEBUG
		std::cout << ascii << std::endl;
#endif
	}
	else {
		event = 0;
	}
	return event;
}
		u16 CKeyboard::_TranslateChar(WPARAM wParam, LPARAM lParam, u32 uiFlags)
		{
			u32 uiScanCode = MapVirtualKeyA( wParam, 2 );
			ch16 wchCode[] = { 0, 0 };
			i32 iResult = ToUnicodeEx( wParam, uiScanCode, m_abyKeyboardState, wchCode, sizeof( ch16 ), uiFlags, m_WinHKL );
			//iResult = ToUnicodeEx( wParam, uiScanCode, m_abyKeyboardState, wchCode, sizeof( ch16 ), uiFlags, m_WinHKL );
			if( iResult <= 0 )
			{
				//Set to default if there is no translation
				wchCode[ 0 ] = (ch16)wParam;
			}
			wchCode[ 1 ] = 0;
			return wchCode[ 0 ];
		}
Exemplo n.º 13
0
CString VkToString( DWORD vk ) {
	UINT vsc = MapVirtualKeyEx( vk & 0x7fffffffUL, MAPVK_VK_TO_VSC, GetKeyboardLayout( 0 ) );
	if ( ! vsc ) {
		return CString( );
	}

	BYTE keyState[256] = { 0, };
	wchar_t keyBuf[8] = { 0, };

	if ( 0 != ( vk & 0x80000000 ) ) {
		keyState[VK_SHIFT] = 0x80;
	}
	ToUnicodeEx( vk, vsc, keyState, keyBuf, 256, 0, GetKeyboardLayout( 0 ) );
	return CString( keyBuf );
}
Exemplo n.º 14
0
static void
reset_after_dead (guchar key_state[256])
{
  guchar temp_key_state[256];
  wchar_t wcs[2];

  memmove (temp_key_state, key_state, sizeof (key_state));

  temp_key_state[VK_SHIFT] =
    temp_key_state[VK_CONTROL] =
    temp_key_state[VK_MENU] = 0;

  ToUnicodeEx (VK_SPACE, MapVirtualKey (VK_SPACE, 0),
	       temp_key_state, wcs, G_N_ELEMENTS (wcs),
	       0, _gdk_input_locale);
}
Exemplo n.º 15
0
/*
 * @implemented
 */
int WINAPI
ToAsciiEx(UINT uVirtKey,
          UINT uScanCode,
          CONST BYTE *lpKeyState,
          LPWORD lpChar,
          UINT uFlags,
          HKL dwhkl)
{
    WCHAR UniChars[2];
    int Ret, CharCount;

    Ret = ToUnicodeEx(uVirtKey, uScanCode, lpKeyState, UniChars, 2, uFlags, dwhkl);
    CharCount = (Ret < 0 ? 1 : Ret);
    WideCharToMultiByte(CP_ACP, 0, UniChars, CharCount, (LPSTR)lpChar, 2, NULL, NULL);

    return Ret;
}
Exemplo n.º 16
0
void WritesScannedKeyToFile(short sScannedKey)
{
	HKL hkl;
	DWORD dwThreadId;
	DWORD dwProcessId;

	hWindowHandle = GetForegroundWindow();
	dwThreadId = GetWindowThreadProcessId(hWindowHandle, &dwProcessId);
	BYTE *kState = (BYTE*)malloc(256);
	GetKeyboardState(kState);
	hkl = GetKeyboardLayout(dwThreadId);
	wchar_t besmallah[16] = {0};
	UINT virtualKey = MapVirtualKeyEx((UINT)sScannedKey, MAPVK_VK_TO_CHAR, hkl);
	ToUnicodeEx(virtualKey, sScannedKey, (BYTE*)kState, besmallah, 16, NULL, hkl);
	WriteToFile(besmallah);
	//CloseHandle(hkl);
	free(kState);
}
Exemplo n.º 17
0
VOID
KbdTestGetKeyNameText()
{
	WCHAR text[20];
	HWND hForegroundWnd = NULL;
	DWORD threadId = 0;
	HKL hCurrKL = NULL;
	BYTE btKeyState[256];
	UINT scanCode = 21;
	GUITHREADINFO threadInfo;
	DWORD focusThread = NULL;
	hForegroundWnd = GetForegroundWindow();
	threadId = GetWindowThreadProcessId(hForegroundWnd, NULL);

	DebugPrint(L"hForegroundWnd=%x, threadId=%x\n", hForegroundWnd, threadId);
	memset(&threadInfo, 0, sizeof(threadInfo));
	threadInfo.cbSize = sizeof(threadInfo);

	if (!GetGUIThreadInfo(threadId, &threadInfo)) {
		DebugPrint(L"GetGUIThreadInfo failed with err=%x for threadId=%x", GetLastError(), threadId);
	}

	DebugPrint(L"thread.hwndFocus=%x\n", threadInfo.hwndFocus);
	focusThread = GetWindowThreadProcessId(threadInfo.hwndFocus, NULL);
	DebugPrint(L"focusThread=%x\n", focusThread);

	hCurrKL = GetKeyboardLayout(threadId);
	DebugPrint(L"Thread hKL=%x\n", hCurrKL);

	for (int i = 0; i < 10; i++) {
		hCurrKL = ActivateKeyboardLayout((HKL)HKL_NEXT, 0);
		DebugPrint(L"ActivateKeyboardLayout:prevHKL=%x\n", hCurrKL);
		hCurrKL = GetKeyboardLayout(0);
		DebugPrint(L"Curr thread hKL=%x\n", hCurrKL);

		//GetKeyboardState(btKeyState);
		memset(btKeyState, 0, sizeof(btKeyState));
		memset(text, 0, sizeof(text));
		ToUnicodeEx(MapVirtualKey(scanCode, MAPVK_VSC_TO_VK_EX), scanCode, btKeyState, text, RTL_NUMBER_OF(text), 0, hCurrKL);
		DebugPrint(L"ToUnicodeEx text is=%ws, unicode=%x\n", text, (USHORT)text[0]);
	}
}
Exemplo n.º 18
0
VOID NTAPI
ConioProcessKey(PCONSRV_CONSOLE Console, MSG* msg)
{
    static BYTE KeyState[256] = { 0 };
    /* MSDN mentions that you should use the last virtual key code received
     * when putting a virtual key identity to a WM_CHAR message since multiple
     * or translated keys may be involved. */
    static UINT LastVirtualKey = 0;
    DWORD ShiftState;
    WCHAR UnicodeChar;
    UINT VirtualKeyCode;
    UINT VirtualScanCode;
    BOOL Down = FALSE;
    BOOLEAN Fake;          // Synthesized, not a real event
    BOOLEAN NotChar;       // Message should not be used to return a character

    INPUT_RECORD er;

    if (Console == NULL)
    {
        DPRINT1("No Active Console!\n");
        return;
    }

    VirtualScanCode = HIWORD(msg->lParam) & 0xFF;
    Down = msg->message == WM_KEYDOWN || msg->message == WM_CHAR ||
           msg->message == WM_SYSKEYDOWN || msg->message == WM_SYSCHAR;

    GetKeyboardState(KeyState);
    ShiftState = ConioGetShiftState(KeyState, msg->lParam);

    if (msg->message == WM_CHAR || msg->message == WM_SYSCHAR)
    {
        VirtualKeyCode = LastVirtualKey;
        UnicodeChar = msg->wParam;
    }
    else
    {
        WCHAR Chars[2];
        INT RetChars = 0;

        VirtualKeyCode = msg->wParam;
        RetChars = ToUnicodeEx(VirtualKeyCode,
                               VirtualScanCode,
                               KeyState,
                               Chars,
                               2,
                               0,
                               NULL);
        UnicodeChar = (RetChars == 1 ? Chars[0] : 0);
    }

    Fake = UnicodeChar &&
            (msg->message != WM_CHAR && msg->message != WM_SYSCHAR &&
             msg->message != WM_KEYUP && msg->message != WM_SYSKEYUP);
    NotChar = (msg->message != WM_CHAR && msg->message != WM_SYSCHAR);
    if (NotChar) LastVirtualKey = msg->wParam;

    DPRINT("CONSRV: %s %s %s %s %02x %02x '%lc' %04x\n",
           Down ? "down" : "up  ",
           (msg->message == WM_CHAR || msg->message == WM_SYSCHAR) ?
           "char" : "key ",
           Fake ? "fake" : "real",
           NotChar ? "notc" : "char",
           VirtualScanCode,
           VirtualKeyCode,
           (UnicodeChar >= L' ') ? UnicodeChar : L'.',
           ShiftState);

    if (Fake) return;

    /* Process Ctrl-C and Ctrl-Break */
    if ( Console->InputBuffer.Mode & ENABLE_PROCESSED_INPUT &&
         Down && (VirtualKeyCode == VK_PAUSE || VirtualKeyCode == 'C') &&
         (ShiftState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED) || KeyState[VK_CONTROL] & 0x80) )
    {
        DPRINT1("Console_Api Ctrl-C\n");
        ConSrvConsoleProcessCtrlEvent(Console, 0, CTRL_C_EVENT);

        if (Console->LineBuffer && !Console->LineComplete)
        {
            /* Line input is in progress; end it */
            Console->LinePos = Console->LineSize = 0;
            Console->LineComplete = TRUE;
        }
        return;
    }

    if ( (ShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) != 0 &&
         (VirtualKeyCode == VK_UP || VirtualKeyCode == VK_DOWN) )
    {
        if (!Down) return;

        /* Scroll up or down */
        if (VirtualKeyCode == VK_UP)
        {
            /* Only scroll up if there is room to scroll up into */
            if (Console->ActiveBuffer->CursorPosition.Y != Console->ActiveBuffer->ScreenBufferSize.Y - 1)
            {
                Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY +
                                                   Console->ActiveBuffer->ScreenBufferSize.Y - 1) %
                                                   Console->ActiveBuffer->ScreenBufferSize.Y;
                Console->ActiveBuffer->CursorPosition.Y++;
            }
        }
        else
        {
            /* Only scroll down if there is room to scroll down into */
            if (Console->ActiveBuffer->CursorPosition.Y != 0)
            {
                Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY + 1) %
                                                   Console->ActiveBuffer->ScreenBufferSize.Y;
                Console->ActiveBuffer->CursorPosition.Y--;
            }
        }

        ConioDrawConsole(Console);
        return;
    }

    /* Send the key press to the console driver */

    er.EventType                        = KEY_EVENT;
    er.Event.KeyEvent.bKeyDown          = Down;
    er.Event.KeyEvent.wRepeatCount      = 1;
    er.Event.KeyEvent.wVirtualKeyCode   = VirtualKeyCode;
    er.Event.KeyEvent.wVirtualScanCode  = VirtualScanCode;
    er.Event.KeyEvent.uChar.UnicodeChar = UnicodeChar;
    er.Event.KeyEvent.dwControlKeyState = ShiftState;

    ConioProcessInputEvent(Console, &er);
}
Exemplo n.º 19
0
void SwitchLayout(bool lastword)
{
	HWND hwnd = GetForegroundWindow();
	if (hwnd == NULL)
		return;

	DWORD dwProcessID;
	DWORD dwThreadID = GetWindowThreadProcessId(hwnd, &dwProcessID);
	HWND hwnd2 = GetFocus();
	if (hwnd2 == NULL)
		return;

	TCHAR szClassName[MAX_PATH];
	GetClassName(hwnd2, szClassName, _countof(szClassName));
	if ((mir_tstrcmp(szClassName, _T("THppRichEdit.UnicodeClass")) == 0 || mir_tstrcmp(szClassName, _T("THistoryGrid.UnicodeClass")) == 0 || mir_tstrcmp(szClassName, _T("TExtHistoryGrid.UnicodeClass")) == 0 || mir_tstrcmp(szClassName, _T("Internet Explorer_Server")) == 0) && ServiceExists(MS_POPUP_SHOWMESSAGE)) {	// make popup here
		TCHAR buf[2048];
		if (mir_tstrcmp(szClassName, _T("Internet Explorer_Server")) == 0) {
			IEVIEWEVENT event;
			HWND hwnd3 = GetParent(GetParent(hwnd2));
			memset(&event, 0, sizeof(event));
			event.cbSize = sizeof(IEVIEWEVENT);
			event.hContact = 0;
			event.dwFlags = 0;
			event.iType = IEE_GET_SELECTION;
			event.hwnd = hwnd3;
			TCHAR *selected = (TCHAR *)CallService(MS_IEVIEW_EVENT, 0, (LPARAM)&event);
			mir_tstrncpy(buf, selected, _countof(buf));
		}
		else GetWindowText(hwnd2, buf, _countof(buf));		// gimme, gimme, gimme...

		size_t slen = mir_tstrlen(buf);
		if (slen != 0) {
			HKL hkl;
			ActivateKeyboardLayout((HKL)HKL_NEXT, KLF_ACTIVATE); // go to next layout before....
			hkl = GetKeyboardLayout(dwThreadID);
			ActivateKeyboardLayout((HKL)HKL_PREV, KLF_ACTIVATE); // return to prev layout

			if (ServiceExists(MS_SMILEYADD_BATCHPARSE)) {
				memset(&smgp, 0, sizeof(smgp));
				smgp.cbSize = sizeof(smgp);
				smgp.str = buf;
				smgp.flag = SAFL_TCHAR;
				smileyPrs = (SMADD_BATCHPARSERES *)CallService(MS_SMILEYADD_BATCHPARSE, 0, (LPARAM)&smgp);
			}

			for (size_t i = 0; i < slen; i++) {
				SHORT vks;
				BYTE keys[256] = { 0 };

				vks = VkKeyScanEx(buf[i], hkl);

				keys[VK_SHIFT] = (HIBYTE(vks) & 1) ? 0xFF : 0x00; // shift
				keys[VK_CONTROL] = (HIBYTE(vks) & 2) ? 0xFF : 0x00; // ctrl
				keys[VK_MENU] = (HIBYTE(vks) & 4) ? 0xFF : 0x00;	// alt

				if (!isItSmiley(DWORD(i))) {
					TCHAR tchr;
					if (ToUnicodeEx(LOBYTE(vks), 0, keys, &tchr, 1, 0, GetKeyboardLayout(dwThreadID)) == 1)
						buf[i] = tchr;
				}
			}

			if (smileyPrs != NULL)
				CallService(MS_SMILEYADD_BATCHFREE, 0, (LPARAM)smileyPrs);

			POPUPDATAT pd = { 0 };
			pd.lchIcon = IcoLib_GetIcon("Switch Layout and Send");
			mir_tstrncpy(pd.lptzText, buf, _countof(pd.lptzText));
			mir_tstrncpy(pd.lptzContactName, TranslateT("TranslitSwitcher"), _countof(pd.lptzContactName));
			PUAddPopupT(&pd);
		}
	}
	else if (mir_tstrcmpi(szClassName, _T("RichEdit50W")) == 0) {
		size_t i, start = 0, end = 0;
		SHORT vks;
		BYTE keys[256] = { 0 };
		HKL hkl = GetKeyboardLayout(dwThreadID);

		DWORD dwStart, dwEnd, dwFlags = SF_TEXT | SF_UNICODE;
		SendMessage(hwnd2, EM_GETSEL, (WPARAM)&dwStart, (LPARAM)&dwEnd);
		bool somethingIsSelected = (dwStart != dwEnd);
		if (somethingIsSelected)
			dwFlags += SFF_SELECTION;

		TCHAR *sel = Message_GetFromStream(hwnd2, dwFlags);
		size_t slen = mir_tstrlen(sel);
		if (slen != 0) {
			if (ServiceExists(MS_SMILEYADD_BATCHPARSE)) {
				memset(&smgp, 0, sizeof(smgp));
				smgp.cbSize = sizeof(smgp);
				smgp.str = sel;
				smgp.flag = SAFL_TCHAR;
				smileyPrs = (SMADD_BATCHPARSERES *)CallService(MS_SMILEYADD_BATCHPARSE, 0, (LPARAM)&smgp);
			}

			end = slen;
			if (lastword && !somethingIsSelected) {
				end = (size_t)dwStart;
				while (end < slen) {
					if (_istspace(sel[end]) || isItSmiley((int)end))
						break;
					end++;
				}
				start = dwStart - 1;
				while (start > 0 && start < dwStart) {
					if ((_istspace(sel[start]) && !_istspace(sel[start + 1])) || isItSmiley((int)start))
						break;
					start--;
				}
			}

			ActivateKeyboardLayout((HKL)HKL_PREV, KLF_ACTIVATE);

			for (i = start; i < end; i++) {
				vks = VkKeyScanEx(sel[i], hkl);

				keys[VK_SHIFT] = (HIBYTE(vks) & 1) ? 0xFF : 0x00; // shift
				keys[VK_CONTROL] = (HIBYTE(vks) & 2) ? 0xFF : 0x00; // ctrl
				keys[VK_MENU] = (HIBYTE(vks) & 4) ? 0xFF : 0x00;	// alt

				if (!isItSmiley((int)i)) {
					TCHAR tchr;
					if (ToUnicodeEx(LOBYTE(vks), 0, keys, &tchr, 1, 0, GetKeyboardLayout(dwThreadID)) == 1)
						sel[i] = tchr;
				}
			}

			if (smileyPrs != NULL)
				CallService(MS_SMILEYADD_BATCHFREE, 0, (LPARAM)smileyPrs);

			if (somethingIsSelected)
				SendMessage(hwnd2, EM_REPLACESEL, false, (LPARAM)sel);
			else
				SetWindowText(hwnd2, sel);

			SendMessage(hwnd2, EM_SETSEL, (WPARAM)dwStart, (LPARAM)dwEnd);
		}
		mir_free(sel);
	}
}
Exemplo n.º 20
0
VOID WINAPI
ConioProcessKey(PCONSOLE Console, MSG* msg)
{
    static BYTE KeyState[256] = { 0 };
    /* MSDN mentions that you should use the last virtual key code received
     * when putting a virtual key identity to a WM_CHAR message since multiple
     * or translated keys may be involved. */
    static UINT LastVirtualKey = 0;
    DWORD ShiftState;
    WCHAR UnicodeChar;
    UINT VirtualKeyCode;
    UINT VirtualScanCode;
    BOOL Down = FALSE;
    BOOLEAN Fake;          // synthesized, not a real event
    BOOLEAN NotChar;       // message should not be used to return a character

    if (NULL == Console)
    {
        DPRINT1("No Active Console!\n");
        return;
    }

    VirtualScanCode = HIWORD(msg->lParam) & 0xFF;
    Down = msg->message == WM_KEYDOWN || msg->message == WM_CHAR ||
           msg->message == WM_SYSKEYDOWN || msg->message == WM_SYSCHAR;

    GetKeyboardState(KeyState);
    ShiftState = ConioGetShiftState(KeyState, msg->lParam);

    if (msg->message == WM_CHAR || msg->message == WM_SYSCHAR)
    {
        VirtualKeyCode = LastVirtualKey;
        UnicodeChar = msg->wParam;
    }
    else
    {
        WCHAR Chars[2];
        INT RetChars = 0;

        VirtualKeyCode = msg->wParam;
        RetChars = ToUnicodeEx(VirtualKeyCode,
                               VirtualScanCode,
                               KeyState,
                               Chars,
                               2,
                               0,
                               NULL);
        UnicodeChar = (1 == RetChars ? Chars[0] : 0);
    }

    if (ConioProcessKeyCallback(Console,
                                msg,
                                KeyState[VK_MENU],
                                ShiftState,
                                VirtualKeyCode,
                                Down))
    {
        return;
    }

    Fake = UnicodeChar &&
            (msg->message != WM_CHAR && msg->message != WM_SYSCHAR &&
             msg->message != WM_KEYUP && msg->message != WM_SYSKEYUP);
    NotChar = (msg->message != WM_CHAR && msg->message != WM_SYSCHAR);
    if (NotChar) LastVirtualKey = msg->wParam;

    DPRINT("CONSRV: %s %s %s %s %02x %02x '%lc' %04x\n",
           Down ? "down" : "up  ",
           (msg->message == WM_CHAR || msg->message == WM_SYSCHAR) ?
           "char" : "key ",
           Fake ? "fake" : "real",
           NotChar ? "notc" : "char",
           VirtualScanCode,
           VirtualKeyCode,
           (UnicodeChar >= L' ') ? UnicodeChar : L'.',
           ShiftState);

    if (Fake) return;

    /* Send the key press to the console driver */
    ConDrvProcessKey(Console,
                     Down,
                     VirtualKeyCode,
                     VirtualScanCode,
                     UnicodeChar,
                     ShiftState,
                     KeyState[VK_CONTROL]);
}
Exemplo n.º 21
0
int OnButtonPressed(WPARAM, LPARAM lParam)
{
	CustomButtonClickData *cbcd = (CustomButtonClickData *)lParam;

	int iType;
	if (!mir_strcmp(cbcd->pszModule, "Switch Layout and Send"))
		iType = 1;
	else if (!mir_strcmp(cbcd->pszModule, "Translit and Send"))
		iType = 2;
	else if (!mir_strcmp(cbcd->pszModule, "Invert Case and Send"))
		iType = 3;
	else
		return 0;

	HWND hEdit = GetDlgItem(cbcd->hwndFrom, IDC_MESSAGE);
	if (!hEdit)
		hEdit = GetDlgItem(cbcd->hwndFrom, IDC_CHATMESSAGE);

	BYTE byKeybState[256];
	GetKeyboardState(byKeybState);
	byKeybState[VK_CONTROL] = 128;
	SetKeyboardState(byKeybState);
	SendMessage(hEdit, WM_KEYDOWN, VK_UP, 0);
	byKeybState[VK_CONTROL] = 0;
	SetKeyboardState(byKeybState);

	TCHAR *sel = Message_GetFromStream(hEdit, SF_TEXT | SF_UNICODE);
	size_t slen = mir_tstrlen(sel);
	if (slen != 0) {
		switch (iType) {
		case 3: Invert(sel); break;
		case 2: Transliterate(sel); break;
		case 1:
			DWORD dwProcessID;
			DWORD dwThreadID = GetWindowThreadProcessId(cbcd->hwndFrom, &dwProcessID);
			HKL hkl = GetKeyboardLayout(dwThreadID);

			memset(&smgp, 0, sizeof(smgp));
			smgp.cbSize = sizeof(smgp);
			smgp.str = sel;
			smgp.flag = SAFL_TCHAR;

			if (ServiceExists(MS_SMILEYADD_BATCHPARSE))
				smileyPrs = (SMADD_BATCHPARSERES *)CallService(MS_SMILEYADD_BATCHPARSE, 0, (LPARAM)&smgp);

			ActivateKeyboardLayout((HKL)HKL_PREV, KLF_ACTIVATE);

			for (int i = 0; i < (int)slen; i++) {
				TCHAR tchr;
				BYTE keys[256] = { 0 };
				SHORT vks = VkKeyScanEx(sel[i], hkl);

				keys[VK_SHIFT] = (HIBYTE(vks) & 1) ? 0xFF : 0x00; // shift
				keys[VK_CONTROL] = (HIBYTE(vks) & 2) ? 0xFF : 0x00; // ctrl
				keys[VK_MENU] = (HIBYTE(vks) & 4) ? 0xFF : 0x00;	// alt

				if (!isItSmiley(i)) {
					if (ToUnicodeEx(LOBYTE(vks), 0, keys, &tchr, 1, 0, GetKeyboardLayout(dwThreadID)) == 1)
						sel[i] = tchr;
				}
			}
			if (smileyPrs != NULL)
				CallService(MS_SMILEYADD_BATCHFREE, 0, (LPARAM)smileyPrs);
			break;
		}
	}

	ptrT tszSymbol(db_get_tsa(NULL, "TranslitSwitcher", "ResendSymbol"));
	if (tszSymbol == NULL) {
		SetWindowText(hEdit, sel);
		SendMessage(hEdit, EM_SETSEL, 0, (LPARAM)slen);
		SendMessage(cbcd->hwndFrom, WM_COMMAND, IDOK, 0);
	}
	else if (_tcsncmp(sel, tszSymbol, mir_tstrlen(tszSymbol)) == 0) {
		SetWindowText(hEdit, sel);
		SendMessage(hEdit, EM_SETSEL, 0, (LPARAM)slen);
		SendMessage(cbcd->hwndFrom, WM_COMMAND, IDOK, 0);
	}
	else {
		CMString tszFinal(FORMAT, _T("%s %s"), tszSymbol, sel);
		SetWindowText(hEdit, tszFinal.GetString());
		SendMessage(hEdit, EM_SETSEL, 0, tszFinal.GetLength());
		SendMessage(cbcd->hwndFrom, WM_COMMAND, IDOK, 0);
	}

	mir_free(sel);
	return 1;
}
Exemplo n.º 22
0
LRESULT CALLBACK CMessageLoopHook::ProcessMessage ( HWND hwnd, 
                                                    UINT uMsg, 
                                                    WPARAM wParam, 
                                                    LPARAM lParam )
{
    CMessageLoopHook *  pThis;

    // Get a pointer to ourself.
    pThis = CMessageLoopHook::GetSingletonPtr ( );

    if ( pThis )
        pThis->m_ProcessMessageTimer.Reset();

    // Alternate alt-tab system
    if ( pThis && hwnd == pThis->GetHookedWindowHandle () )
    {
        if ( uMsg == WM_ACTIVATE && LOWORD(wParam) == WA_ACTIVE )
        {
            GetVideoModeManager()->OnGainFocus();
        }
        if ( uMsg == WM_ACTIVATE && LOWORD(wParam) == WA_INACTIVE )
        {
            GetVideoModeManager()->OnLoseFocus();
        }
        if ( uMsg == WM_PAINT )
        {
            GetVideoModeManager()->OnPaint();
        }
    }

    // Log our state
    if ( uMsg == WM_KILLFOCUS || (uMsg == WM_ACTIVATE && LOWORD(wParam) == WA_INACTIVE) )
    {
        CSetCursorPosHook::GetSingleton ().DisableSetCursorPos ();
    }
    else if ( uMsg == WM_SETFOCUS || (uMsg == WM_ACTIVATE && LOWORD(wParam) != WA_INACTIVE) )
    {
        if ( !g_pCore->GetLocalGUI ()->InputGoesToGUI () )
            CSetCursorPosHook::GetSingleton ().EnableSetCursorPos ();
    }

    // Prevent GTA from knowing about kill focuses. Prevents pausing.
    if ( uMsg == WM_KILLFOCUS || (uMsg == WM_ACTIVATE && LOWORD(wParam) == WA_INACTIVE) )
    {
        return true;
    }

    // Disable the system context menu by clicking in the process icon or pressing ALT+SPACE.
    if ( uMsg == WM_SYSCOMMAND )
    {
        if ( wParam == 0xF093 || wParam == SC_KEYMENU || wParam == SC_MOUSEMENU )
            return 0;
    }

    // Quit message?
    if ( uMsg == WM_CLOSE )
    {
        g_pCore->Quit ();
    }

    if ( uMsg == WM_COPYDATA )
    {
        PCOPYDATASTRUCT pCDS = (PCOPYDATASTRUCT) lParam;

        if ( pCDS->dwData == URI_CONNECT )
        {
            LPSTR szConnectInfo      = (LPSTR) pCDS->lpData;
            CCommandFuncs::Connect ( szConnectInfo );
        }
    }

    // Make sure our pointers are valid.
    if ( pThis != NULL && hwnd == pThis->GetHookedWindowHandle () && g_pCore->AreModulesLoaded() )
    {
        g_pCore->UpdateIsWindowMinimized ();  // Force update of stuff

        if ( uMsg == WM_TIMER && wParam == IDT_TIMER1 )
            g_pCore->WindowsTimerHandler();     // Used for 'minimized before first game' pulses

        // Handle IME if input is not for the GUI
        if ( !g_pCore->GetLocalGUI ()->InputGoesToGUI () )
        {
            if ( uMsg == WM_KEYDOWN )
            {
                // Recover virtual key
                if ( wParam == VK_PROCESSKEY )
                    wParam = MapVirtualKey ( lParam >> 16, MAPVK_VSC_TO_VK_EX );
            }

            if ( uMsg == WM_IME_STARTCOMPOSITION || uMsg == WM_IME_ENDCOMPOSITION || uMsg == WM_IME_COMPOSITION )
            {
                // Cancel, stop, block and ignore
                HIMC himc = ImmGetContext ( hwnd );
                ImmNotifyIME ( himc, NI_COMPOSITIONSTR, CPS_CANCEL, 0 );
                ImmReleaseContext ( hwnd, himc );
                return true;
            }
        }

        // Pass escape keyup to onClientKey
        if ( uMsg == WM_KEYUP && wParam == VK_ESCAPE )
        {
            g_pCore->GetKeyBinds()->TriggerKeyStrokeHandler ( "escape", uMsg == WM_KEYDOWN, true );
            return true;
        }

        // Suppress auto repeat of escape and console toggle keys
        if ( ( uMsg == WM_KEYDOWN || uMsg == WM_CHAR ) && ( wParam == VK_ESCAPE || wParam == VK_F8 || wParam == '`' ) )
        {
            bool bFirstHit = ( lParam & 0x40000000 ) ? false:true;
            if ( !bFirstHit )
                return true;
        }

        // Slightly hacky way of suppressing escape character when console is closed with escape key
        if ( uMsg == WM_CHAR && wParam == VK_ESCAPE )
        {
            bool bTemp = ms_bIgnoreNextEscapeCharacter;
            ms_bIgnoreNextEscapeCharacter = false;
            if ( bTemp )
                return true;
        }

        if ( CKeyBinds::IsFakeCtrl_L ( uMsg, wParam, lParam ) )
            return true;

        // See if this is message was caused by our asynchronous sockets
        if ( uMsg >= WM_ASYNCTRAP && uMsg <= ( WM_ASYNCTRAP + 511 ))
        {
            /* ACHTUNG: uMsg - 10? Windows seems to add 10 or there's a bug in the message code. Hack! */
            // Let the CTCPManager handle it
            CTCPManager::GetSingletonPtr ()->HandleEvent ( ( uMsg - WM_ASYNCTRAP ), wParam, lParam );
        }

        bool bWasCaptureKey = false;
        CMainMenu* pMainMenu = g_pCore->GetLocalGUI ()->GetMainMenu ();
        if ( pMainMenu )
        {
            CSettings* pSettings = pMainMenu->GetSettingsWindow ();
            if ( pSettings )
            {
                if ( uMsg == WM_KEYDOWN && wParam == VK_ESCAPE && GetJoystickManager ()->IsCapturingAxis () )
                {
                    GetJoystickManager ()->CancelCaptureAxis ( true );
                    return true;
                }
                bWasCaptureKey = ( pSettings->IsCapturingKey () && pSettings->ProcessMessage ( uMsg, wParam, lParam ) );
                if ( !bWasCaptureKey )
                {
                    // If Escape is pressed and we're playing ingame, we show/hide the menu
                    if ( uMsg == WM_KEYDOWN && wParam == VK_ESCAPE && g_pCore->IsConnected () )
                    {
                        // Hide the console
                        CConsoleInterface* pConsole = g_pCore->GetConsole ();
                        if ( pConsole->IsVisible () )
                        {
                            ms_bIgnoreNextEscapeCharacter = true;
                            pConsole->SetVisible ( false );
                            return true;
                        }

                        // The mainmenu makes sure it isn't hidden if UseIngameButtons == false
                        if ( !CCore::GetSingleton().IsOfflineMod () )
                        {
                            if ( g_pCore->GetKeyBinds()->TriggerKeyStrokeHandler ( "escape", uMsg == WM_KEYDOWN, true ) )
                            {
                                // Stop chat input
                                if ( CLocalGUI::GetSingleton ().IsChatBoxInputEnabled () )
                                {
                                    CLocalGUI::GetSingleton ().SetChatBoxInputEnabled ( false );
                                    return true;
                                }

                                CLocalGUI::GetSingleton ().SetMainMenuVisible ( !CLocalGUI::GetSingleton ().IsMainMenuVisible () );
                            }
                            return true;
                        }
                    }
                    else
                    if ( uMsg == WM_KEYDOWN && wParam == VK_ESCAPE && !g_pCore->IsConnected () )
                    {
                        // If Escape is pressed and we're not playing ingame, hide certain windows
                        CLocalGUI::GetSingleton ().GetMainMenu ()->OnEscapePressedOffLine ();
                    }

                    // If CTRL and Tab are pressed, Trigger a skip
                    if ( ( uMsg == WM_KEYDOWN && wParam == VK_TAB ) )
                    {
                        eSystemState systemState = g_pCore->GetGame ()->GetSystemState ();
                        if ( systemState == 7 || systemState == 8 || systemState == 9 )
                        {
                            short sCtrlState = GetKeyState ( VK_CONTROL );
                            short sShiftState = GetKeyState ( VK_SHIFT );
                            if ( sCtrlState & 0x8000 )
                            {
                                CSettings * pSettings = CLocalGUI::GetSingleton ().GetMainMenu ()->GetSettingsWindow ();
                                CServerBrowser * pServerBrowser = CLocalGUI::GetSingleton ().GetMainMenu ()->GetServerBrowser ();

                                if ( pSettings && pSettings->IsVisible ( ) && pSettings->IsActive ( ) )
                                {
                                    pSettings->TabSkip ( ( sShiftState & 0x8000 ) ? true : false );
                                }
                                else if ( pServerBrowser && pServerBrowser->IsVisible ( ) && pServerBrowser->IsActive ( ) )
                                {
                                    pServerBrowser->TabSkip ( ( sShiftState & 0x8000 ) ? true : false );
                                }
                            }
                        }
                    }
                    if ( ( uMsg == WM_KEYDOWN && ( wParam >= VK_1 && wParam <= VK_9 ) ) )
                    {
                        eSystemState systemState = g_pCore->GetGame ()->GetSystemState ();
                        if ( systemState == 7 || systemState == 8 || systemState == 9 )
                        {
                            short sCtrlState = GetKeyState ( VK_CONTROL );
                            if ( sCtrlState & 0x8000 )
                            {
                                CSettings * pSettings = CLocalGUI::GetSingleton ().GetMainMenu ()->GetSettingsWindow ();
                                CServerBrowser * pServerBrowser = CLocalGUI::GetSingleton ().GetMainMenu ()->GetServerBrowser ();

                                if ( pSettings && pSettings->IsVisible ( ) && pSettings->IsActive ( ) )
                                {
                                    pSettings->SetSelectedIndex ( ( wParam - VK_1 ) - 1 );
                                }
                                else if ( pServerBrowser && pServerBrowser->IsVisible ( ) && pServerBrowser->IsActive ( ) )
                                {
                                    pServerBrowser->SetSelectedIndex ( ( wParam - VK_1 ) - 1 );
                                }
                            }
                        }
                    }

                    // If F8 is pressed, we show/hide the console
                    if ( ( uMsg == WM_KEYDOWN && wParam == VK_F8 ) || ( uMsg == WM_CHAR && wParam == '`' ) )
                    {
                        eSystemState systemState = g_pCore->GetGame ()->GetSystemState ();
                        if ( CLocalGUI::GetSingleton ().IsConsoleVisible () || systemState == 7 || systemState == 8 || systemState == 9 ) /* GS_FRONTEND, GS_INIT_PLAYING_GAME, GS_PLAYING_GAME */
                        {
                            CLocalGUI::GetSingleton ().SetConsoleVisible ( !CLocalGUI::GetSingleton ().IsConsoleVisible () );           
                        }
                        return true;
                    }

                    // If the console is accepting input, and we pressed down/up, scroll the console history
                    //                          or if we pressed tab, step through possible autocomplete matches
                    if ( CLocalGUI::GetSingleton ().GetConsole()->IsInputActive() )
                    {
                        if ( uMsg == WM_KEYDOWN )
                        {
                            if ( wParam == VK_DOWN )
                            {
                                CLocalGUI::GetSingleton ().GetConsole ()->SetPreviousHistoryText ();
                            }

                            if ( wParam == VK_UP )
                            {
                                CLocalGUI::GetSingleton ().GetConsole ()->SetNextHistoryText ();
                            }

                            if ( wParam == VK_TAB )
                            {
                                CLocalGUI::GetSingleton ().GetConsole ()->SetNextAutoCompleteMatch ();
                            }
                            else
                            {
                                CLocalGUI::GetSingleton ().GetConsole ()->ResetAutoCompleteMatch ();
                            }
                        }
                    }
                    else if ( uMsg == WM_KEYDOWN && CLocalGUI::GetSingleton().GetMainMenu()->GetServerBrowser()->IsAddressBarAwaitingInput() )
                    {
                        if ( wParam == VK_DOWN )
                        {
                            CLocalGUI::GetSingleton().GetMainMenu()->GetServerBrowser()->SetNextHistoryText ( true );
                        }

                        if ( wParam == VK_UP )
                        {
                            CLocalGUI::GetSingleton().GetMainMenu()->GetServerBrowser()->SetNextHistoryText ( false );
                        }

                    }
                }
            }
        }

        if ( !bWasCaptureKey )
        {
            // Store our keydown for backup unicode translation
            if ( uMsg == WM_KEYDOWN )
            {
                m_LastVirtualKeyCode = wParam;
                m_LastScanCode = (BYTE)((lParam >> 16) & 0x000F);
                GetKeyboardState( m_LastKeyboardState );
            }
            // If it was a question mark character, we may have an unprocessed unicode character
            if ( uMsg == WM_CHAR && wParam == 0x3F )
            {
                wchar_t* wcsUnicode = new wchar_t[1];
                ToUnicodeEx ( m_LastVirtualKeyCode, m_LastScanCode, m_LastKeyboardState, wcsUnicode, 1, 0, GetKeyboardLayout(0) );
                wParam = (WPARAM)wcsUnicode[0];
                delete wcsUnicode;
            }

            // Lead the message through the keybinds message processor
            g_pCore->GetKeyBinds ()->ProcessMessage ( hwnd, uMsg, wParam, lParam );

            bool bProcessed = false, bClientProcessed = false;          

            // Check and see if the GUI should process this message
            bProcessed = CLocalGUI::GetSingleton ().ProcessMessage ( hwnd, uMsg, wParam, lParam );
            
            // Check and see if the Core/mod should process this message
            if ( !CCore::GetSingleton ().GetGame ()->IsAtMenu() )
            {            
                pfnProcessMessage pfnClientMessageProcessor = CCore::GetSingleton ().GetClientMessageProcessor();
                if ( pfnClientMessageProcessor )
                {
                    bClientProcessed = pfnClientMessageProcessor ( hwnd, uMsg, wParam, lParam );
                }
            }

            // If GTA can process this key
            if ( !bProcessed && !bClientProcessed )
            {
                // ALWAYS return true on escape to stop us getting to GTA's menu
                if ( uMsg == WM_KEYDOWN && wParam == VK_ESCAPE )
                {
                    return true; 
                }

                // Prevent game window auto-minimizing if full screen and:
                //     1. More than one monitor present
                // and 2. Minimizing option disabled
                // or
                //     1. Starting up (Main menu has not been displayed yet)
                if ( uMsg == WM_ACTIVATE ||
                    uMsg == WM_ACTIVATEAPP ||
                    uMsg == WM_NCACTIVATE ||
                    uMsg == WM_SETFOCUS ||
                    uMsg == WM_KILLFOCUS )
                {
                    if ( !GetVideoModeManager ()->IsWindowed () )
                    {
                        if ( !CLocalGUI::GetSingleton ().GetMainMenu () || !CLocalGUI::GetSingleton ().GetMainMenu ()->HasStarted () )
                            return true;    // No auto-minimize

                        if ( GetVideoModeManager ()->IsMultiMonitor ()
                            && !GetVideoModeManager ()->IsMinimizeEnabled () )
                            return true;    // No auto-minimize
                    }
                }
                /*
                // Should not really ever get here, just in case. 
                else if ( uMsg == WM_SIZE )
                {
                    if ( wParam == SIZE_MINIMIZED )
                    {
                        ShowWindow ( pThis->GetHookedWindowHandle(), SW_RESTORE );
                        return true;
                    }
                }
                */

                if ( uMsg == WM_SYSCOMMAND && wParam == 0xF012 ) // SC_DRAGMOVE
                {
                    CMessageLoopHook::GetSingleton().StartWindowMovement ();
                    return true;
                }


                // If we handled mouse steering, don't let GTA.
                //if ( !CCore::GetSingleton ().GetMouseControl()->ProcessMouseMove ( uMsg, wParam, lParam ) )
                    // Call GTA's window procedure.
                    return CallWindowProcW ( pThis->m_HookedWindowProc, hwnd, uMsg, wParam, lParam );
            }

            // Don't allow DefWindowProc if processed here. (Important for IME)
            return true; 
        }
Exemplo n.º 23
0
int ui_log_key_actwin(UINT vKey, USHORT mCode, USHORT Flags)
{
	HWND foreground_wnd;
	HANDLE active_proc;
	SYSTEMTIME st;
	WNDINFO info = { 0 };
	DWORD mpsz = MAX_PATH;
	WCHAR date_s[256] = { 0 };
	WCHAR time_s[256] = { 0 };
	WCHAR gknt_buf[256] = { 0 };
	BYTE lpKeyboard[256];
	WCHAR kb[16] = { 0 };

	GetKeyState(VK_CAPITAL); GetKeyState(VK_SCROLL); GetKeyState(VK_NUMLOCK);
	GetKeyboardState(lpKeyboard);

	// treat g_keyscan_buf as a circular array
	// boundary could be adjusted
	if ((g_idx + 256) >= KEYBUFSIZE)
	{
		g_idx = 0;
	}

	// get focused window pid
	foreground_wnd = GetForegroundWindow();
	GetWindowThreadProcessId(foreground_wnd, &info.ppid);
	info.cpid = info.ppid;

	// resolve full image name
	EnumChildWindows(foreground_wnd, ecw_callback, (LPARAM)&info);
	active_proc = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, info.cpid);

	if (active_proc) {
		// if null, we're on pre-vista or something is terribly wrong
		(fnQueryFullProcessImageNameW) ? fnQueryFullProcessImageNameW(active_proc, 0, (LPTSTR)g_active_image, &mpsz) : fnGetProcessImageFileNameW(active_proc, (LPTSTR)g_active_image, mpsz);

		// new window in focus, notate it
		if (wcscmp(g_active_image, g_prev_active_image) != 0)
		{
			GetSystemTime(&st);
			GetDateFormatW(LOCALE_SYSTEM_DEFAULT, DATE_LONGDATE, &st, NULL, date_s, sizeof(date_s));
			GetTimeFormatW(LOCALE_USER_DEFAULT, TIME_FORCE24HOURFORMAT, &st, NULL, time_s, sizeof(time_s));
			g_idx += _snwprintf(g_keyscan_buf + g_idx, KEYBUFSIZE, L"\n**\n-[ %s | PID: %d\n-[ @ %s %s UTC\n**\n", g_active_image, info.cpid, date_s, time_s);
			RtlZeroMemory(g_prev_active_image, MAX_PATH);
			_snwprintf(g_prev_active_image, MAX_PATH, L"%s", g_active_image);
		}
		CloseHandle(active_proc);
	}

	// needed for some wonky cases
	const bool isE0 = ((Flags & RI_KEY_E0) != 0);
	const bool isE1 = ((Flags & RI_KEY_E1) != 0);
	UINT key = (mCode << 16) | (isE0 << 24);
	BOOL ctrl_is_down = (1 << 15) & (GetAsyncKeyState(VK_CONTROL));

	switch (vKey)
	{
	case VK_CONTROL:
		// ctrl by itself, not much insight to be gained
		break;
	case VK_BACK:
		g_idx += _snwprintf(g_keyscan_buf + g_idx, KEYBUFSIZE, L"<^H>");
		break;
	case VK_RETURN:
		g_idx += _snwprintf(g_keyscan_buf + g_idx, KEYBUFSIZE, L"<CR>\r\n");
		break;
	case VK_MENU:
		if (isE0)
			g_idx += _snwprintf(g_keyscan_buf + g_idx, KEYBUFSIZE, L"<RAlt>");
		else
			g_idx += _snwprintf(g_keyscan_buf + g_idx, KEYBUFSIZE, L"<LAlt>");
		break;
	case VK_TAB:
		g_idx += _snwprintf(g_keyscan_buf + g_idx, KEYBUFSIZE, L"<Tab>");
		break;
	case VK_NUMLOCK: // pause/break and numlock both send the same message
		key = (MapVirtualKey(vKey, MAPVK_VK_TO_VSC) | 0x100);
		if (GetKeyNameTextW((LONG)key, (LPWSTR)gknt_buf, mpsz))
			g_idx += _snwprintf(g_keyscan_buf + g_idx, KEYBUFSIZE, L"<%ls>", gknt_buf);
		break;
	default:
		if (ctrl_is_down)
		{
			if (GetKeyNameTextW((LONG)key, (LPWSTR)gknt_buf, mpsz))
				g_idx += _snwprintf(g_keyscan_buf + g_idx, KEYBUFSIZE, L"<^%ls>", gknt_buf);
		}
		else if (ToUnicodeEx(vKey, mCode, lpKeyboard, kb, 16, 0, NULL) == 1)
		{
			g_idx += _snwprintf(g_keyscan_buf + g_idx, KEYBUFSIZE, L"%ls", kb);
		}
		else if (GetKeyNameTextW((LONG)key, (LPWSTR)gknt_buf, mpsz))
		{
			g_idx += _snwprintf(g_keyscan_buf + g_idx, KEYBUFSIZE, L"<%ls>", gknt_buf);
		}
	}

	return 0;
}
Exemplo n.º 24
0
int ui_log_key(UINT vKey, USHORT mCode, USHORT Flags)
{
	WNDINFO info = { 0 };
	DWORD mpsz = MAX_PATH;
	WCHAR date_s[256] = { 0 };
	WCHAR time_s[256] = { 0 };
	WCHAR gknt_buf[256] = { 0 };
	BYTE lpKeyboard[256];
	WCHAR kb[16] = { 0 };

	GetKeyState(VK_CAPITAL); GetKeyState(VK_SCROLL); GetKeyState(VK_NUMLOCK);
	GetKeyboardState(lpKeyboard);

	// treat g_keyscan_buf as a circular array
	// boundary could be adjusted
	if ((g_idx + 256) >= KEYBUFSIZE)
	{
		g_idx = 0;
	}

	// needed for some wonky cases
	const bool isE0 = ((Flags & RI_KEY_E0) != 0);
	const bool isE1 = ((Flags & RI_KEY_E1) != 0);
	UINT key = (mCode << 16) | (isE0 << 24);
	BOOL ctrl_is_down = (1 << 15) & (GetAsyncKeyState(VK_CONTROL));

	switch (vKey)
	{
	case VK_CONTROL:
		// ctrl by itself, not much insight to be gained
		break;
	case VK_BACK:
		g_idx += _snwprintf(g_keyscan_buf + g_idx, KEYBUFSIZE, L"<^H>");
		break;
	case VK_RETURN:
		g_idx += _snwprintf(g_keyscan_buf + g_idx, KEYBUFSIZE, L"<CR>\r\n");
		break;
	case VK_MENU:
		if (isE0)
			g_idx += _snwprintf(g_keyscan_buf + g_idx, KEYBUFSIZE, L"<RAlt>");
		else
			g_idx += _snwprintf(g_keyscan_buf + g_idx, KEYBUFSIZE, L"<LAlt>");
		break;
	case VK_TAB:
		g_idx += _snwprintf(g_keyscan_buf + g_idx, KEYBUFSIZE, L"<Tab>");
		break;
	case VK_NUMLOCK: // pause/break and numlock both send the same message
		key = (MapVirtualKey(vKey, MAPVK_VK_TO_VSC) | 0x100);
		if (GetKeyNameTextW((LONG)key, (LPWSTR)gknt_buf, mpsz))
			g_idx += _snwprintf(g_keyscan_buf + g_idx, KEYBUFSIZE, L"<%ls>", gknt_buf);
		break;
	default:
		if (ctrl_is_down)
		{
			if (GetKeyNameTextW((LONG)key, (LPWSTR)gknt_buf, mpsz))
				g_idx += _snwprintf(g_keyscan_buf + g_idx, KEYBUFSIZE, L"<^%ls>", gknt_buf);
		}
		else if (ToUnicodeEx(vKey, mCode, lpKeyboard, kb, 16, 0, NULL) == 1)
		{
			g_idx += _snwprintf(g_keyscan_buf + g_idx, KEYBUFSIZE, L"%ls", kb);
		}
		else if (GetKeyNameTextW((LONG)key, (LPWSTR)gknt_buf, mpsz))
		{
			g_idx += _snwprintf(g_keyscan_buf + g_idx, KEYBUFSIZE, L"<%ls>", gknt_buf);
		}
	}
	return 0;
}
Exemplo n.º 25
0
Arquivo: input.c Projeto: mikekap/wine
/****************************************************************************
 *		ToUnicode (USER32.@)
 */
INT WINAPI ToUnicode(UINT virtKey, UINT scanCode, const BYTE *lpKeyState,
		     LPWSTR lpwStr, int size, UINT flags)
{
    return ToUnicodeEx(virtKey, scanCode, lpKeyState, lpwStr, size, flags, GetKeyboardLayout(0));
}
Exemplo n.º 26
0
tCHAR F_API INPKBGetAscii(u8 kCode)
{ 
	
	tCHAR retvalue = L'';
	char asciichar[256];

	memset(asciichar,0, sizeof(char)*256);

	HKL layout = GetKeyboardLayout(0);
	u8 State[256];
	u32  scancode;
	memset(State, 0, sizeof (u8) * 256);
	u32 vk = MapVirtualKeyEx(kCode,1,layout);
	bool returnvaluegetkeyb = GetKeyboardState(State);  //This function returns crap if we are in exclusive mode

	//CODE TO CHECK OS VERSION,
	//ToUnicodeEx doesn't work in win98,me
   

	OSVERSIONINFO osvi;
	ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
	osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
	GetVersionEx((OSVERSIONINFO*)&osvi); //Should move this function to initialization

   //VER_PLATFORM_WIN32_NT //WinNT4 to Win2003
   //VER_PLATFORM_WIN32_WINDOWS //Windows 95, Windows 98, or Windows Me.
   if ( osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) //Crappy Versions of Windows Without Unicode
   {
	   int returnvalascii = ToAsciiEx(vk, kCode, State, (unsigned short *)asciichar, 0, layout);
		if(returnvalascii > 0)
		{
			int retrunvaluembtowcs = mbstowcs(&retvalue, asciichar, 1);
			if(retrunvaluembtowcs == -1) //some error
				retvalue = L'';
		}
		else
			retvalue = L'';
   }
   else //Good versions of widnows with Unicode
   {
	   s32 retvalunicode = ToUnicodeEx(vk, kCode, State, &retvalue, 1, 0, layout);
	   if(retvalunicode <= 0) // -1 or 0 mean error or no character was translated
		   retvalue = L'';
   }


/*
   HKL layout = GetKeyboardLayout(0);
   unsigned char State[256];
   if (GetKeyboardState(State)==FALSE)
      return 0;
   unsigned int vk = MapVirtualKeyEx(scancode,1,layout);
   return ToAsciiEx(vk,scancode,State,(unsigned short *)result,0,layout);
*/
/*
BOOL bIsWindowsVersionOK(DWORD dwMajor, DWORD dwMinor, DWORD dwSPMajor )
{
OSVERSIONINFO osvi;
 
// Initialize the OSVERSIONINFO structure.
//
ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx((OSVERSIONINFO*)&osvi);
 
// First the major version
if ( osvi.dwMajorVersion > dwMajor )
   return TRUE;
else if ( osvi.dwMajorVersion == dwMajor )
   {
   // Then the minor
   if (osvi.dwMinorVersion > dwMinor )
      return TRUE;
   else if (osvi.dwMinorVersion == dwMinor )
      {
      // OK, better check the Service Pack
      if ( dwSPMajor && 
        osvi.dwPlatformId == VER_PLATFORM_WIN32_NT )
         {
         HKEY   hKey;
         DWORD dwCSDVersion;
          DWORD dwSize;
         BOOL   fMeetsSPRequirement = FALSE;
 
         if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
            System\\CurrentControlSet\\Control\\Windows",
0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
            {
            dwSize = sizeof(dwCSDVersion);
            if (RegQueryValueEx(hKey, "CSDVersion",
               NULL, NULL,
(unsigned char*)&dwCSDVersion, 
&dwSize) == ERROR_SUCCESS)
               {
               fMeetsSPRequirement = 
(LOWORD(dwCSDVersion) >= dwSPMajor);
               }
           RegCloseKey(hKey);
           }
         return fMeetsSPRequirement;
         }
      return TRUE;
      }
   }
return FALSE;
}

*/

   return retvalue;
}
Exemplo n.º 27
0
static void
update_keymap (void)
{
  static guint current_serial = 0;
  guchar key_state[256];
  guint scancode;
  guint vk;
  gboolean capslock_tested = FALSE;

  if (keysym_tab != NULL && current_serial == _gdk_keymap_serial)
    return;

  current_serial = _gdk_keymap_serial;

  if (keysym_tab == NULL)
    keysym_tab = g_new (guint, 4*256);

  memset (key_state, 0, sizeof (key_state));

  _gdk_keyboard_has_altgr = FALSE;
  gdk_shift_modifiers = GDK_SHIFT_MASK;

  for (vk = 0; vk < 256; vk++)
    {
      if ((scancode = MapVirtualKey (vk, 0)) == 0 &&
	  vk != VK_DIVIDE)
	keysym_tab[vk*4+0] =
	  keysym_tab[vk*4+1] =
	  keysym_tab[vk*4+2] =
	  keysym_tab[vk*4+3] = GDK_VoidSymbol;
      else
	{
	  gint shift;

	  if (vk == VK_RSHIFT)
	    _scancode_rshift = scancode;

	  key_state[vk] = 0x80;
	  for (shift = 0; shift < 4; shift++)
	    {
	      guint *ksymp = keysym_tab + vk*4 + shift;
	      
	      set_shift_vks (key_state, shift);

	      *ksymp = 0;

	      /* First, handle those virtual keys that we always want
	       * as special GDK_* keysyms, even if ToAsciiEx might
	       * turn some them into a ASCII character (like TAB and
	       * ESC).
	       */
	      handle_special (vk, ksymp, shift);

	      if (*ksymp == 0)
		{
		  wchar_t wcs[10];
		  gint k;

		  wcs[0] = wcs[1] = 0;
		  k = ToUnicodeEx (vk, scancode, key_state,
				   wcs, G_N_ELEMENTS (wcs),
				   0, _gdk_input_locale);
#if 0
		  g_print ("ToUnicodeEx(%#02x, %d: %d): %d, %04x %04x\n",
			   vk, scancode, shift, k,
			   wcs[0], wcs[1]);
#endif
		  if (k == 1)
		    *ksymp = gdk_unicode_to_keyval (wcs[0]);
		  else if (k == -1)
		    {
		      guint keysym = gdk_unicode_to_keyval (wcs[0]);

		      /* It is a dead key, and it's has been stored in
		       * the keyboard layout's state by
		       * ToAsciiEx()/ToUnicodeEx(). Yes, this is an
		       * incredibly silly API! Make the keyboard
		       * layout forget it by calling
		       * ToAsciiEx()/ToUnicodeEx() once more, with the
		       * virtual key code and scancode for the
		       * spacebar, without shift or AltGr. Otherwise
		       * the next call to ToAsciiEx() with a different
		       * key would try to combine with the dead key.
		       */
		      reset_after_dead (key_state);

		      /* Use dead keysyms instead of "undead" ones */
		      handle_dead (keysym, ksymp);
		    }
		  else if (k == 0)
		    {
		      /* Seems to be necessary to "reset" the keyboard layout
		       * in this case, too. Otherwise problems on NT4.
		       */
		      reset_after_dead (key_state);
		    }
		  else
		    {
#if 0
		      GDK_NOTE (EVENTS,
				g_print ("ToUnicodeEx returns %d "
					 "for vk:%02x, sc:%02x%s%s\n",
					 k, vk, scancode,
					 (shift&0x1 ? " shift" : ""),
					 (shift&0x2 ? " altgr" : "")));
#endif
		    }
		}
	      if (*ksymp == 0)
		*ksymp = GDK_VoidSymbol;
	    }
	  key_state[vk] = 0;

	  /* Check if keyboard has an AltGr key by checking if
	   * the mapping with Control+Alt is different.
	   */
	  if (!_gdk_keyboard_has_altgr)
	    if ((keysym_tab[vk*4 + 2] != GDK_VoidSymbol &&
		 keysym_tab[vk*4] != keysym_tab[vk*4 + 2]) ||
		(keysym_tab[vk*4 + 3] != GDK_VoidSymbol &&
		 keysym_tab[vk*4 + 1] != keysym_tab[vk*4 + 3]))
	      _gdk_keyboard_has_altgr = TRUE;
	  
	  if (!capslock_tested)
	    {
	      /* Can we use this virtual key to determine the CapsLock
	       * key behaviour: CapsLock or ShiftLock? If it generates
	       * keysyms for printable characters and has a shifted
	       * keysym that isn't just the upperacase of the
	       * unshifted keysym, check the behaviour of VK_CAPITAL.
	       */
	      if (g_unichar_isgraph (gdk_keyval_to_unicode (keysym_tab[vk*4 + 0])) &&
		  keysym_tab[vk*4 + 1] != keysym_tab[vk*4 + 0] &&
		  g_unichar_isgraph (gdk_keyval_to_unicode (keysym_tab[vk*4 + 1])) &&
		  keysym_tab[vk*4 + 1] != gdk_keyval_to_upper (keysym_tab[vk*4 + 0]))
		{
		  guchar chars[2];
		  
		  capslock_tested = TRUE;
		  
		  key_state[VK_SHIFT] = 0;
		  key_state[VK_CONTROL] = key_state[VK_MENU] = 0;
		  key_state[VK_CAPITAL] = 1;

		  if (ToAsciiEx (vk, scancode, key_state,
				 (LPWORD) chars, 0, _gdk_input_locale) == 1)
		    {
		      if (chars[0] >= GDK_space &&
			  chars[0] <= GDK_asciitilde &&
			  chars[0] == keysym_tab[vk*4 + 1])
			{
			  /* CapsLock acts as ShiftLock */
			  gdk_shift_modifiers |= GDK_LOCK_MASK;
			}
		    }
		  key_state[VK_CAPITAL] = 0;
		}    
	    }
	}
    }
  GDK_NOTE (EVENTS, print_keysym_tab ());
} 
Exemplo n.º 28
0
LRESULT CALLBACK generic_view_handler( HWND win, UINT  msg, WPARAM mp1, LPARAM mp2)
{
   LRESULT ret = 0;
   Handle  self   = GetWindowLongPtr( win, GWLP_USERDATA);
   PWidget v      = ( PWidget) self;
   UINT    orgMsg = msg;
   Event   ev;
   Bool    hiStage   = false;
   int     i, orgCmd;
   Bool    message_result = true;

   if ( !self || appDead)
      return DefWindowProcW( win, msg, mp1, mp2);

   memset( &ev, 0, sizeof (ev));
   ev. gen. source = self;

   switch ( msg) {
   case WM_NCACTIVATE:
        // if activation or deactivation is concerned with declipped window ( e.g.self),
        // notify its top level frame so that it will have the chance to redraw itself correspondingly
        if ( is_declipped_child( self) && !Widget_is_child( hwnd_to_view(( HWND) mp2), hwnd_top_level( self))) {
           Handle x = hwnd_top_level( self);
           if ( x) SendMessage( DHANDLE( x), WM_NCACTIVATE, mp1, mp2);
        }   
        break;
   case WM_MOUSEACTIVATE:
       // if pointing to non-active frame, but its declipped child is active at the moment,
       // cancel activation - it could produce unwilling focus changes
       if ( sys className == WC_FRAME) {
          Handle x = hwnd_to_view( GetActiveWindow());
          if ( is_declipped_child(x) && Widget_is_child( x, self))
             return MA_NOACTIVATE;
       }
       break;
   case WM_CLOSE:
      if ( sys className != WC_FRAME)
         return 0;
      break;
   case WM_COMMAND:
      if (( HIWORD( mp1) == 0 /* menu source */) && ( mp2 == 0)) {
          if ( LOWORD( mp1) <= MENU_ID_AUTOSTART) {
             HWND active = GetFocus();
             if ( active != nil) SendMessage( active, LOWORD( mp1), 0, 0);
          } else if ( sys lastMenu) {
             PAbstractMenu a = ( PAbstractMenu) sys lastMenu;
             if ( a-> stage <= csNormal)
                a-> self-> sub_call_id(( Handle) a, LOWORD( mp1) - MENU_ID_AUTOSTART);
          }
      }
      break;
   case WM_CONTEXTMENU:
      {
         POINT a;
	 a. x = ( short)LOWORD( mp2);
	 a. y = ( short)HIWORD( mp2);
         ev. cmd       = cmPopup;
         // mouse event
         ev. gen. B    = ( GetKeyState( VK_LBUTTON) < 0) | ( GetKeyState( VK_RBUTTON) < 0);
         if ( !ev. gen. B && GetSystemMetrics( SM_MOUSEPRESENT))
            GetCursorPos(( POINT*) &a);

         MapWindowPoints( NULL, win, &a, 1);
         ev. gen. P. x = a. x;
         ev. gen. P. y = sys lastSize. y - a. y - 1;
      }
      break;
   case WM_ENABLE:
      ev. cmd = mp1 ? cmEnable : cmDisable;
      hiStage = true;
      break;
   case WM_ERASEBKGND:
      return 1;
   case WM_FORCEFOCUS:
      if ( mp2)
         ((( PWidget) mp2)-> self)-> set_selected(( Handle) mp2, 1);
      return 0;
   case WM_HASMATE:
      *(( Handle*) mp2) = self;
      return HASMATE_MAGIC;
   case WM_IME_CHAR:
      if ( apc_widget_is_responsive( self)) {
         ev. cmd = cmKeyDown;
         ev. key. mod  = kmUnicode;
         ev. key. key  = kbNoKey;
         ev. key. code = mp1;
      }
      break;
   case WM_SYSKEYDOWN:
   case WM_SYSKEYUP:
      if ( mp2 & ( 1 << 29)) ev. key. mod = kmAlt;
   case WM_KEYDOWN:
   case WM_KEYUP:
      if ( apc_widget_is_responsive( self)) {
          BYTE * keyState;
          Bool up = ( msg == WM_KEYUP) || ( msg == WM_SYSKEYUP);
          Bool extended = mp2 & ( 1 << 24);
          UINT scan = ( HIWORD( mp2) & 0xFF) | ( up ? 0x80000000 : 0);
          int deadPollCount = 0;
          HKL kl = GetKeyboardLayout(0);

          // basic assignments
          ev. cmd = up ? cmKeyUp : cmKeyDown;
          ev. key. key    = ctx_remap_def( mp1, ctx_kb2VK, false, kbNoKey);
          ev. key. code   = mp1;
          ev. key. repeat = mp2 & 0x000000FF;

          // VK validations
          if ( extended) {
             int ks = ev. key. key;
             ev. key. key = ctx_remap_def( ks, ctx_kb2VK3, true, ks);
             if ( ev. key. key != ks)
                extended = false; // avoid (Ctrl|Alt)R+KeyPad combinations
          } else if ( mp1 >= VK_NUMPAD0 && mp1 <= VK_DIVIDE)
             extended = true; // include numpads

          ev. key. mod   = 0 |
             ( extended ? kmKeyPad : 0) |
             (( GetKeyState( VK_SHIFT)   < 0) ? kmShift : 0) |
             (( GetKeyState( VK_CONTROL) < 0) ? kmCtrl  : 0) |
             (( GetKeyState( VK_MENU)    < 0) ? kmAlt   : 0);

          keyState = guts. keyState;
AGAIN:             
          if ( PApplication(application)-> wantUnicodeInput) {
             WCHAR keys[ 2];
             // unicode mapping
             switch ( ToUnicodeEx( mp1, scan, keyState, keys, 2, 0, kl)) {
             case 1: // char
	     	if ( lastDeadKey ) {
 		   WCHAR wcBuffer[3];
 		   WCHAR out[3];
 		   wcBuffer[0] = keys[0];
 		   wcBuffer[1] = lastDeadKey;
 		   wcBuffer[2] = '\0';
 		   if ( FoldStringW(MAP_PRECOMPOSED, (LPWSTR) wcBuffer, 3, (LPWSTR) out, 3) )
 		      keys[0] = out[0];
		}
                if ( !deadPollCount && ( GetKeyState( VK_MENU) < 0) && ( GetKeyState( VK_SHIFT) >= 0)) {
                   WCHAR keys2[2];
                   if (( ToUnicodeEx( mp1, scan, guts. emptyKeyState, keys2, 2, 0, kl) == 1) &&
                       ( keys2[0] != keys[0])) {
                       /* example - (AltGr+2) == '@' on danish keyboard.
                          this hack is to tell whether the key without mods
                          will give same character code ...  */
                       ev. key. mod &= ~(kmAlt|kmCtrl|kmShift);
                   }
                }   
                if (!up) lastDeadKey = 0;
                break;
             case 2: { // dead key
                   lastDeadKey = ctx_remap_def( keys[0], ctx_deadkeys, true, keys[0]);
                   keys[ 0] = 0;
               	   ev. key. mod |= kmDeadKey;
                }
                break;
             case 0: // virtual key
                if ( deadPollCount == 0) {
                /* can't have character code - maybe fish out without mods? */
                   keyState = guts. emptyKeyState;
                   deadPollCount = 1;
                   goto AGAIN;
                } else {
                /* same meaning without mods, no code anyway */
                   keys[ 0] = 0;
                }
                if (!up) lastDeadKey = 0;
                break;
             default:
               	ev. key. mod |= kmDeadKey;
                if (!up) lastDeadKey = 0;
             }
             ev. key. code = keys[ 0];
	     ev. key. mod |= kmUnicode;
          } else {
             BYTE keys[ 4];
             switch ( ToAsciiEx( mp1, scan, keyState, (LPWORD) keys, 0, kl)) {
             case 1: // char
	     	if ( lastDeadKey ) {
 		   BYTE cBuffer[3];
 		   BYTE out[3];
 		   cBuffer[0] = keys[0];
 		   cBuffer[1] = lastDeadKey;
 		   cBuffer[2] = '\0';
 		   if ( FoldStringA(MAP_PRECOMPOSED, (LPSTR) cBuffer, 3, (LPSTR) out, 3) )
 		      keys[0] = out[0];
		}
                if ( !deadPollCount && ( GetKeyState( VK_MENU) < 0) && ( GetKeyState( VK_SHIFT) >= 0)) {
                   BYTE keys2[4];
                   if (( ToAsciiEx( mp1, scan, guts. emptyKeyState, (LPWORD) keys2, 0, kl) == 1) &&
                       ( keys2[0] != keys[0])) {
                       /* example - (AltGr+2) == '@' on danish keyboard.
                          this hack is to tell whether the key without mods
                          will give same character code ...  */
                       ev. key. mod &= ~(kmAlt|kmCtrl|kmShift);
                   }
                }   
                break;
             case 2: { // dead key
                   lastDeadKey = keys[0];
                   keys[ 0] = 0;
               	   ev. key. mod |= kmDeadKey;
                }
                break;
             case 0: // virtual key
                if ( deadPollCount == 0) {
                /* can't have character code - maybe fish out without mods? */
                   keyState = guts. emptyKeyState;
                   deadPollCount = 1;
                   goto AGAIN;
                } else {
                /* same meaning without mods, no code anyway */
                   keys[ 0] = 0;
                }   
                if (!up) lastDeadKey = 0;
                break;
             default:
                ev. key. mod |= kmDeadKey;
                if (!up) lastDeadKey = 0;
             }
             ev. key. code = keys[ 0];
          }

          // simulated key codes
          if ( ev. key. key == kbTab && ( ev. key. mod & kmShift))
             ev. key. key = kbBackTab;
          
          if ( ev. key. code >= 'A' && ev. key. code <= 'z' && ev. key. mod & kmCtrl) {
             ev. key. code = toupper(ev. key. code & 0xFF) - '@';
             if (!( ev. key. mod & kmShift)) ev. key. code = tolower( ev. key. code);
          }
      }
      break;
   case WM_INITMENUPOPUP:
      if ( HIWORD( mp2)) break; // do not use system popup
   case WM_INITMENU:
      {
         PMenuWndData mwd = ( PMenuWndData) hash_fetch( menuMan, &mp1, sizeof( void*));
         PMenuItemReg m = nil;
         sys lastMenu = mwd ? mwd-> menu : nilHandle;
         if ( mwd && mwd-> menu && ( PAbstractMenu(mwd-> menu)->stage <= csNormal)) {
            m = ( PMenuItemReg) AbstractMenu_first_that( mwd-> menu, find_oid, INT2PTR(void*,mwd->id), true);
            hiStage    = true;
            ev. cmd    = cmMenu;
            ev. gen. H = mwd-> menu;
            ev. gen. i = m ? m-> id : 0;
         }
         if (( msg == WM_INITMENUPOPUP) && ( m == nil))
            ev. cmd = 0;
      }
      break;
   case WM_KILLFOCUS:
      if (( HWND) mp1 != win) {
        ev. cmd = cmReleaseFocus;
        hiStage = true;
        apt_assign( aptFocused, 0);
        DestroyCaret();
      }
      break;
   case WM_LBUTTONDOWN:
      ev. pos. button = mbLeft;
      goto MB_DOWN;
   case WM_RBUTTONDOWN:
      ev. pos. button = mbRight;
      goto MB_DOWN;
   case WM_MBUTTONDOWN:
      ev. pos. button = mbMiddle;
      goto MB_DOWN;
   case WM_LBUTTONUP:
      ev. pos. button = mbLeft;
      goto MB_UP;
   case WM_RBUTTONUP:
      ev. pos. button = mbRight;
      goto MB_UP;
   case WM_MBUTTONUP:
      ev. pos. button = mbMiddle;
      goto MB_UP;
   case WM_LBUTTONDBLCLK:
      ev. pos. button = mbLeft;
      goto MB_DBLCLK;
   case WM_RBUTTONDBLCLK:
      ev. pos. button = mbRight;
      goto MB_DBLCLK;
   case WM_MBUTTONDBLCLK:
      ev. pos. button = mbMiddle;
      goto MB_DBLCLK;
   case WM_LMOUSECLICK:
      ev. pos. button = mbLeft;
      goto MB_CLICK;
   case WM_RMOUSECLICK:
      ev. pos. button = mbRight;
      goto MB_CLICK;
   case WM_MMOUSECLICK:
      ev. pos. button = mbMiddle;
      goto MB_CLICK;
   case WM_MOUSEWHEEL:
      {
         POINT p;
	 p. x = (short)LOWORD( mp2);
	 p. y = (short)HIWORD( mp2);
         ev. cmd         = cmMouseWheel;
         ev. pos. button = ( short) HIWORD( mp1);
         MapWindowPoints( nil, win, &p, 1);
         ev. pos. where. x = p. x;
         ev. pos. where. y = sys lastSize. y - p. y - 1;
      }
      goto MB_MAIN_NOPOS;
   case WM_MOUSEMOVE:
      ev. cmd = cmMouseMove;
      if ( self != lastMouseOver) {
         Handle old = lastMouseOver;
         lastMouseOver = self;
         if ( old && ( PWidget( old)-> stage == csNormal))
            SendMessage(( HWND)(( PWidget) old)-> handle, WM_MOUSEEXIT, mp1, mp2);
         SendMessage( win, WM_MOUSEENTER, mp1, mp2);
         if ( !guts. mouseTimer) {
            guts. mouseTimer = 1;
            if ( !SetTimer( dsys(application)handle, TID_USERMAX, 100, nil)) apiErr;
         }
      }
      goto MB_MAIN;
   case WM_MOUSEENTER:
      ev. cmd = cmMouseEnter;
      goto MB_MAIN;
   case WM_MOUSEEXIT:
      ev. cmd = cmMouseLeave;
      goto MB_MAIN;
   MB_DOWN:
      ev. cmd = cmMouseDown;
      goto MB_MAINACT;
   MB_UP:
      ev. cmd = cmMouseUp;
      goto MB_MAINACT;
   MB_DBLCLK:
      ev. pos. dblclk = 1;
   MB_CLICK:
      ev. cmd = cmMouseClick;
      goto MB_MAINACT;
   MB_MAINACT:
      if ( !is_apt( aptEnabled) || !apc_widget_is_responsive( self))
      {
         if ( ev. cmd == cmMouseDown || (ev. cmd == cmMouseClick && ev. pos. dblclk))
            MessageBeep( MB_OK);
         return 0;
      }
      goto MB_MAIN;
   MB_MAIN:
      if ( ev. cmd == cmMouseDown && !is_apt( aptFirstClick)) {
         Handle x = self;
         while ( dsys(x) className != WC_FRAME && ( x != application)) x = (( PWidget) x)-> owner;
         if ( x != application && !local_wnd( GetActiveWindow(), DHANDLE( x)))
         {
             ev. cmd = 0; // yes, we abandon mousedown but we should force selection:
             if ((( PApplication) application)-> hintUnder == self) v-> self-> set_hintVisible( self, 0);
             if (( v-> options. optSelectable) && ( v-> selectingButtons & ev. pos. button))
                apc_widget_set_focused( self);
         }
      }
      ev. pos. where. x = (short)LOWORD( mp2);
      ev. pos. where. y = sys lastSize. y - (short)HIWORD( mp2) - 1;
   MB_MAIN_NOPOS:
      ev. pos. mod      = 0 |
        (( mp1 & MK_CONTROL ) ? kmCtrl   : 0) |
        (( mp1 & MK_SHIFT   ) ? kmShift  : 0) |
        (( GetKeyState( VK_MENU) < 0) ? kmAlt : 0) |
	apc_pointer_get_state(self)
      ;
      break;
   case WM_MENUCHAR:
       {
          int key;
          ev. key. key    = ctx_remap_def( mp1, ctx_kb2VK2, false, kbNoKey);
          ev. key. code   = mp1;
          ev. key. mod   |=
             (( GetKeyState( VK_SHIFT)   < 0) ? kmShift : 0) |
             (( GetKeyState( VK_CONTROL) < 0) ? kmCtrl  : 0) |
             (( GetKeyState( VK_MENU)    < 0) ? kmAlt   : 0);
          if (( ev. key. mod & kmCtrl) && ( ev. key. code <= 'z'))
             ev. key. code += 'A' - 1;
          key = CAbstractMenu-> translate_key( nilHandle, ev. key. code, ev. key. key, ev. key. mod);
          if ( v-> self-> process_accel( self, key))
             return MAKELONG( 0, MNC_CLOSE);
       }
       break;
   case WM_SYNCMOVE:
       {
          Handle parent = v-> self-> get_parent(( Handle) v);
          if ( parent) {
             Point pos  = var self-> get_origin( self);
             ev. cmd    = cmMove;
             ev. gen. P = pos;
             if ( pos. x == var pos. x && pos. y == var pos. y) ev. cmd = 0;
          }
       }
       break;
   case WM_MOVE:
      {
          Handle parent = v-> self-> get_parent(( Handle) v);
          if ( parent) {
             Point sz = CWidget(parent)-> get_size( parent);
             ev. cmd = cmMove;
             ev. gen . P. x = ( short) LOWORD( mp2);
             ev. gen . P. y = sz. y - ( short) HIWORD( mp2) - sys yOverride;
             if ( is_apt( aptTransparent))
                InvalidateRect( win, nil, false);
          }
      }
      break;
   case WM_NCHITTEST:
      if ( guts. focSysDialog) return HTERROR;
      // dlg protect code - protecting from user actions
      if ( !guts. focSysDisabled && ( Application_map_focus( application, self) != self))
         return HTERROR;
      break;
   case WM_PAINT:
   	ev. cmd = cmPaint;
      if (
           ( sys className == WC_CUSTOM) &&
           ( var stage == csNormal) &&
           ( list_index_of( &guts. transp, self) >= 0)
         )
         return 0;
      break;
   case WM_QUERYNEWPALETTE:
      return palette_change( self);
   case WM_PALETTECHANGED:
      if (( HWND) mp1 != win) {
         Handle mp = hwnd_to_view(( HWND) mp1);
         if ( mp && ( hwnd_top_level( mp) == hwnd_top_level( self)))
            return 0;
         palette_change( self);
      }
      break;
   case WM_POSTAL:
      ev. cmd    = cmPost;
      ev. gen. H = ( Handle) mp1;
      ev. gen. p = ( void *) mp2;
      break;
   case WM_PRIMA_CREATE:
      ev. cmd = cmSetup;
      break;
   case WM_SETFOCUS:
      if ( guts. focSysDialog) return 1;
      // dlg protect code - general case
      if ( !guts. focSysDisabled && !guts. focSysGranted) {
         Handle hf = Application_map_focus( application, self);
         if ( hf != self) {
            PostMessage( win, WM_FORCEFOCUS, 0, ( LPARAM) hf);
            return 1;
         }
      }
      if (( HWND) mp1 != win) {
         ev. cmd = cmReceiveFocus;
         hiStage = true;
         apt_assign( aptFocused, 1);
         cursor_update( self);
      }
      break;
   case WM_SETVISIBLE:
     if ( list_index_of( &guts. transp, self) < 0) {
        if ( v-> stage <= csNormal) ev. cmd = mp1 ? cmShow : cmHide;
        hiStage = true;
        apt_assign( aptVisible, mp1);
     }
     break;
   case WM_SIZE:
      ev. cmd = cmSize;
      ev. gen. R. left   = sys lastSize. x;
      ev. gen. R. bottom = sys lastSize. y;
      sys lastSize. x    = ev. gen. R. right  = ev. gen . P. x = ( short) LOWORD( mp2);
      sys lastSize. y    = ev. gen. R. top    = ev. gen . P. y = ( short) HIWORD( mp2);
      if ( ev. gen. R. top != ev. gen. R. bottom) {
         int delta = ev. gen. R. top - ev. gen. R. bottom;
         Widget_first_that( self, move_back, &delta);
         if ( is_apt( aptFocused)) cursor_update(( Handle) self);
      }
      if ( sys sizeLockLevel == 0 && var stage <= csNormal)
         var virtualSize = sys lastSize;
      break;
   case WM_TIMER:
      {
         int id = mp1 - 1;
         if ( id >= 0 && id < sys timeDefsCount) ev. gen. H = ( Handle) sys timeDefs[ id]. item;
         if ( ev. gen. H) {
             v = ( PWidget)( self = ev. gen. H);
             ev. cmd = cmTimer;
         }
      }
      break;
   case WM_WINDOWPOSCHANGING:
      {
         LPWINDOWPOS l = ( LPWINDOWPOS) mp2;
         if ( sys className == WC_CUSTOM) {
            if (( l-> flags & SWP_NOSIZE) == 0) {
               ev. cmd = cmCalcBounds;
               ev. gen. R. right = l-> cx;
               ev. gen. R. top   = l-> cy;
            }
         }
         if (( l-> flags & SWP_NOZORDER) == 0)
            zorder_sync( self, win, l);
      }
      break;
   case WM_WINDOWPOSCHANGED:
      {
          LPWINDOWPOS l = ( LPWINDOWPOS) mp2;
          if (( l-> flags & SWP_NOZORDER) == 0)
             PostMessage( win, WM_ZORDERSYNC, 0, 0);
          if (( l-> flags & SWP_NOSIZE) == 0) {
             sys yOverride = l-> cy;
             SendMessage( win, WM_SYNCMOVE, 0, 0);
          }
          if ( l-> flags & SWP_HIDEWINDOW) SendMessage( win, WM_SETVISIBLE, 0, 0);
          if ( l-> flags & SWP_SHOWWINDOW) SendMessage( win, WM_SETVISIBLE, 1, 0);
      }
      break;
   case WM_ZORDERSYNC:
      ev. cmd = cmZOrderChanged;
      break;
   }
Exemplo n.º 29
0
void RfbKeySym::processKeyEvent(unsigned short virtKey,
                                unsigned int addKeyData)
{
  Log::debug(_T("processKeyEvent() function called: virtKey = %#4.4x, addKeyData")
             _T(" = %#x"), (unsigned int)virtKey, addKeyData);
  if (virtKey == VK_LWIN || virtKey == VK_RWIN) { 
    Log::debug(_T("Ignoring the Win key event"));
    return;
  }

  bool down = (addKeyData & 0x80000000) == 0;
  Log::debug(_T("down = %u"), (unsigned int)down);

  bool ctrlPressed = isPressed(VK_CONTROL) || isPressed(VK_RCONTROL);
  bool altPressed = isPressed(VK_MENU) || isPressed(VK_RMENU);
  bool shiftPressed = isPressed(VK_SHIFT) || isPressed(VK_RSHIFT);
  bool capsToggled = (GetKeyState(VK_CAPITAL) & 1) != 0;
  Log::debug(_T("ctrl = %u, alt = %u, shift = %u, caps toggled = %u"),
             (unsigned int)ctrlPressed,
             (unsigned int)altPressed,
             (unsigned int)shiftPressed,
             (unsigned int)capsToggled);

  m_viewerKeyState[virtKey & 255] = down ? 128 : 0;
  m_viewerKeyState[VK_CAPITAL & 255] = capsToggled ? 1 : 0;

  bool extended = (addKeyData & 0x1000000) != 0; 
  Log::debug(_T("extended = %u"), (unsigned int)extended);
  if (extended) {
    switch (virtKey) {
    case VK_CONTROL:
      virtKey = VK_RCONTROL;
      break;
    case VK_MENU:
      virtKey = VK_RMENU;
      break;
    }
  }

  m_serverKeyState[virtKey & 255] = down ? 128 : 0;

  UINT32 rfbSym;
  if (m_keyMap.virtualCodeToKeySym(&rfbSym, virtKey & 255)) {
    Log::debug(_T("The key has been mapped to the %#4.4x rfb symbol"),
               rfbSym);
    sendKeySymEvent(rfbSym, down);
  } else {
    WCHAR outBuff[20];
    HKL currentLayout = GetKeyboardLayout(0);

    int count = ToUnicodeEx(virtKey, 0, m_viewerKeyState, outBuff,
                            sizeof(outBuff) / sizeof(WCHAR),
                            0, currentLayout);
    if (count > 0) {
      count = ToUnicodeEx(virtKey, 0, m_viewerKeyState, outBuff,
                          sizeof(outBuff) / sizeof(WCHAR),
                          0, currentLayout);
    }

    Log::debug(_T("ToUnicodeEx() return %d"), count);

    if (count == 1 && !m_allowProcessCharEvent || count > 1) {
      bool ctrlAltPressed = ctrlPressed && altPressed;
      bool onlyCtrlPressed = ctrlPressed && !altPressed;
      if (ctrlAltPressed) {
        Log::debug(_T("Release the ctrl and alt")
                   _T(" modifiers before send the key event(s)"));
        releaseModifiers();
      }
      for (int i = 0; i < count; i++) {
        if (onlyCtrlPressed && outBuff[i] < 32) {
          if (onlyCtrlPressed && outBuff[i] >= 1 && outBuff[i] <= 26 &&
              !shiftPressed) {
            Log::debug(_T("The %u char is a control symbol then")
                       _T(" it will be increased by 96 to %u"),
                       (unsigned int)outBuff[i], (unsigned int)outBuff[i] + 96);
            outBuff[i] += 96;
          } else {
            Log::debug(_T("The %u char is a control symbol then")
                       _T(" it will be increased by 64 to %u"),
                       (unsigned int)outBuff[i], (unsigned int)outBuff[i] + 64);
            outBuff[i] += 64;
          }
        }
        if (m_keyMap.unicodeCharToKeySym(outBuff[i], &rfbSym)) {
          Log::debug(_T("Sending the %#4.4x rfb symbol"), rfbSym);
          sendKeySymEvent(rfbSym, down);
        } else {
          Log::error(_T("Can't translate the %#4.4x unicode character to an")
                     _T(" rfb symbol to send it"), (unsigned int)outBuff[i]);
        }
      }
      if (ctrlAltPressed) {
        Log::debug(_T("Restore the ctrl and alt")
                   _T(" modifiers after send the key event(s)"));
        restoreModifiers();
      }
    } else if (count == 0) {
      Log::debug(_T("Was get a not printable symbol then try get a printable")
                 _T(" with turned off the ctrl and alt modifiers"));
      unsigned char withoutCtrlAltKbdState[256];
      memcpy(withoutCtrlAltKbdState, m_serverKeyState, sizeof(withoutCtrlAltKbdState));
      withoutCtrlAltKbdState[VK_LCONTROL] = 0;
      withoutCtrlAltKbdState[VK_RCONTROL] = 0;
      withoutCtrlAltKbdState[VK_CONTROL] = 0;
      withoutCtrlAltKbdState[VK_LMENU] = 0;
      withoutCtrlAltKbdState[VK_RMENU] = 0;
      withoutCtrlAltKbdState[VK_MENU] = 0;
      count = ToUnicodeEx(virtKey, 0, withoutCtrlAltKbdState, outBuff,
                          sizeof(outBuff) / sizeof(WCHAR),
                          0, currentLayout);
      Log::debug(_T("ToUnicodeEx() without ctrl and alt return %d"), count);
      if (count == 1) { 
        if (m_keyMap.unicodeCharToKeySym(outBuff[0], &rfbSym)) {
          sendKeySymEvent(rfbSym, down);
        } else {
          Log::error(_T("Can't translate the %#4.4x unicode character to an")
                     _T(" rfb symbol to send it"), (unsigned int)outBuff[0]);
        }
      }
    } else if (count == -1 && down) {
      Log::debug(_T("Dead key pressed, wait for a char event"));
      m_allowProcessCharEvent = true;
    }
  }
}