using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows.Forms;namespace wa_hooktest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        internal enum HookType //枚举,钩子的类型 
        {            //MsgFilter = -1,             //JournalRecord = 0,             //JournalPlayback = 1,             Keyboard = 2,            //GetMessage = 3,             //CallWndProc = 4,             //CBT = 5,             //SysMsgFilter = 6,             //Mouse = 7,             //Hardware = 8,             //Debug = 9,             //Shell = 10,             //ForegroundIdle = 11,             //CallWndProcRet = 12,             KeyboardLL = 13,             //MouseLL = 14,         };        [DllImport("kernel32.dll")]
        static extern int GetCurrentThreadId(); //取得当前线程编号的API         [DllImport("User32.dll")]
        internal extern static void UnhookWindowsHookEx(IntPtr handle); //取消Hook的API 
        [DllImport("User32.dll")]
        internal extern static IntPtr SetWindowsHookEx(int idHook, [MarshalAs(UnmanagedType.FunctionPtr)] HookProc lpfn, IntPtr hinstance, int threadID); //设置Hook的API 
        [DllImport("User32.dll")]
        internal extern static IntPtr CallNextHookEx(IntPtr handle, int code, IntPtr wparam, IntPtr lparam); //取得下一个Hook的API 
        IntPtr _nextHookPtr; //记录Hook编号        public delegate IntPtr HookProc(int code, IntPtr wparam, IntPtr lparam);
        public IntPtr MyHookProc(int code, IntPtr wparam, IntPtr lparam)
        {
            if (code < 0)
            {
                return CallNextHookEx(_nextHookPtr, code, wparam, lparam);
            } //返回,让后面的程序处理该消息             if (wparam.ToInt32() == 98 || wparam.ToInt32() == 66)
            {//如果用户输入的是 b                this.textBox1.Text = "a";
                return (IntPtr)1; //直接返回了,该消息就处理结束了 
            }
            else
            {
                return IntPtr.Zero; //返回,让后面的程序处理该消息 
            }
            
            //if (wparam.ToInt32() == 91)
            //{
            //    return (IntPtr)1;
            //}
            //else {
            //    return IntPtr.Zero;
            //}
        }        public void SetHook()
        {            if (_nextHookPtr != IntPtr.Zero) //已经勾过了                return;
            //线程钩子
            HookProc myhookProc = new HookProc(MyHookProc); //声明一个自己的Hook实现函数的委托对象            //_nextHookPtr = SetWindowsHookEx((int)HookType.Keyboard, myhookProc, IntPtr.Zero, GetCurrentThreadId()); //加到Hook链中             //全局钩子
            _nextHookPtr = SetWindowsHookEx((int)HookType.KeyboardLL, myhookProc, Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]), 0 ); //加到Hook链中             MessageBox.Show(_nextHookPtr.ToString());
        }        public void UnHook()
        {            if (_nextHookPtr != IntPtr.Zero)
            {
                UnhookWindowsHookEx(_nextHookPtr); //从Hook链中取消 
                _nextHookPtr = IntPtr.Zero;
            }        }        private void Form1_Load(object sender, EventArgs e)
        {
            SetHook(); 
        }        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            UnHook(); 
        }
    }
}

解决方案 »

  1.   

    类似的问题好多............前几天就有人文这个问题。你也不说明什么问题就发代码...
    新建一个form4窗体.增加2个button,增加事件。。然后复制代码
    其实不一样的地方就是红色的地方
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;
    using System.Reflection;
    using System.Diagnostics;namespace WindowsApplication1
    {
        ///  <summary> 
        /// Description of MainForm. 
        ///  </summary> 
        public partial class Form4 : Form
        {
            //委托 
            public delegate int HookProc(int nCode, int wParam, IntPtr lParam);
            static int hHook = 0;
            public const int WH_KEYBOARD_LL = 13;
            //LowLevel键盘截获,如果是WH_KEYBOARD=2,并不能对系统键盘截取,Acrobat Reader会在你截取之前获得键盘。 
            HookProc KeyBoardHookProcedure;
            //键盘Hook结构函数 
            [StructLayout(LayoutKind.Sequential)]
            public class KeyBoardHookStruct
            {
                public int vkCode;
                public int scanCode;
                public int flags;
                public int time;
                public int dwExtraInfo;
            }
            #region DllImport
            //设置钩子 
            [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);        [DllImport("kernel32.dll")]
            public static extern int GetCurrentThreadId();         [DllImport("kernel32.dll")]
            public static extern IntPtr GetModuleHandle(string name);

            
            #endregion
            #region 自定义事件
            public void Hook_Start()
            {
                // 安装键盘钩子 
                if (hHook == 0)
                {
                    KeyBoardHookProcedure = new HookProc(KeyBoardHookProc);                //hHook = SetWindowsHookEx(2,
                    //            KeyBoardHookProcedure,
                    //           GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName), GetCurrentThreadId());                hHook = SetWindowsHookEx(WH_KEYBOARD_LL,
                              KeyBoardHookProcedure,
                             GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName), 0);

                    //如果设置钩子失败. 
                    if (hHook == 0)
                    {
                        Hook_Clear();
                        //throw new Exception("设置Hook失败!");
                    }
                }
            }        //取消钩子事件 
            public void Hook_Clear()
            {
                bool retKeyboard = true;
                if (hHook != 0)
                {
                    retKeyboard = UnhookWindowsHookEx(hHook);
                    hHook = 0;
                }
                //如果去掉钩子失败. 
                if (!retKeyboard) throw new Exception("UnhookWindowsHookEx failed.");
            }        //这里可以添加自己想要的信息处理 
            public static int KeyBoardHookProc(int nCode, int wParam, IntPtr lParam)
            {
                if (nCode >= 0)
                {
                 
                    KeyBoardHookStruct kbh = (KeyBoardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyBoardHookStruct));
                    if (kbh.vkCode == (int)Keys.S && (int)Control.ModifierKeys == (int)Keys.Control)  // 截获F8 
                    {
                        MessageBox.Show("快捷键已拦截!不能保存!");
                        return 1;                }
                    if (kbh.vkCode == (int)Keys.Y
                       && (int)Control.ModifierKeys == (int)Keys.Control + (int)Keys.Alt)  //截获Ctrl+Alt+Y 
                    {                    //MessageBox.Show("不能全部保存!"); 
                        return 1;
                    }
                    if (kbh.vkCode == (int)Keys.X)
                    {
                        MessageBox.Show("不能全部保存!");
                        return 1;
                    }
                }
                return CallNextHookEx(hHook, nCode, wParam, lParam);
            }
            #endregion        public Form4()
            {            InitializeComponent();
            }
            private void button1_Click(object sender, EventArgs e)
            {
                Hook_Start();
            }        private void button2_Click(object sender, EventArgs e)
            {
                Hook_Clear();
            }    }
    }
      

  2.   

    全局钩子必须是一个独立的DLL,
    不要写到FORM APPLICANTION里钩子方法编译到库里,新建一个FORM方法调用
      

  3.   

    你知道什么?
    你有没试过
                   hHook = SetWindowsHookEx(WH_KEYBOARD, 
                              KeyBoardHookProcedure, 
                            GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName), 0); 把KEYBOARD_LL换成KEYBOARD,同样是全局钩子,但后者只响应本应用窗口中的按键,为什么呢?
      

  4.   

    一楼牛逼啊……终于找到了……安装全局钩子是这样做的,为什么我测试不能成功呢?
    hKeyboardHook = SetWindowsHookEx(13, KeyboardHookProcedure, Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]), 0);