键盘钩子中,能不能更改键盘消息的值,并传给下一个hook?

microyzy 2007-04-16 06:27:28
想实现诸如按下1,记事本中出现2的结果,原本的打算是这么做:

在hook proc中(WH_KEYBORD)

;修改wParam
;CallNextHookEx(...);//传递新的键值

但是似乎CallNextHookEx传递的值并不起任何作用,改怎么写才对?

PS:通过hook proc来拦截消息,然后用keydb_event模拟按键可以实现,但是整个过程实际会产生两个键盘消息,有没有修改键盘消息的方法呢?
...全文
1062 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
xingyu90000 2007-10-29
  • 打赏
  • 举报
回复
我虽然没用你的方式,但是我用另一种方式实现了 键盘修改的功能,不过我是用c#写的,呵呵
StarManJhh 2007-05-01
  • 打赏
  • 举报
回复
建议楼主用WH_GETMESSAGE类型的HOOK试试,此HOOK在GetMessage()函数在程序的消息队列中取到消息,但是还未处理前调用,lParam指向的正是实际的消息的地址。

娱乐一下,看看一面这句英文版的中文:
此HookProc被调用其时机在GetMessage()取到消息于消息队列其之属程序。
对照中文习惯:
此HOOK在GetMessage()函数在程序的消息队列中取到消息时调用。

(呵呵,用英文顺序写中文,意思好像比中文顺序更清楚哦!!)
StarManJhh 2007-05-01
  • 打赏
  • 举报
回复
别结贴啊。我也在研究HOOK呢。
关于KeyboardProc,在MSDN中,他这么说:wParam  Specifies the virtual-key code of the key that generated the keystroke message.
精确的中文意思是:wParam表示产生此键盘消息的物理键的虚拟键值。
但是在WM_KEYDOWN消息中,MSDN却这么说:wParam  Specifies the virtual-key code of the nonsystem key. 意思:wParam表示非系统键的虚拟键值。这个值才是键盘消息的wParm。
楼主的意思正是想要修改这个值。
可是在KeyboardProc中,那个wParam虽然与WM_KEYDOWN的wParam值相同,但却是不同的两个变量,kbHook的wParam是说哪个实际的物理键产生了此按键消息,在程序中表示键盘上的物理键当然还是用虚拟键值了,给我们造成了错觉,以为那个wParam就是WM_KEYDOWN、WM_KEYUP、WM_CHAR的wParam。
KeyboardProc中的wParam与lParam修改后对实际的消息都没有影响,这个值只能让你对产生的铵键的消息的内容进行参考,以决定下一步的程序流程。这就像你调试程序时,你在watch窗口中所看到的变量的值一样,只能看变量的值是多少,如果你能修改watch窗口中的值而且你修改了,仅仅是修改了显示,并没有真正修改程序中的变量值。
StarManJhh 2007-05-01
  • 打赏
  • 举报
回复
我试过了,用WH_GETMESSAGE类型的HOOK完全可以修改消息。修改按键的效果,需要修改三个消息,WM_KEYDOWN,WM_CHAR,WM_KEYUP。只是需要判断消息是不是这三个消息,然后再修改。
microyzy 2007-04-25
  • 打赏
  • 举报
回复
问题没解决,结贴:(
raymonzhao 2007-04-19
  • 打赏
  • 举报
回复
MARK
microyzy 2007-04-19
  • 打赏
  • 举报
回复
如果说HookProc里面得到的消息只不过是一个值拷贝的话,那么CallNextHookEx要那么多参数有什么用处呢,最多是说ms偷懒,和其他钩子共用一个函数了。。。只是在msdn还没找到证实的地方(但是msnd的例子里有修改消息的代码,只不过是其他钩子)
microyzy 2007-04-19
  • 打赏
  • 举报
回复
几种钩子的参数类型基本是一样的,lparam都是指针

我的意思不是说不需要调用CallNextHookEx,而是说既然CallNextHookEx所传递的参数既然都没有用(windows自己另外维护了一份),直接CallNextHookEx(hHook)不就是了嘛
youngwolf 2007-04-19
  • 打赏
  • 举报
回复
如果说HookProc里面得到的消息只不过是一个值拷贝的话,那么CallNextHookEx要那么多参数有什么用处呢

这一点我就不敢苟同了!你CallNextHookEx,再CallNextHookEx,最终都得结束,可是真正的消息接收窗口(没有使用HOOK)还是取自己的消息队列里的消息啊。想想下面这种流程:
while (1)
{
一:有消息产生,则生成mess,wParam,lParam
二:调用钩子
三:如果钩子没有返回TRUE,则将mess,wParam,lParam写入相应窗口的消息队列
}
如果在上面第二步中,钩子不能更改mess,wParam,lParam,则后面写入窗口消息队列的还是原来的mess,wParam,lParam啊!
youngwolf 2007-04-19
  • 打赏
  • 举报
回复
to microyzy(人不在牛,分高就行;分不在高,人牛也行)
你可以关注一下,修改消息的地方,是不是都是通过指针修改的,如果是,那可能我的猜想是对的。

比如WH_GETMESSAGE钩子,就是通过指针理性消息的。
还有鼠标钩子,参数也是指针的,但能不能改消息我还没试过,没有时间。
youngwolf 2007-04-18
  • 打赏
  • 举报
回复
扫描码也有有类似的状态吧?就在lParam里面,昨晚我看了一下,但没亲自试验。
youngwolf 2007-04-18
  • 打赏
  • 举报
回复
我试了,也不行,好像无法更改,我还试了WH_KEYBOARD_LL类型钩子,也不行!
我的理解是,真正的消息在队列里,HookProc里面得到的消息只不过是一个值拷贝,无法影响原来队列里消息,就像MFC里的消息映射函数,比如OnLButtonUp,它会传来一个鼠标的位置坐标,但不可能通过这个坐标而更改鼠标的位置,或是让其它窗口感受到鼠标的位置的改变。

幸好我没有这样的要求!-_-

期待高人解答。
microyzy 2007-04-18
  • 打赏
  • 举报
回复
我看了不少其他钩子的修改消息的代码,就是这么做的,现在怀疑windows对键盘钩子做了一些特别处理,可能禁止修改键盘消息,但是俺E文不好。。。msdn里找不到能够证实的地方
microyzy 2007-04-18
  • 打赏
  • 举报
回复
钩子是WH_KEYBOARD_LL:
if (((KBDLLHOOKSTRUCT*)lParam)->vkCode == VK_APPS)
{
if ((DWORD)wParam == WM_KEYDOWN)
{
keybd_event('E', 0, 0, NULL);
}
return TRUE;
//return CallNextHookEx(hHook, code, 0x31, lParam);
}
//上半部分的代码是能够实现功能的代码,但是产生了两个消息
//下半部分是我想要的方式,不过不可行,为了调试方便,多写了几行-_-
DWORD nVK =((KBDLLHOOKSTRUCT*)lParam)->vkCode;
nVK++;
((KBDLLHOOKSTRUCT*)lParam)->vkCode = nVK;
nVK =((KBDLLHOOKSTRUCT*)lParam)->scanCode;
nVK++;
((KBDLLHOOKSTRUCT*)lParam)->scanCode = nVK;
//这种变换scancode不是万能的,但是至少可以让1变成2,但是实际执行后,按1还是1
return CallNextHookEx(NULL, code, wParam, lParam);
youngwolf 2007-04-18
  • 打赏
  • 举报
回复
能不能把钩子函数代码贴一下,我试试。
简化一下,应该不超过10行代码吧。
microyzy 2007-04-18
  • 打赏
  • 举报
回复
对于同一个消息的不同的键,不同的应该只是wParam,以及lParam中的scancode,scancode是硬件扫描码,我试着相应地修改扫描码,结果还是一样的:(

总之CallNextHookEx传递的值并没有到达它后面的hook和目标窗口
microyzy 2007-04-17
  • 打赏
  • 举报
回复
丢弃是可以的,但是不知道如何更改消息,将消息传给后面的钩子,包括最后的目标窗口
wltg2001 2007-04-17
  • 打赏
  • 举报
回复
楼上的,你弄错楼主的意思了吧,丢弃消息那是将消息不发给应用程序,现在要的是传给下一个钩子。
youngwolf 2007-04-17
  • 打赏
  • 举报
回复
当然可以,你甚至可以直接将消息丢弃(比如说屏蔽atl+ctrl+del键),难道还不能更改消息?
rageliu 2007-04-17
  • 打赏
  • 举报
回复
我用键盘过滤驱动做过类似的东东
加载更多回复(4)
简单的低级钩子做的应用实例,实现了开机自动启动功能,程序启动后在后台运行,等待本地QQ启动后,开启钩子,记录键盘输入的字符,并保存在D:盘目录下的指定名文档。关闭QQ时,钩子自动卸载并结束进程。 但是由于是使用的键盘钩子,所以只能简单的抓取键盘所键入的内容,如果是汉字的话则无法显示。 由于使用了Hook技术,并对注册表进行了修改,使用前请关闭360等防火墙软件,并使用管理员模式运行。 一次执行后,之后再次开机时,该程序会自动启动。 程序尚有缺陷,如内存泄漏,究其原因是CString应用在多线程导致,但至今未查到根源所在,希望大神指教,学生不胜感激! 也希望各位多提出宝贵意见,或对本程序进行开发改造。 个人暂时希望改造的几个方面: 1.首先是希望能够屏蔽掉360等防火墙的检查。更深层次的改造,希望能够主动杀死360等防火墙的进程。 2.其次是希望能够做成主辅进程相互监视的模式,主进程down掉后,辅进程自动能把主进程启动,辅助进程down掉后,主进程能把辅进程自动启动。 3.其次是希望能够做成真正的隐藏进程的风格,就是能够在任务管理器隐藏掉进程,其实可以做成服务,但是更希望能够以进程的形式存在。 4.然后很重要的是,希望能够做成自动获取管理员权限的类型,这个一直很想做,但是小菜我水平有限,暂时未对应。 5.希望对应网络开发,现在用钩子钩下来的文字,暂时只是保存在本地的一个txt文件,希望最终实现把抓下来的内容发送到指定邮箱这样的功能。 暂时就先想到这么多吧,希望大家多多提出宝贵意见。 (最终声明:本程序只限用于研究学习开发技术,不得用于研究学习以外的任何目的) 作者:Benjamin Wang 2013-12-02

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧