C#中运用全局钩子

转自:

http://topic.csdn.net/u/20080328/07/e0343ac4-32eb-4d7b-acee-c479cf26560a.html

 

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();
        }
    }
}
以上程序并不能得到钩子,以下是改正后的:
 
50  修改 删除 举报 引用 回复

发表于:2008-03-28 09:58:531楼 得分:50
类似的问题好多............前几天就有人文这个问题。你也不说明什么问题就发代码...
新建一个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();
        }


    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值