zoukankan      html  css  js  c++  java
  • 使用钩子函数[1]


    目前对钩子的理解:

    譬如我们用鼠标在某个窗口上双击了一次, 或者给某个窗口输入了一个字母 A;
    首先发现这些事件的不是窗口, 而是系统!

    然后系统告诉窗口: 喂! 你让人点了, 并且是连续点了两鼠标, 你准备怎么办?
    或者是系统告诉窗口: 喂! 有人向你家里扔砖头了, 不信你看看, 那块砖头是 A.

    这时窗口的对有些事件会忽略、对有些事件会做出反应:
    譬如, 可能对鼠标单击事件忽略, 窗口想: 你单击我不要紧, 累死你我不负责;
    但一旦谁要双击我, 我会马上行动, 给你点颜色瞧瞧!
    这里窗口准备要采取的行动, 就是我们提前写好的事件.
    用 Windows 的话说, 窗口的事件就是系统发送给窗口的消息; 窗口要采取的行动(事件代码)就是窗口的回调函数.

    但是! 往往隔墙有耳. 系统要通知给窗口的"话"(消息), 可能会被另一个家伙(譬如是一个贼)提前听到!
    有可能这个贼就是专门在这等情报的, 贼知道后, 往往在窗口知道以前就采取了行动!
    并且这个贼对不同的消息会采取不同的行动方案, 它的行动方案一般也是早就准备好的;
    当然这个贼也不是对什么消息都感兴趣, 对不感兴趣的消息也就无须制定相应的行动方案.

    总结: 这个"贼"就是我们要设置的钩子; "贼"的"行动方案"就是钩子函数, 或者叫钩子的回调函数.

    钩子分两种, 一种是系统级的全局钩子; 一种是线程级的钩子.
    全局钩子函数需要定义在 DLL 中, 从线程级的钩子开始比较简单.

    其实钩子函数就三个:
    设置钩子: SetWindowsHookEx
    释放钩子: UnhookWindowsHookEx
    继续钩子: CallNextHookEx
    在线程级的钩子中经常用到 GetCurrentThreadID 函数来获取当前线程的 ID.

    下面例子中设定了一个线程级的键盘钩子, 专门拦截字母 A.
    unit Unit1;
    
    interface
    
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs;
    
    type
      TForm1 = class(TForm)
        procedure FormCreate(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
      end;
    
    {声明键盘钩子回调函数; 其参数传递方式要用 API 的 stdcall}
    function KeyHook(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
    
    var
      Form1: TForm1;
    
    implementation
    
    {$R *.DFM}
    
    var
      hook: HHOOK; {定义一个钩子句柄}
    
    {实现键盘钩子回调函数}
    function KeyHook(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT;
    begin
      if (wParam = 65) then Beep; {每拦截到字母 A 会发声}
      Result := CallNextHookEx(hook, nCode, wParam, lParam);
    end;
    
    {设置键盘钩子}
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      hook := SetWindowsHookEx(WH_KEYBOARD, @KeyHook, 0, GetCurrentThreadID);
    end;
    
    {释放键盘钩子}
    procedure TForm1.FormDestroy(Sender: TObject);
    begin
      UnhookWindowsHookEx(hook);
    end;
    
    end.
    
  • 相关阅读:
    HDU 1874 畅通工程续(dijkstra)
    HDU 2112 HDU Today (map函数,dijkstra最短路径)
    HDU 2680 Choose the best route(dijkstra)
    HDU 2066 一个人的旅行(最短路径,dijkstra)
    关于测评机,编译器,我有些话想说
    测评机的优化问题 时间控制
    CF Round410 D. Mike and distribution
    数字三角形2 (取模)
    CF Round410 C. Mike and gcd problem
    CF Round 423 D. High Load 星图(最优最简构建)
  • 原文地址:https://www.cnblogs.com/wanqian/p/3124098.html
Copyright © 2011-2022 走看看