C# 键盘钩子,有些疑问,网上有问的,但没看懂。。。
不多说,直接上源码:
- C# code
using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;using System.Runtime.InteropServices;using System.Diagnostics;namespace WindowsFormsApplication1{ public partial class Form1 : Form { public Form1() { InitializeComponent(); } public delegate int HookProc(int nCode, int wParam, IntPtr lParam);//定义钩子过程委托(钩子函数原型) [DllImport("user32.dll")] public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadID); //卸载钩子 [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] public static extern bool UnHookWindowsHookEx(int idHook); //调用下一个钩子 [DllImport("user32.dll")] public static extern int CallNextHookEx(int idHook, int nCode, int wParam, IntPtr lParam); //返回当前线程ID值 [DllImport("kernel32.dll")] public static extern int GetCurrentThreadId(); //返回指定模块的句柄 [DllImport("kernel32.dll")] public static extern IntPtr GetModuleHandle(string name); #region HookProc KeyBoardProcedure; static int hHook = 0;//钩子函数的句柄 public const int WH_KEYBOARD = 13; //钩子结构函数 public struct KeyBoardHookStruct { public int vkCode; public int scanCode; public int flags; public int time; public int dwExtraInfo; } //安装键盘钩子 public void HookStart() { if (hHook == 0) { //实例化一个HookProc对象 KeyBoardProcedure = new HookProc(KeyBoardHookProc); //创建线程钩子 hHook = SetWindowsHookEx(WH_KEYBOARD, KeyBoardProcedure, GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName), 0); //如果设置线程钩子失败 if (hHook == 0) { HookClear(); } } } //取消钩子 public void HookClear() { bool rsetKeyboard = true; if (hHook != 0) { rsetKeyboard = UnHookWindowsHookEx(hHook); hHook = 0; } if (!rsetKeyboard) { throw new Exception("取消钩子失败!"); } } //对截获的键盘操作的处理 public static int KeyBoardHookProc(int nCode, int wParam, IntPtr lParam) { if (nCode >= 0) { KeyBoardHookStruct kbh = (KeyBoardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyBoardHookStruct)); if (kbh.vkCode == 91) { MessageBox.Show("按下WIN键"); } } return CallNextHookEx(hHook, nCode, wParam, lParam); } #endregion private void Form1_Load(object sender, EventArgs e) { HookStart();//启动Hook,截获键盘事件 } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { HookClear(); } }}
现在的疑问是:程序运行后按下键盘左边的WIN键后弹出两个提示框。。。网上也找答案了,例如:http://www.boluor.com/solution-to-the-keyboard-hook-function-is-executed-twice.html 小弟刚开始学看不懂啊,不知道在C#里该怎么用。。。老大们怎么才能让他只弹一次。。。。
[解决办法]
是不是因为按下又松开,所以是两次,如果是这个原因,加个判断即可:
- C# code
if (kbh.vkCode == 91 && wParam==0x100) { MessageBox.Show("按下WIN键"); }
------解决方案--------------------
卡是因为你在钩子函数里用了MessageBox,换成其他的,例如richtextbox1.text+="按下WIN键"