/** * Sends a char using emulated keyboard input * * This works for most cases, but not for dead keys etc **/ void sendChar(TCHAR key, KBDLLHOOKSTRUCT keyInfo) { SHORT keyScanResult = VkKeyScanEx(key, GetKeyboardLayout(0)); keyInfo.vkCode = keyScanResult; char modifiers = keyScanResult >> 8; bool shift = ((modifiers & 1) != 0); bool alt = ((modifiers & 2) != 0); bool ctrl = ((modifiers & 4) != 0); bool altgr = alt && ctrl; if (altgr) { ctrl = false; alt = false; } if (altgr) keybd_event(VK_RMENU, 0, 0, 0); if (ctrl) keybd_event(VK_CONTROL, 0, 0, 0); if (alt) keybd_event(VK_MENU, 0, 0, 0); // ALT if (shift) keybd_event(VK_SHIFT, 0, 0, 0); keybd_event(keyInfo.vkCode, keyInfo.scanCode, keyInfo.flags, keyInfo.dwExtraInfo); if (altgr) keybd_event(VK_RMENU, 0, KEYEVENTF_KEYUP, 0); if (ctrl) keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0); if (alt) keybd_event(VK_MENU, 0, KEYEVENTF_KEYUP, 0); // ALT if (shift) keybd_event(VK_SHIFT, 0, KEYEVENTF_KEYUP, 0); }
Relax::Relax(Playmanagement &playmanager) { Playmanager = &playmanager; std::string Key1 = "."; std::string Key2 = "-"; Button1.Keycode = VkKeyScanEx(Key1.at(0), GetKeyboardLayout(0)) & 0xFF; Button2.Keycode = VkKeyScanEx(Key2.at(0), GetKeyboardLayout(0)) & 0xFF; InitButton(Button1.PressButton, Button1.Keycode, true); //Initiate buttons InitButton(Button1.ReleaseButton, Button1.Keycode, false); InitButton(Button2.PressButton, Button2.Keycode, true); InitButton(Button2.ReleaseButton, Button2.Keycode, false); Klicked = true; //Load first hit }
BOOL SendText( LPCTSTR lpctszText ) { std::vector<INPUT> EventQueue; TCHAR Buff[120 * sizeof(TCHAR)] = {0}; GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_ILANGUAGE, Buff, sizeof(Buff)); HKL hKeyboardLayout = ::LoadKeyboardLayout( Buff, KLF_ACTIVATE ); const size_t Len = wcslen( lpctszText ); for( size_t Index = 0; Index < Len; ++Index ) { INPUT Event = { 0 }; const SHORT Vk = VkKeyScanEx(lpctszText[Index], hKeyboardLayout); const UINT VKey = ::MapVirtualKey( LOBYTE( Vk ), 0 ); if( HIBYTE( Vk ) == 1 ) // Check if shift key needs to be pressed for this key { // Press shift key ::ZeroMemory( &Event, sizeof( Event )); Event.type = INPUT_KEYBOARD; Event.ki.dwFlags = KEYEVENTF_SCANCODE; Event.ki.wScan = ::MapVirtualKey( VK_LSHIFT, 0 ); EventQueue.push_back( Event ); } // Keydown ::ZeroMemory( &Event, sizeof( Event )); Event.type = INPUT_KEYBOARD; Event.ki.dwFlags = KEYEVENTF_SCANCODE; Event.ki.wScan = VKey; EventQueue.push_back( Event ); // Keyup ::ZeroMemory( &Event, sizeof( Event )); Event.type = INPUT_KEYBOARD; Event.ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP; Event.ki.wScan = VKey; EventQueue.push_back( Event ); if( HIBYTE( Vk ) == 1 )// Release if previously pressed { // Release shift key ::ZeroMemory( &Event, sizeof( Event )); Event.type = INPUT_KEYBOARD; Event.ki.dwFlags = KEYEVENTF_SCANCODE| KEYEVENTF_KEYUP; Event.ki.wScan = ::MapVirtualKey( VK_LSHIFT, 0 ); EventQueue.push_back( Event ); } }// End for if( hKeyboardLayout ) { UnloadKeyboardLayout( hKeyboardLayout ); } return static_cast<BOOL>(::SendInput( static_cast<UINT>(EventQueue.size()), &EventQueue[0], sizeof( INPUT ))); }
void CKeySendImpl::OldSendChar(TCHAR c) { BOOL shiftDown = false; // Assume shift key is up at start. BOOL ctrlDown = false; BOOL altDown = false; SHORT keyScanCode = VkKeyScanEx(c, m_hlocale); // high order byte of keyscancode indicates if SHIFT, CTRL etc keys should be down if (keyScanCode & 0x100) { shiftDown = true; //send a shift down - Fixes bug #1208955 keybd_event(VK_SHIFT, (BYTE) MapVirtualKeyEx(VK_SHIFT, 0, m_hlocale), 0, 3); } if (keyScanCode & 0x200) { ctrlDown = true; //send a ctrl down keybd_event(VK_CONTROL, (BYTE) MapVirtualKeyEx(VK_CONTROL, 0, m_hlocale), KEYEVENTF_EXTENDEDKEY, 0); } if (keyScanCode & 0x400) { altDown = true; //send a alt down keybd_event(VK_MENU, (BYTE) MapVirtualKeyEx(VK_MENU, 0, m_hlocale), KEYEVENTF_EXTENDEDKEY, 0); } // the lower order byte has the key scan code we need. keyScanCode = (SHORT)(keyScanCode & 0xFF); keybd_event((BYTE)keyScanCode, (BYTE) MapVirtualKeyEx(keyScanCode, 0, m_hlocale), 0, 0); keybd_event((BYTE)keyScanCode, (BYTE) MapVirtualKeyEx(keyScanCode, 0, m_hlocale), KEYEVENTF_KEYUP, 0); if (shiftDown) { //send a shift up keybd_event(VK_SHIFT, (BYTE) MapVirtualKeyEx(VK_SHIFT, 0, m_hlocale), KEYEVENTF_KEYUP, 3); //Fixes bug #1208955 shiftDown = false; } if (ctrlDown) { //send a ctrl up keybd_event(VK_CONTROL, (BYTE) MapVirtualKeyEx(VK_CONTROL, 0, m_hlocale), KEYEVENTF_KEYUP |KEYEVENTF_EXTENDEDKEY, 0); ctrlDown = false; } if (altDown) { //send a alt up keybd_event(VK_MENU, (BYTE) MapVirtualKeyEx(VK_MENU, 0, m_hlocale), KEYEVENTF_KEYUP |KEYEVENTF_EXTENDEDKEY, 0); altDown = false; } ::Sleep(m_delay); }
HEIMY_API bool SendText(LPCSTR lpctszText) { std::vector<INPUT> EventQueue; char Buff[120] = {0}; //GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_ILANGUAGE, (LPWSTR) Buff, sizeof(Buff)); //HKL hKeyBoardLayout = LoadKeyboardLayout((LPWSTR) Buff, KLF_ACTIVATE); const int Len = strlen(lpctszText); for(int Index = 0; Index < Len; ++Index) { INPUT Event = {0}; const SHORT Vk = VkKeyScanEx(lpctszText[Index], NULL); const UINT VKey = MapVirtualKey(LOBYTE(Vk), 0); if(HIBYTE(Vk) == 1) { ZeroMemory(&Event, sizeof(Event)); Event.type = INPUT_KEYBOARD; Event.ki.dwFlags = KEYEVENTF_SCANCODE; Event.ki.wScan = MapVirtualKey(VK_LSHIFT, 0); EventQueue.push_back(Event); } ZeroMemory(&Event, sizeof(Event)); Event.type = INPUT_KEYBOARD; Event.ki.dwFlags = KEYEVENTF_SCANCODE; Event.ki.wScan = VKey; EventQueue.push_back(Event); ZeroMemory(&Event, sizeof(Event)); Event.type = INPUT_KEYBOARD; Event.ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP; Event.ki.wScan = VKey; EventQueue.push_back(Event); if(HIBYTE(Vk) == 1) { ZeroMemory(&Event, sizeof(Event)); Event.type = INPUT_KEYBOARD; Event.ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP; Event.ki.wScan = MapVirtualKey(VK_LSHIFT, 0); EventQueue.push_back(Event); } } /*if(hKeyBoardLayout) { UnloadKeyboardLayout(hKeyBoardLayout); }*/ return SendInput(EventQueue.size(), &EventQueue[0], sizeof(INPUT)); }
void send_char(char ch) { uint16 code=VkKeyScanEx(ch,0); // with an n.z. accent uint8 shft=(uint8)((code>>8)&0x0ff); uint8 k=(uint8)(code&0x0ff); if(shft&1) { shift(k); } else { key(k); } }
/** * Uses the SendInput function from windows.h * @param c_key is the character to print using keyboard simulation * */ int kb_print_char(char c_key) { /*** 0x0409 is the US english layout, KLF_ACTIVATE is load the layout if not loaded */ short int v_key = VkKeyScanEx(c_key, LoadKeyboardLayout("0x0409", KLF_ACTIVATE)); ///< Translate char to virtual key code (lower byte is key code, higher byte is the shift state) int in_status = 0; ///< Holds the SendInput return, 0 is device already blocked by another threat, different means that amount of times the correct inputs INPUT in_struct; ///< Declare an INPUT structure, to know which type will be, mouse, kb or other hdw in_struct.type = INPUT_KEYBOARD; ///< INPUT_KEYBOARD is an enum (num 1) and should be combined with "ki" struct in_struct.ki.time = 0; ///< 0 means let the OS put it's own time stamp in_struct.ki.wVk = v_key; ///< virtual-key code, use the sent char param in_struct.ki.dwFlags = 0; ///< 0 for key press in_status = SendInput(1, &in_struct, sizeof(INPUT)); ///< Indicates only 1 input if(in_status == 0) return 0; ///< don't try to lift the key since resource is blocked in_struct.ki.dwFlags = KEYEVENTF_KEYUP; ///< KEYEVENTF_KEYUP for key release SendInput(1, &in_struct, sizeof(INPUT)); return in_status; ///< return the number of succesful insertions }
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; }
bool KeyboardDevice::writeText(const QString &text, int delay, bool noUnicodeCharacters) const { #ifdef Q_OS_UNIX bool result = true; KeySym keySym[2]; std::wstring wideString = text.toStdWString(); wchar_t wcSinglecharStr[2] = {L'\0'}; for(unsigned int i = 0; wideString[i] != L'\0' && i < wideString.size(); ++i) { wcSinglecharStr[0] = wideString[i]; //KeySym lookup keySym[0] = ActionTools::KeySymHelper::wcharToKeySym(wcSinglecharStr[0]); keySym[1] = 0; if(keySym[0] == 0 || ActionTools::KeySymHelper::keySymToKeyCode(keySym[0]) == 0) { //No keycode found -> try to find a Multi_key combination for this character keySym[0] = 0; for(int j = 0; j < ActionTools::KeySymHelper::MULTIKEY_MAP_SIZE; ++j) { if(wcSinglecharStr[0] == ActionTools::KeySymHelper::multikeyMapChar[j])//Found { keySym[0] = ActionTools::KeySymHelper::wcharToKeySym(ActionTools::KeySymHelper::multikeyMapFirst[j]); keySym[1] = ActionTools::KeySymHelper::wcharToKeySym(ActionTools::KeySymHelper::multikeyMapSecond[j]); if((ActionTools::KeySymHelper::keySymToKeyCode(keySym[0]) == 0) || (ActionTools::KeySymHelper::keySymToKeyCode(keySym[1]) == 0)) keySym[0] = 0;//Character not supported break; } } } if(keySym[0]) { if(keySym[1])//Multi key sequence { result &= sendKey("Multi_key"); result &= sendCharacter(keySym[0]); result &= sendCharacter(keySym[1]); } else//Single key result &= sendCharacter(keySym[0]); } if(delay > 0) ActionTools::CrossPlatform::sleep(delay); } return result; #endif #ifdef Q_OS_WIN std::array<INPUT, 2> input; SecureZeroMemory(input.data(), input.size() * sizeof(INPUT)); bool result = true; for(int i = 0; i < 2; ++i) { input[i].type = INPUT_KEYBOARD; input[i].ki.wVk = 0; if(noUnicodeCharacters) input[i].ki.dwFlags = KEYEVENTF_SCANCODE | (i == 0 ? 0 : KEYEVENTF_KEYUP); else input[i].ki.dwFlags = KEYEVENTF_UNICODE | (i == 0 ? 0 : KEYEVENTF_KEYUP); input[i].ki.time = 0; input[i].ki.dwExtraInfo = 0; } HKL keyboardLayout = GetKeyboardLayout(0); auto sendModifiersFunction = [&keyboardLayout](int key, int additionalFlags) { INPUT modifierInput; SecureZeroMemory(&modifierInput, sizeof(INPUT)); modifierInput.type = INPUT_KEYBOARD; modifierInput.ki.dwFlags = KEYEVENTF_SCANCODE | additionalFlags; modifierInput.ki.wScan = MapVirtualKeyEx(key, MAPVK_VK_TO_VSC, keyboardLayout); if(extendedKeys.count(key) > 0) modifierInput.ki.dwFlags |= KEYEVENTF_EXTENDEDKEY; SendInput(1, &modifierInput, sizeof(INPUT)); }; for(int i = 0; i < text.length(); ++i) { SHORT virtualKey = 0; if(noUnicodeCharacters) { virtualKey = VkKeyScanEx(text[i].unicode(), keyboardLayout); auto scanCode = MapVirtualKeyEx(LOBYTE(virtualKey), MAPVK_VK_TO_VSC, keyboardLayout); if(extendedKeys.count(virtualKey) > 0) { input[0].ki.dwFlags |= KEYEVENTF_EXTENDEDKEY; input[1].ki.dwFlags |= KEYEVENTF_EXTENDEDKEY; } if(HIBYTE(virtualKey) & 1) //Shift sendModifiersFunction(VK_LSHIFT, 0); if(HIBYTE(virtualKey) & 2) //Control sendModifiersFunction(VK_LCONTROL, 0); if(HIBYTE(virtualKey) & 4) //Alt sendModifiersFunction(VK_LMENU, 0); input[0].ki.wVk = input[1].ki.wVk = virtualKey; input[0].ki.wScan = input[1].ki.wScan = scanCode; } else { input[0].ki.wScan = input[1].ki.wScan = text[i].unicode(); } result &= (SendInput(2, input.data(), sizeof(INPUT)) != 0); if(noUnicodeCharacters) { if(HIBYTE(virtualKey) & 4) //Alt sendModifiersFunction(VK_LMENU, KEYEVENTF_KEYUP); if(HIBYTE(virtualKey) & 2) //Control sendModifiersFunction(VK_LCONTROL, KEYEVENTF_KEYUP); if(HIBYTE(virtualKey) & 1) //Shift sendModifiersFunction(VK_LSHIFT, KEYEVENTF_KEYUP); } if(delay > 0) ActionTools::CrossPlatform::sleep(delay); } return result; #endif }
// Map a character to the native code and key modifiers needed to generate it int Input::MapChar (int nChar_, int *pnMods_) { if (!nChar_) return 0; // Regular character? if (nChar_ < HK_MIN) { // Convert from character to virtual keycode to raw scancode WORD wVirtual = VkKeyScanEx(nChar_, hkl); if (pnMods_) { int nMods = HM_NONE; if (wVirtual & 0x100) nMods |= HM_SHIFT; if (wVirtual & 0x200) nMods |= HM_CTRL; if (wVirtual & 0x400) nMods |= HM_ALT; *pnMods_ = nMods; } int nKey = MapVirtualKeyEx(wVirtual & 0xff, MAPVK_VK_TO_VSC, hkl); return nKey; } // Host keycode switch (nChar_) { case HK_LSHIFT: return DIK_LSHIFT; case HK_RSHIFT: return DIK_RSHIFT; case HK_LCTRL: return DIK_LCONTROL; case HK_RCTRL: return DIK_RCONTROL; case HK_LALT: return DIK_LMENU; case HK_RALT: return DIK_RMENU; case HK_LWIN: return DIK_LWIN; case HK_RWIN: return DIK_RWIN; case HK_LEFT: return DIK_LEFT; case HK_RIGHT: return DIK_RIGHT; case HK_UP: return DIK_UP; case HK_DOWN: return DIK_DOWN; case HK_KP0: return DIK_NUMPAD0; case HK_KP1: return DIK_NUMPAD1; case HK_KP2: return DIK_NUMPAD2; case HK_KP3: return DIK_NUMPAD3; case HK_KP4: return DIK_NUMPAD4; case HK_KP5: return DIK_NUMPAD5; case HK_KP6: return DIK_NUMPAD6; case HK_KP7: return DIK_NUMPAD7; case HK_KP8: return DIK_NUMPAD8; case HK_KP9: return DIK_NUMPAD9; case HK_F1: return DIK_F1; case HK_F2: return DIK_F2; case HK_F3: return DIK_F3; case HK_F4: return DIK_F4; case HK_F5: return DIK_F5; case HK_F6: return DIK_F6; case HK_F7: return DIK_F7; case HK_F8: return DIK_F8; case HK_F9: return DIK_F9; case HK_F10: return DIK_F10; case HK_F11: return DIK_F11; case HK_F12: return DIK_F12; case HK_CAPSLOCK: return DIK_CAPITAL; case HK_NUMLOCK: return DIK_NUMLOCK; case HK_KPPLUS: return DIK_ADD; case HK_KPMINUS: return DIK_SUBTRACT; case HK_KPMULT: return DIK_MULTIPLY; case HK_KPDIVIDE: return DIK_DIVIDE; case HK_KPENTER: return DIK_NUMPADENTER; case HK_KPDECIMAL: return DIK_DECIMAL; case HK_INSERT: return DIK_INSERT; case HK_DELETE: return DIK_DELETE; case HK_HOME: return DIK_HOME; case HK_END: return DIK_END; case HK_PGUP: return DIK_PRIOR; case HK_PGDN: return DIK_NEXT; case HK_ESC: return DIK_ESCAPE; case HK_TAB: return DIK_TAB; case HK_BACKSPACE: return DIK_BACK; case HK_RETURN: return DIK_RETURN; case HK_APPS: return DIK_APPS; case HK_NONE: return 0; } return 0; }
//============================================================================ void ReadDs4RawInput ( unsigned rawDataCount, unsigned rawDataBytesEach, const BYTE * rawDataArray ) { s_inputBufferIndex = (s_inputBufferIndex + 1) % s_inputBufferCount; Ds4Frame & ds4Frame = s_ds4FrameBuffer[s_inputBufferIndex]; memcpy(&ds4Frame, rawDataArray, rawDataBytesEach * rawDataCount); unsigned povValue = rawDataArray[DS4_BYTE_FACE_AND_POV] & 0x0F; unsigned gkosChord = 0x0; /* if (rawDataArray[DS4_BYTE_L_R_MISC_DIGITAL] & (1 << 0)) // L1 gkosChord |= GKOS_KEY_FLAG_1; if ((povValue >= 1 && povValue <= 3) || rawDataArray[DS4_BYTE_L2_ANALOG] >= 0x1F) // POV East OR L2 gkosChord |= GKOS_KEY_FLAG_2; if (povValue >= 3 && povValue <= 5) // POV South gkosChord |= GKOS_KEY_FLAG_3; if (rawDataArray[DS4_BYTE_L_R_MISC_DIGITAL] & (1 << 1)) // R1 gkosChord |= GKOS_KEY_FLAG_4; if ((rawDataArray[DS4_BYTE_FACE_AND_POV] & (1 << 4)) || rawDataArray[DS4_BYTE_R2_ANALOG] >= 0x1F) // Square OR R2 gkosChord |= GKOS_KEY_FLAG_5; if (rawDataArray[DS4_BYTE_FACE_AND_POV] & (1 << 5)) // X gkosChord |= GKOS_KEY_FLAG_6; /*/ //if (rawDataArray[DS4_BYTE_L_R_MISC_DIGITAL] & (1 << 0)) // L1 //gkosChord |= GKOS_KEY_FLAG_3; if ((povValue >= 1 && povValue <= 3) || rawDataArray[DS4_BYTE_L2_ANALOG] >= 0x1F) // POV East OR L2 gkosChord |= GKOS_KEY_FLAG_1; if (povValue >= 3 && povValue <= 5) // POV South gkosChord |= GKOS_KEY_FLAG_2; //if (rawDataArray[DS4_BYTE_L_R_MISC_DIGITAL] & (1 << 1)) // R1 //gkosChord |= GKOS_KEY_FLAG_6; if ((rawDataArray[DS4_BYTE_FACE_AND_POV] & (1 << 4)) || rawDataArray[DS4_BYTE_R2_ANALOG] >= 0x1F) // Square OR R2 gkosChord |= GKOS_KEY_FLAG_4; if (rawDataArray[DS4_BYTE_FACE_AND_POV] & (1 << 5)) // X gkosChord |= GKOS_KEY_FLAG_5; //*/ // Combine with keyboard-based gkos keys for (unsigned i = 1; i <= 6; ++i) { if (GkosDll::g_IsGkosKeyboardKeyPressed(i)) gkosChord |= (1 << (i - 1)); } s_gkosFrameBuffer[s_inputBufferIndex].chordCode = gkosChord; s_gkosFrameBuffer[s_inputBufferIndex].flags = 0; if (!gkosChord) return; bool chordPressed = true; for (unsigned i = 1; i < s_chordMinFrameCount; ++i) { const GkosChordFrame & gkosFrame = GetRelativeGkosChordFrame(i); if (gkosFrame.chordCode != gkosChord) { chordPressed = false; break; } } // Send the key if the chord was just pressed if (chordPressed && GetRelativeGkosChordFrame(s_chordMinFrameCount).chordCode != gkosChord) { const GkosChord & gkosKey = gkosKeysAbc[gkosChord]; TCHAR buf[64]; if (gkosKeysAbc[gkosChord].str) swprintf_s(buf, L"Chord 0x%02X yields Key %s\n", gkosChord, gkosKey.str); else swprintf_s(buf, L"Chord 0x%02X yields Virtual Key %X\n", gkosChord, gkosKey.vkey); OutputDebugString(buf); INPUT ins[32]; UINT insCount = 0; memset(ins, 0, sizeof(ins)); for (unsigned i = 0; i < 32; ++i) ins[i].type = INPUT_KEYBOARD; // Can also use _MOUSE or _HARDWARE if (gkosKey.vkey) { ins[0].ki.wVk = gkosKey.vkey; } else if (gkosKey.str) { // Note: This doesn't handle numpad keys SHORT vkey = VkKeyScanEx(gkosKey.str[0], NULL); if (vkey == -1) return; ins[0].ki.wVk = vkey; } else return; SendInput(1, ins, sizeof(ins[0])); ins[0].ki.dwFlags = KEYEVENTF_KEYUP; SendInput(1, ins, sizeof(ins[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; }
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); } }