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.Reflection;namespace 键盘钩子屏蔽热键
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private IntPtr pKeyboardHook = IntPtr.Zero;//键盘钩子句柄
        public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);// 钩子委托声明
        //键盘钩子委托实例不能省略变量
        private HookProc KeyboardHookProcedure;
        //底层键盘钩子
        public const int idHook = 13;
        //安装钩子
        [DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)]
        public static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn,
            IntPtr pInstance, int threadId);
        //卸载钩子
        [DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)]
        public static extern bool UnhookWindowsHookEx(IntPtr pHookHandle);
        //寻找目标进程窗口
        [DllImport("USER32.DLL")]
        public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);        //设置进程窗口到最前
        [DllImport("USER32.DLL")]
        public static extern bool SetForegroundWindow(IntPtr hWnd);
        //模拟键盘事件
        [DllImport("User32.dll")]
        public static extern void keybd_event(Byte bVk, Byte bScan, Int32 dwFlags, Int32 dwExtraInfo);
        //释放按键的常量
        private const int KEYEVENTF_KEYUP = 2;        //键盘钩子处理函数
        private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
        {
            KeyMSG m = (KeyMSG)Marshal.PtrToStructure(lParam, typeof(KeyMSG));
            if (pKeyboardHook != IntPtr.Zero)
            {
                //switch (((Keys)m.vkCode))
                //{
                //    case Keys.LWin:
                //    case Keys.RWin:
                //    case Keys.Delete:
                //    case Keys.Alt:
                //    case Keys.Escape:
                //    case Keys.F4:
                //    case Keys.Control:
                //    case Keys.Tab:
                //        return 1;
                //}
                if (m.vkCode == (int)Keys.A) 
                {
                    IntPtr wc = FindWindow(null, "新建文本文档.txt - 记事本");
                    if (wc != IntPtr.Zero) 
                    {
                        SetForegroundWindow(wc);
                        byte VK_key = 103;
                        keybd_event(VK_key, 0, 0, 0);//按下小键盘7
                        //keybd_event(VK_key, 0, KEYEVENTF_KEYUP, 0); //松开小键盘7
                        return 1;
                    }
                }
            }
            return 0;
        }
        //安装钩子
        public bool InsertHook()
        {
            IntPtr pIn = Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]);//(IntPtr)4194304
            if (this.pKeyboardHook == IntPtr.Zero)
            {
                this.KeyboardHookProcedure = new HookProc(KeyboardHookProc);
                this.pKeyboardHook = SetWindowsHookEx(idHook, KeyboardHookProcedure, pIn, 0);
                if (this.pKeyboardHook == IntPtr.Zero)
                {
                    this.UnInsertHook();
                    return false;
                }
            }
            return true;
        }
        //卸载钩子
        public bool UnInsertHook()
        {
            bool result = true;
            if (this.pKeyboardHook != IntPtr.Zero)
            {
                result = (UnhookWindowsHookEx(this.pKeyboardHook) && result);
                this.pKeyboardHook = IntPtr.Zero;
            }
            return result;
        }
        //定义键盘结构
        [StructLayout(LayoutKind.Sequential)]
        public struct KeyMSG
        {
            public int vkCode;
            public int scanCode;
            public int flags;
            public int time;
            public int dwExtraInfo;
        }        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox1.Checked)
            {
                InsertHook();
            }
            else
            {
                UnInsertHook();
            }
        }        private void Form1_Load(object sender, EventArgs e)
        {        }
    }
}两个问题:
1.为什么在调试的时候钩子安装失败。。pKeyboardHook等于0.而在调试一遍之后到Bin目录里面去直接打开程序的话钩子就能安装成功
2.
                if (m.vkCode == (int)Keys.A) 
                {
                    IntPtr wc = FindWindow(null, "新建文本文档.txt - 记事本");//找到窗口
                    if (wc != IntPtr.Zero) 
                    {
                        SetForegroundWindow(wc);
                        byte VK_key = 103;
                        keybd_event(VK_key, 0, 0, 0);//按下小键盘7
                        //keybd_event(VK_key, 0, KEYEVENTF_KEYUP, 0); //松开小键盘7
                        return 1;
                    }
                }
这个部分,我只按下一次A就出现两次7?这个源码本来是魔兽改键的。。后面我改的大大们。。高手们小弟不解啊

解决方案 »

  1.   

    1,可以将pIn改为IntPtr.zero试试
    2,可能是keydown和keyup就是两次了
      

  2.   


    怎么解决呢。。我不明白你们说的down和up是什么能说具体点吗
      

  3.   

    你只判断了键是否是A,按A键会产生两个消息(WM_KEYDOWN,WM_KEYUP)
    所以判断一下!(lParam&0xA0000000)是否为真,真就是按下,假就是松开
      

  4.   


    if(!(lParam&0xA0000000))
    {
    if (m.vkCode == (int)Keys.A) 
                    {
                        IntPtr wc = FindWindow(null, "新建文本文档.txt - 记事本");//找到窗口
                        if (wc != IntPtr.Zero) 
                        {
                            SetForegroundWindow(wc);
                            byte VK_key = 103;
                            keybd_event(VK_key, 0, 0, 0);//按下小键盘7
                            //keybd_event(VK_key, 0, KEYEVENTF_KEYUP, 0); //松开小键盘7
                            return 1;
                        }
                    }
    }