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

来源:互联网 发布:linux常用命令cat 编辑:程序博客网 时间:2024/06/05 03:10

 对于钩子函数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么???

 

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

原创粉丝点击