做HOOK钩信系统消息,可用SETWINDOWSHOOKEX函数设置钩子过程。想截获键盘按键盘消息,可挂接WH_KEYBOAD钩子。钩子实现分为全局的和对于应用程序线程的。想做成全局钩子,必须把钩子的处理过程做到DLL中才可实现。
可用到的API如下:
SETWINDOWSHOOKEX
CALLNEXTHOOK
UNHOOKWINDOWSHOOKEX

解决方案 »

  1.   

    就是上面的方法,MSDN中有完整的例子,用API写的,与所使用的语言
    无关(例子是C++代码,但不难转换成Delphi).
      

  2.   

    在DELPHI中HOOK程序的编写   在编写WINDOWS应用程序的时候,有时候我们希望所编写的程序可以捕获用户的某一个特定的动作(比如是否按下鼠标右键)。如果我们的程序处于系统前台,实现这一功能并不复杂。但如果程序在后台运行或者程序不是当前运行的进程的话,这一功能应该如何实现呢?答案就是HOOK程序。   ■ 使用DELPHI实现的HOOK程序   DELPHI作为一种可视化的开发工具以其程序开发的短周期和编译代码的高效率受到了广大程序人员的喜爱。一般来说,编写HOOK程序应将hook procedures函数编写为DLL,然后在主程序中调用。因此,编写HOOK程序需要调用API函数并将其编译为DLL(动态连接库),这两点在DELPHI中实现起来可以说是轻而易举。通过以下的小例子你可以看到在DELPHI中实现HOOK程序是多么的简单。   首先是DLL的源代码(我们假设需要捕捉CRTL+N这一击键动作):   选择FILE菜单中的NEW选项,选择产生一个新的DLL模板,存为HKTEST.DPR 
        library HKTest;   uses   HKProc in ′HKProc.pas′;// hook procedures函数在这个文件中定义   exports    EnableHotKeyHook, 
       DisableHotKeyHook;   //输出两个函数,保证在其他程序中可以调用这个DLL 
      begin 
       hNextHookProc := 0; 
       //以下这两条保证在DLL释放时解除HOOK 
       procSaveExit := ExitProc; 
       ExitProc := @HotKeyHookExit; 
      end.   以下是文件HKPROC.PAS的源码   unit HKProc;   interface   uses 
       Windows, Messages;   var 
       hNextHookProc: HHook; 
       procSaveExit: Pointer; 
      function KeyboardHookHandler(iCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; export; 
      function EnableHotKeyHook: BOOL; export;//使HOOK生效 
      function DisableHotKeyHook: BOOL; export;//使HOOK失效 
      procedure HotKeyHookExit; far;//   implementation   function KeyboardHookHandler(iCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; export; 
      const 
       —KeyPressMask = $80000000; 
      begin 
       Result := 0; 
       If iCode < 0 Then 
       begin 
         Result := CallNextHookEx(hNextHookProc, iCode, wParam, lParam); 
         Exit; 
       end; 
      //捕捉CRTL+N 
       if ((lParam and —KeyPressMask) = 0) and (GetKeyState(vk—Control) < 0) and (wParam = Ord(′N′)) then 
       begin 
         Result := 1; 
         WinExec(′Notepad.exe′, sw—Normal);//每当用户按下CRTL+N时运行记事本程序
         end; 
      end;   function EnableHotKeyHook: BOOL; export; 
      begin 
       Result := False; 
       if hNextHookProc <> 0 then Exit; // 连接到WH—KEYBOARD HOOK链,以捕捉击键动作。同时保留传回值以免HOOK链中断 
       hNextHookProc := SetWindowsHookEx(WH—KEYBOARD, KeyboardHookHandler, HInstance, 0); 
       Result := hNextHookProc <> 0; 
      end;   function DisableHotKeyHook: BOOL; export; 
      begin 
       if hNextHookProc <> 0 then 
       begin 
         UnhookWindowshookEx(hNextHookProc); //解除 Keyboard Hook 
         hNextHookProc := 0; 
         MessageBeep(0); 
          MessageBeep(0); 
       end; 
       Result := hNextHookProc = 0; 
      end;   procedure HotKeyHookExit; 
      begin 
       // 如果忘了解除HOOK,自动代理解除HOOK 
       if hNextHookProc <> 0 then DisableHotKeyHook; 
       ExitProc := procSaveExit; 
      end;   end.   该程序在编译以后会产生一个名为HKTEST.dll的文件,在程序中调用该DLL的方法非常的简单,只需声明DLL中的两个函数:   function EnableHotKeyHook: BOOL; external ′HKTEST.DLL′;   function DisableHotKeyHook: BOOL; external ′HKTEST.DLL′;   然后就可以在程序中使用EnableHotKeyHook函数来使HOOK有效,使用DisableHotKeyHook来关闭HOOK。在程序运行中当HOOK程序运行时,你会看到无论程序当前是否在前台,只要你按下CRTL+N,系统就会启动一个记事本的进程。   有一点应当注意的是:因为HOOK程序增加了系统处理每一条消息的工作量,它的运行有可能会降低系统的运行效率,所以在不需要的时候一定要将HOOK程序关闭。