谁能用c语言写一个钩子函数的例子

谁能用c语言写一个钩子函数的例子,第1张

例子:

HWND hWnd = NULL//定义成全局变量

HHOOK hKeyboard

HHOOK hMouse

LRESULT CALLBACK MouseProc( int nCode, WPARAM wParam, LPARAM lparam )// 鼠标钩子函数

{

return 1 // 返回非零值表示已经对当前消息进行了处理,这样系统就不会再将这个消息传递给目标窗口过程

}

LRESULT CALLBACK KeyboardProc( int nCode, WPARAM wParam, LPARAM lparam )

if( VK_F4 == wParam &&(1 == (lparam>>29&1)) )// 系统后门:Alt+F4键退出程序

{

::SendMessageA( hWnd, WM_CLOSE, 0, 0 )

定义钩子函数

钩子函数是一种特殊键袜尘的回调函数。钩子监视的特定事件发生后,系统会调用钩子函数进行处理。不同事件的钩子函数的形式是各不相同的。下面以鼠好埋标钩子函数举例说明钩子函数的原型:

LRESULT CALLBACK HookProc(int nCode ,WPARAM wParam,LPARAM lParam)

参数wParam和 lParam包含所钩消息的信息,比如鼠标位置、状态,键盘按键等。nCode包含有关消息本身的信息,比如是否从消息队列中移出。 我们先在钩子函数中实现自定义的功能,然后稿禅调用函数 CallNextHookEx.把钩子信息传递给钩子链的下一个钩子函数。CallNextHookEx.的原型如下:

LRESULT CallNextHookEx( HHOOK hhk, int nCode, WPARAM wParam, LPARAM lParam ) 参数 hhk是钩子句柄。nCode、wParam和lParam 是钩子函数。

当然也可以通过直接返回TRUE来丢弃该消息,就阻止了该消息的传递。

pytest为任何给定的钩子(hook)规范调用已注册插件的钩子(hook)方法。让我们看一下钩子(hook)的典型钩子(hook)方法,pytest在收集完所有测试项目后调用。 pytest_collection_modifyitems(session, config,items)

当我们 pytest_collection_modifyitems 在插件中实现一个方法时,pytest将在注册期间验证你是否使用了与规范匹配的参数名称,如果没有则拯救。

让我们看一下可能的实现:

这里, pytest 将传入 config (pytest配置对象)和 items (收集的测试项列表)余枣,但不会传入 session 参数,因为我们没有在方法签名中列出它。这种动态的“修剪”参数允许 pytest “未来兼容”:我们可以引入新的钩子(hook)命名参数而不破坏现有钩子(hook)实现的签名。这是pytest插件的一般长期兼容性的原因之一。

请注意,除了 pytest_runtest_* 不允许引发异常之外的钩子(hook)方法。这样做会打破pytest运行。

大多数对 pytest 钩子(hook)的调用都会产生一个 结果列表, 其中包含被调用钩子(hook)方法的所有非None结果。

一些钩子(hook)规范使用该 firstresult=True 选项,以便钩子(hook)调用仅执行,直到N个注册方法中的第一个返回非None结果,然后将其作为整个钩子(hook)调用的结果。在这种情况下,不会调用其余的钩子(hook)方法。

版本2.7中的新功能。

pytest插件可以实现钩子(hook)包装器,它包装其他钩子(hook)实现的执行。钩子(hook)包装器是一个生成器方法,它只产生一次。当pytest调用钩子(hook)时,它首先执行钩子(hook)包装器并传递与常规钩子(hook)相同的参数。

在钩子(hook)包装器的屈服点,pytest将执行下一个钩子(hook)实现,并以 Result 封装结果或异常信息的实例的形式将其结果返回到屈服点。因此,屈服点本身通常不会引发异常(除非存在错误)。

以下是钩子(hook)包装器的示例定义:

请注意,钩子(hook)包装器本身不返回结果,它们只是围绕实际的钩子(hook)实现执行跟踪或其他副作用。如果底层钩子(hook)的结果是一个可变对象,它们可能会修改该结果,但最好避免它。

有关更多信息,请参阅 插件文档 。

对于任何给定的钩子(hook)规范,可能存在多个实现,因此我们通常将 hook 执行视为 1:N 方法调用,其中 N 是已注册方法的数量。有一些方法隐枝可以影响钩子(hook)实现是在其他人之前还是之后,即在 N -sized方法列表中的位置:

这是执行的顺序:

这是可能的使用 tryfirst ,并 trylast 结合还 hookwrapper=True 处于这种情况下,它会影响彼此之间hookwrappers的排序。

插件和 conftest.py 文件可以声明新钩子(hook),然后可以由其他插件实现,以便改变行为或与新插件交互:

<dt>pytest_addhooks (*pluginmanager *) [来源]

在插件注册时调用,允许通过调用添加新的挂钩 。 pluginmanager.add_hookspecs(module_or_class, prefix)

参数: | pluginmanager ( _pytest.config.PytestPluginManager ) - pytest插件管理器

钩子(hook)通常被声明为do-nothing方法,它们只包含描述何时调用钩子(hook)以及期望返回值的文档。

有关示例,请参阅 xdist中 的 newhooks.py 。

由于标准的 验证机制, 如上所述使用插件中的新钩子(hook)可能有点棘手:如果你依赖未安装的插件,验证将失败并且错误消息对你的用户没有多大意义。

一灶毁敏种方法是将钩子(hook)实现推迟到新的插件,而不是直接在插件模块中声明钩子(hook)方法,例如:

1.钩子到底是什么意思呢?为啥按Ctrl+Alt+Z就把QQ主面板d出来?这就是用到了键盘钩子,他能截获系统的瞎激明键盘事件。

而键盘钩子就可以在用户按Ctrl+Alt+Z的时候截取到这个按键消息。

然后对这个消息进行处理,比如说QQ的处理就是把他的主面板d出来。

2.C#键盘鼠标勾子的例程:

using System

using System.Runtime.InteropServices

using System.Reflection

using System.Threading

using System.Windows.Forms

using System.Diagnostics

using System.Collections.Generic

namespace ConsoleApplicationTest

{

    /// <summary> 

    /// 这个类可以让你得到一个在运行中程序的所有鼠标和键盘事件 (系统钩子)

    /// 并且引发一个带KeyEventArgs和MouseEventArgs参数的.NET事件以便你很容易使用这些信息

    /// 鼠标钩子处理函数:MouseHookProc

    /// 键盘钩子处理函数:KeyboardHookProc

    /// 使用方法:

    ///   1.新建该类。

    ///   2.声明OnMouseActivity、OnKeyDownEvent、OnKeyUpEvent、OnKeyPressEvent.

    ///   3.使用时调用相应的事件即可。

    ///   4.要添加应用请在MouseHookProc()和KeyboardHookProc()中自己添加。

    /// 使用示例:

    /// public mkhook = new KeyBordHook()

    /// mkhook.OnKeyDownEvent += new KeyEventHandler(OnKeyDownEventHandler)

    /// mkhook.OnMouseActivity += new MouseEventHandler(OnMouseEventHandler)

    /// private void OnKeyDownEventHandler(object sender, KeyEventArgs e)

    /// {

    ///     Console.WriteLine("KeyDown......")

    /// }

    /// private void OnMouseEventHandler(object sender, MouseEventArgs e)

    /// {

    ///     Console.WriteLine("MouseEvent......")

    /// }

    /// </summary> 

    /// <remarks> 

    /// 修改:xyan nay6@163.com

    /// 修改时间:10.06.11 

    /// </remarks> 

    public class KeyBordHook : IDisposable

    {

        private const int WM_KEYDOWN = 0x100

        private const int WM_KEYUP = 0x101

        private const int WM_SYSKEYDOWN = 0x104

        private const int WM_SYSKEYUP = 0x105

        //全局的事件 

        public event MouseEventHandler OnMouseActivity//鼠标事件

        public event KeyEventHandler OnKeyDownEvent//键按下

        public event KeyEventHandler OnKeyUpEvent//键放下

        public event KeyPressEventHandler OnKeyPressEvent//键按下

        static int hMouseHook = 0   //鼠标钩子句柄

        static int hKeyboardHook = 0 //键盘钩子句柄

        //鼠标常量 

        磨告public const int WH_MOUSE = 7

        public const int WH_MOUSE_LL = 14 //鼠标常量 

        public const int WH_KEYBOARD_LL = 13 //键盘铅大常量 

        HookProc MouseHookProcedure   //声明鼠标钩子事件类型.

        HookProc KeyboardHookProcedure //声明键盘钩子事件类型.

        //Declare   wrapper   managed   POINT   class. 

        [StructLayout(LayoutKind.Sequential)]

        public class POINT

        {

            public int x

            public int y

        }

        //声明鼠标钩子的封送结构类型 

        [StructLayout(LayoutKind.Sequential)]

        public class MouseHookStruct

        {

            public POINT pt

            public int hwnd

            public int wHitTestCode

            public int dwExtraInfo

        }

        //声明键盘钩子的封送结构类型 

        [StructLayout(LayoutKind.Sequential)]

        public class KeyboardHookStruct

        {

            public int vkCode //表示一个在1到254间的虚似键盘码 

            public int scanCode //表示硬件扫描码 

            public int flags

            public int time

            public int dwExtraInfo

        }

        //装置钩子的函数 

        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]

        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", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]

        public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam)

        [DllImport("user32")]

        public static extern int ToAscii(int uVirtKey, int uScanCode, byte[] lpbKeyState, byte[] lpwTransKey, int fuState)

        [DllImport("user32")]

        public static extern int GetKeyboardState(byte[] pbKeyState)

        [DllImport("kernel32.dll", CharSet = CharSet.Auto,

            CallingConvention = CallingConvention.StdCall)]

        private static extern IntPtr GetModuleHandle(string lpModuleName)

        public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam)

        //先前按下的键

        public List<Keys> preKeys = new List<Keys>()

        /// <summary> 

        /// 墨认的构造函数构造当前类的实例并自动的运行起来. 

        /// </summary> 

        public KeyBordHook()

        {

            Start()

        }

        //析构函数. 

        ~KeyBordHook()

        {

            Stop()

        }

        public void Dispose()

        {

            Stop()

        }

        public void Start()

        {

            //安装键盘钩子 

            if (hKeyboardHook == 0)

            {

                KeyboardHookProcedure = new HookProc(KeyboardHookProc)

                //hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure, Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]), 0)

                Process curProcess = Process.GetCurrentProcess()

                ProcessModule curModule = curProcess.MainModule

                hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL,

                    KeyboardHookProcedure,

                    GetModuleHandle(curModule.ModuleName),

                    0)

                if (hKeyboardHook == 0)

                {

                    Stop()

                    Console.WriteLine("SetWindowsHookEx ist failed.")

                    throw new Exception("SetWindowsHookEx ist failed.")

                }

            }

            //   install   Mouse   hook   

            if (hMouseHook == 0)

            {

                //   Create   an   instance   of   HookProc. 

                MouseHookProcedure = new HookProc(this.MouseHookProc)

                Process curProcess = Process.GetCurrentProcess()

                ProcessModule curModule = curProcess.MainModule

                //curProcess.Threads[0].Id

                hMouseHook = SetWindowsHookEx(WH_MOUSE_LL,

                    MouseHookProcedure,

                    GetModuleHandle(curModule.ModuleName),

                    0)//curProcess.Id//Process.GetCurrentProcess().Id

                //If   SetWindowsHookEx   fails. 

                if (hMouseHook == 0)

                {

                    Stop()

                    Console.WriteLine("SetWindowsHookEx   failed. ")

                    throw new Exception("SetWindowsHookEx   failed. ")

                }

            }

        }

        public void Stop()

        {

            bool retMouse = true

            bool retKeyboard = true

            if (hMouseHook != 0)

            {

                retMouse = UnhookWindowsHookEx(hMouseHook)

                hMouseHook = 0

            }

            if (hKeyboardHook != 0)

            {

                retKeyboard = UnhookWindowsHookEx(hKeyboardHook)

                hKeyboardHook = 0

            }

            //如果卸下钩子失败 

            if (!(retKeyboard))

            {

                Console.WriteLine("UnhookWindowsHookEx failed.")

                throw new Exception("UnhookWindowsHookEx failed.")

            }

        }

        private const int WM_MOUSEMOVE = 0x200

        private const int WM_LBUTTONDOWN = 0x201

        private const int WM_RBUTTONDOWN = 0x204

        private const int WM_MBUTTONDOWN = 0x207

        private const int WM_LBUTTONUP = 0x202

        private const int WM_RBUTTONUP = 0x205

        private const int WM_MBUTTONUP = 0x208

        private const int WM_LBUTTONDBLCLK = 0x203

        private const int WM_RBUTTONDBLCLK = 0x206

        private const int WM_MBUTTONDBLCLK = 0x209

        private int MouseHookProc(int nCode, Int32 wParam, IntPtr lParam)

        {

            //   if   ok   and   someone   listens   to   our   events 

            if ((nCode >= 0) && (OnMouseActivity != null))

            {

                MouseButtons button = MouseButtons.None

                switch (wParam)

                {

                    case WM_LBUTTONDOWN://鼠标左键

                    case WM_LBUTTONUP:

                    case WM_LBUTTONDBLCLK:

                        button = MouseButtons.Left

                        break

                    case WM_RBUTTONDOWN://鼠标右键

                    case WM_RBUTTONUP:

                    case WM_RBUTTONDBLCLK:

                        button = MouseButtons.Right

                        break

                    //case WM_MBUTTONDOWN:

                    //    //case   WM_MBUTTONUP:   

                    //    //case   WM_MBUTTONDBLCLK:   

                    //    button = MouseButtons.Middle

                    //    break

                    default:

                        break

                }

                int clickCount = 0

                if (button != MouseButtons.None)

                {

                    if (wParam == WM_LBUTTONDBLCLK || wParam == WM_RBUTTONDBLCLK || wParam == WM_MBUTTONDBLCLK)

                    {

                        clickCount = 2

                    }

                    else

                    {

                        clickCount = 1

                    }

                }

                //}

                //Console.WriteLine(clickCount.ToString())

                //Marshall   the   data   from   callback. 

                MouseHookStruct MyMouseHookStruct = (MouseHookStruct)Marshal.PtrToStructure(lParam, typeof(MouseHookStruct))

                MouseEventArgs e = new MouseEventArgs(

                button,

                clickCount,

                MyMouseHookStruct.pt.x,

                MyMouseHookStruct.pt.y,

                0)

                OnMouseActivity(this, e)

            }

            return CallNextHookEx(hMouseHook, nCode, wParam, lParam)

        }

    }

}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12348333.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-24
下一篇 2023-05-24

发表评论

登录后才能评论

评论列表(0条)

保存