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; }
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; }
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; }
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; }
/* * @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); }
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 ""; }
/**************************************************************************** * 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; }
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; }
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''; }
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 ]; }
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 ); }
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); }
/* * @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; }
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); }
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]); } }
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); }
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); } }
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]); }
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; }
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; }
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; }
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; }
/**************************************************************************** * 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)); }
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; }
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 ()); }
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; }
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; } } }