#if defined(Q_WS_WIN32) char buff[MAX_PATH]; HWND active = GetForegroundWindow(); DWORD tid = GetWindowThreadProcessId(active, 0); DWORD cid = GetCurrentThreadId(); AttachThreadInput(cid, tid, true); HWND focused = GetFocus(); //qDebug() << GetWindowText(focused, (LPTSTR)buff, sizeof(buff)); DWORD res = SendMessage( focused, WM_GETTEXT, sizeof(buff), LPARAM((LPTSTR)buff)); editor->setText(QString::fromUtf16((ushort*)buff)); AttachThreadInput(cid, tid, false); #endif
#include "kbdhook.h"QString kbdbuffer;QString spell_dic;Hunspell *pChecker = 0;bool ownApp;LRESULT CALLBACK KeyboardProc(int code,WPARAM wParam,LPARAM lParam) {// http://msdn.microsoft.com/en-us/library/windows/desktop/ms644984(v=vs.85).aspx// WPARAM The virtual-key code of the key that generated the keystroke message.// // lParam decomposition //WORD nRepeat = (WORD) lParam; // bits 0..15 UINT nScanCode = (UINT) (lParam & 0x00F0); //LPARAM bContext = lParam & 0x20000000; //LPARAM bPrev = lParam & 0x40000000; LPARAM bRelease = lParam & 0x80000000; bool isChar = false; bool isLetter = false; if (bRelease) // KeyUp { static BYTE keyState[256]; GetKeyboardState(keyState); static WCHAR inBuffer[4] = {0}; HWND hWnd = GetForegroundWindow(); DWORD WinThreadProcId = GetWindowThreadProcessId(hWnd, 0); HKL kbLayout = GetKeyboardLayout(WinThreadProcId); if (ToUnicodeEx(wParam, nScanCode, keyState, (WCHAR*)&inBuffer, 4, 0, kbLayout) >= 1) { isChar = true; QChar chr = QString::fromUtf16((const ushort*)&inBuffer, 1)[0]; if (chr.isLetter()) { isLetter = true; kbdbuffer += chr; } } if ((!kbdbuffer.isEmpty()) & (!isLetter)) { if (pChecker == 0) { spell_dic="ru_RU"; pChecker = new Hunspell(spell_dic.toLatin1()+".aff",spell_dic.toLatin1()+".dic"); } QByteArray encodedString; QString spell_encoding=QString(pChecker->get_dic_encoding()); QTextCodec *codec = QTextCodec::codecForName(spell_encoding.toLatin1()); encodedString = codec->fromUnicode(kbdbuffer); bool isValid = pChecker->spell(encodedString.data()); if (!isValid) { char ** wlst; int ns = pChecker->suggest(&wlst,encodedString.data()); if (ns > 0) { QString newtext; { QMenu *ckMenu = new QMenu(); for (int i=0; i < ns; i++) { ckMenu->addAction( codec->toUnicode(wlst[i]) ); free(wlst[i]); } free(wlst); QAction *act = ckMenu->exec(QCursor::pos()); if (act != 0) newtext = act->text(); ckMenu->close(); delete ckMenu; } if (newtext.length()>0) { int dRepeat = 0; dRepeat = (kbdbuffer.length()); if (isChar) dRepeat = dRepeat + 1; for (int ii=0; ii<dRepeat; ii++) { keybd_event( VK_BACK, 0x45, KEYEVENTF_EXTENDEDKEY | 0, 0 ); keybd_event( VK_BACK, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0 ); } for (int uu=0; uu<newtext.length(); uu++) { QString substr(newtext.at(uu)); static WCHAR ss; substr.toWCharArray(&ss); short vk = VkKeyScanEx(ss, kbLayout); keybd_event( LOBYTE(vk), 0, KEYEVENTF_EXTENDEDKEY | 0, 0 ); keybd_event( LOBYTE(vk), 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0 ); } } }// if ns >0 pChecker->free_list(&wlst, ns); } kbdbuffer.clear(); } if (!isLetter) kbdbuffer.clear(); }return CallNextHookEx(0,code,wParam,lParam);}BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved ) { if (fdwReason==DLL_PROCESS_ATTACH) { QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8")); QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8")); QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8")); kbdbuffer = ""; ownApp = QMfcApp::pluginInstance(hinstDLL); QMfcApp::enterModalLoop(); } else if (fdwReason==DLL_PROCESS_DETACH) { if (pChecker!=0) { delete pChecker; pChecker = 0; } if (ownApp) { QMfcApp::exitModalLoop(); delete qApp; } } return TRUE;}
#if defined(KBDHOOK_LIBRARY)# define KBDHOOKSHARED_EXPORT Q_DECL_EXPORT#else# define KBDHOOKSHARED_EXPORT Q_DECL_IMPORT#endif...extern "C" { KBDHOOKSHARED_EXPORT BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved ); KBDHOOKSHARED_EXPORT LRESULT CALLBACK KeyboardProc(int code,WPARAM wParam,LPARAM lParam);}