首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

C# 键盘钩子,有些疑问,网下有问的,但没看懂。

2012-10-21 
C# 键盘钩子,有些疑问,网上有问的,但没看懂。。。不多说,直接上源码:C# codeusing Systemusing System.Colle

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键"

热点排行