全局键盘钩子与线程键盘钩子获取键码的不同方式

本文详细解读了键盘钩子函数hookproc的实现原理,包括按键识别、参数解码以及如何通过参数区分按键按下与弹起。同时,文章探讨了一个奇特现象:在某些情况下,键盘事件被触发后,钩子函数会执行多次。通过实验和分析,作者尝试解释这一现象,并提出了相应的解决方案。最后,文章还讨论了如何通过lParam的符号来过滤按键状态,但指出此方法存在局限性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 对于钩子函数hookproc(int nCode, int wParam, int lParam)参数的解码,可以得到按键值,钩子类型不同,获取键码的方式也不同。。

1,若全局键盘钩子SetWindowsHookEx(13,hookproc, IntPtr.Zero,0);

创建格式化类

[StructLayout(LayoutKind.Sequential)]//格式化类的布局方式

 public class KeyBoardHookStruct
        {
            public int vkCode;//表达一个在1到254间的虚拟键盘码
            public int scanCode;//表示硬件扫描码
            public int flags;//具体作用不知道,不过经测试可用来过滤按键弹起
            public int time;//
            public int dwExtraInfo;//
        }

KeyBoardHookStruct kbh = (KeyBoardHookStruct)Marshal.PtrToStructure((IntPtr)lParam, typeof(KeyBoardHookStruct));//专业说法不会,我把他理解成将数据存入格式化内存

此处可用wParam过滤键盘时按下还是弹起

           AllocConsole();
           
if(wParam ==(0x100))
            { Console.WriteLine("键盘按下"); }
            if (wParam == (0x101))
            { Console.WriteLine("键盘弹起"); }


            Keys key = (Keys)kbh.vkCode;//kbh.vkCode即为按键的ASCII码

 

2.线程钩子hook = SetWindowsHookEx(2,hookproc, IntPtr.Zero,GetCurrentThreadId());

wParam即为按键的ASCII码

但是经测试发现了个奇怪的现象就是钩子函数每次按键按下都会执行两次,按键弹起也会执行两次,就是不进行任何处理的话,函数hookproc会执行4次,我来个擦,网上查证,竟然没发现有人提出这个问题,是我太out了么?!初学者水平有限,暂时还不能解释次问题。但是可以通过代码屏蔽掉第二次执行。解决方案自己写(按下后得到的两次iParam参数值一样)。

至于如何过滤按键状态,网上得到的一种解决方法是判断lParam的符号:

        if (lParam> 0)
            {
                Console.WriteLine("键盘按下");

            }

            if (lParam< 0)
            {
                Console.WriteLine("键盘弹起");
            }

但是方案依然不完美,只能检测按键按下,第一次按键的弹起没触发钩子函数。原因是奇怪的现象再次发生了:

按键第一次按下时,调用钩子函数,正常,而按键弹起时,却没有再次调用钩子函数!而以后的按键,按下与弹起则会正常触发函数。汗,你们能看懂么,谁能给个解释呢,难道是WR的bug么???

 

我只能称之为奇怪的现象,我太水了。。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值