CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
花落谁家,你作主! 盛大widget设计大赛英雄榜
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  Delphi >  VCL组件开发及应用

怎么让钩子(HOOK) 截获按键,并转化为别的按键!

楼主netlark(云雀)2001-03-06 18:11:00 在 Delphi / VCL组件开发及应用 提问

我想做一个hook   程序,让HOOK程序截获的按键如   '1'   转为'g'   如何实现?  
   
   
  问题点数:66、回复次数:12Top

1 楼Nicky_he(尼克)回复于 2001-03-06 19:19:00 得分 0

用Send_Message  
  vkey编码  
   
      VK_LBUTTON   =   1;  
      VK_RBUTTON   =   2;  
      VK_CANCEL   =   3;  
      VK_MBUTTON   =   4;     {   NOT   contiguous   with   L   &   RBUTTON   }  
      VK_BACK   =   8;  
      VK_TAB   =   9;  
      VK_CLEAR   =   12;  
      VK_RETURN   =   13;  
      VK_SHIFT   =   $10;  
      VK_CONTROL   =   17;  
      VK_MENU   =   18;  
      VK_PAUSE   =   19;  
      VK_CAPITAL   =   20;  
      VK_KANA   =   21;  
      VK_HANGUL   =   21;  
      VK_JUNJA   =   23;  
      VK_FINAL   =   24;  
      VK_HANJA   =   25;  
      VK_KANJI   =   25;  
      VK_CONVERT   =   28;  
      VK_NONCONVERT   =   29;  
      VK_ACCEPT   =   30;  
      VK_MODECHANGE   =   31;  
      VK_ESCAPE   =   27;  
      VK_SPACE   =   $20;  
      VK_PRIOR   =   33;  
      VK_NEXT   =   34;  
      VK_END   =   35;  
      VK_HOME   =   36;  
      VK_LEFT   =   37;  
      VK_UP   =   38;  
      VK_RIGHT   =   39;  
      VK_DOWN   =   40;  
      VK_SELECT   =   41;  
      VK_PRINT   =   42;  
      VK_EXECUTE   =   43;  
      VK_SNAPSHOT   =   44;  
      VK_INSERT   =   45;  
      VK_DELETE   =   46;  
      VK_HELP   =   47;  
  {   VK_0   thru   VK_9   are   the   same   as   ASCII   '0'   thru   '9'   ($30   -   $39)   }  
  {   VK_A   thru   VK_Z   are   the   same   as   ASCII   'A'   thru   'Z'   ($41   -   $5A)   }  
      VK_LWIN   =   91;  
      VK_RWIN   =   92;  
      VK_APPS   =   93;  
      VK_NUMPAD0   =   96;  
      VK_NUMPAD1   =   97;  
      VK_NUMPAD2   =   98;  
      VK_NUMPAD3   =   99;  
      VK_NUMPAD4   =   100;  
      VK_NUMPAD5   =   101;  
      VK_NUMPAD6   =   102;  
      VK_NUMPAD7   =   103;  
      VK_NUMPAD8   =   104;  
      VK_NUMPAD9   =   105;  
      VK_MULTIPLY   =   106;  
      VK_ADD   =   107;  
      VK_SEPARATOR   =   108;  
      VK_SUBTRACT   =   109;  
      VK_DECIMAL   =   110;  
      VK_DIVIDE   =   111;  
      VK_F1   =   112;  
      VK_F2   =   113;  
      VK_F3   =   114;  
      VK_F4   =   115;  
      VK_F5   =   116;  
      VK_F6   =   117;  
      VK_F7   =   118;  
      VK_F8   =   119;  
      VK_F9   =   120;  
      VK_F10   =   121;  
      VK_F11   =   122;  
      VK_F12   =   123;  
      VK_F13   =   124;  
      VK_F14   =   125;  
      VK_F15   =   126;  
      VK_F16   =   127;  
      VK_F17   =   128;  
      VK_F18   =   129;  
      VK_F19   =   130;  
      VK_F20   =   131;  
      VK_F21   =   132;  
      VK_F22   =   133;  
      VK_F23   =   134;  
      VK_F24   =   135;  
      VK_NUMLOCK   =   144;  
      VK_SCROLL   =   145;  
  {   VK_L   &   VK_R   -   left   and   right   Alt,   Ctrl   and   Shift   virtual   keys.  
      Used   only   as   parameters   to   GetAsyncKeyState()   and   GetKeyState().  
      No   other   API   or   message   will   distinguish   left   and   right   keys   in   this   way.   }  
      VK_LSHIFT   =   160;  
      VK_RSHIFT   =   161;  
      VK_LCONTROL   =   162;  
      VK_RCONTROL   =   163;  
      VK_LMENU   =   164;  
      VK_RMENU   =   165;  
      VK_PROCESSKEY   =   229;  
      VK_ATTN   =   246;  
      VK_CRSEL   =   247;  
      VK_EXSEL   =   248;  
      VK_EREOF   =   249;  
      VK_PLAY   =   250;  
      VK_ZOOM   =   251;  
      VK_NONAME   =   252;  
      VK_PA1   =   253;  
      VK_OEM_CLEAR   =   254;  
   
  就是HOOK技术加模拟按键啦!到程序员大本营里找。  
   
  Top

2 楼netlark(云雀)回复于 2001-03-06 21:44:00 得分 0

喂,老兄呀,您能不能说的清楚一点,我不太明白呀Top

3 楼2001Sky(呆鸟)回复于 2001-03-06 21:48:00 得分 0

对呀,到程序员大本营里找。在这里要花钱(分)的.  
   
  Top

4 楼netlark(云雀)回复于 2001-03-06 23:24:00 得分 0

各位大虾,快点帮我,我读了很多的HOOK   例程却没有办法达到这种效果,如有人知道,请救我呀!分数没有问题,我很多的1000分还是有的!Top

5 楼netlark(云雀)回复于 2001-03-06 23:26:00 得分 0

我在HOOK   例程里无法改变其值只能是屏蔽该值!不知道什么原因?Top

6 楼netlark(云雀)回复于 2001-03-07 08:12:00 得分 0

有人有完整的例程吗?(按照我的描述做的)?  
  能Mail   一份给我吗?Top

7 楼Nicky_he(尼克)回复于 2001-03-07 09:21:00 得分 0

贴一篇文章,取自http://go8.163.com/~aton/,  
  既然说明了出处,作者应该不会怪我了把。  
  这篇文章应该解决了你的问题  
   
   
  ☆★通过Delphi建立键盘鼠标动作纪录与回放★☆  
     
       
   
  很多的教学软件或系统监视软件可以自动记录回放用户的输入文字或点击按钮等操作操作,这个功能的实现是使用  
  了Windows的Hook函数。  
  Windows提供API函数SetwindowsHookEx来建立一个Hook,通过这个函数可以将一个程序添加到Hook链中监视Windows  
  消息,函数语法为:  
  SetWindowsHookEx(idHook:   Integer;   lpfn:   TFNHookProc;   hmod:   HINST;   dwThreadId:   DWORD)  
  其中参数idHook指定建立的监视函数类型。通过Windows   MSDN帮助可以看到,SetwindowsHookEx函数提供15种不同    
  的消息监视类型,在这里我们将使用WH_JOURNALRECORD和WH_JOURNALPLAYBACK来监视键盘和鼠标操作。参数lpfn指定消  
  息函数,在相应的消息产生后,系统会调用该函数并将消息值传递给该函数供处理。函数的一般形式为:  
  Hookproc   (code:   Integer;   wparam:   WPARAM;   lparam:   LPARAM):   LRESULT   stdcall;  
  其中code为系统指示标记,wParam和lParam为附加参数,根据不同的消息监视类型而不同。只要在程序中建立这样  
  一个函数再通过SetwindowsHookEx函数将它加入到消息监视链中就可以处理消息了。  
  在不需要监视系统消息时需要调用提供UnHookWindowsHookEx来解除对消息的监视。  
  WH_JOURNALRECORD和WH_JOURNALPLAYBACK类型是两种相反的Hook类型,前者获得鼠标、键盘动作消息,后者回放鼠  
  标键盘消息。所以在程序中我们需要建立两个消息函数,一个用于纪录鼠标键盘操作并保存到一个数组中,另一个用于  
  将保存的操作返给系统回放。  
  下面来建立程序,在Delphi中建立一个工程,在Form1上添加3个按钮用于程序操作。另外再添加一个按钮控件和一  
  个Edit控件用于验证操作。  
  下面是Form1的全部代码  
   
  unit   Unit1;  
   
  interface  
   
  uses  
  Windows,   Messages,   SysUtils,   Classes,   Graphics,   Controls,   Forms,   Dialogs,  
  StdCtrls;  
   
  type  
  TForm1   =   class(TForm)  
  Button1:   TButton;  
  Button2:   TButton;  
  Button3:   TButton;  
  Edit1:   TEdit;  
  Button4:   TButton;  
  procedure   FormCreate(Sender:   TObject);  
  procedure   Button1Click(Sender:   TObject);  
  procedure   Button2Click(Sender:   TObject);  
  procedure   Button3Click(Sender:   TObject);  
  private  
  {   Private   declarations   }  
  public  
  {   Public   declarations   }  
  end;  
   
  var  
  Form1:   TForm1;  
   
  EventArr:array[0..1000]of   EVENTMSG;  
  EventLog:Integer;  
  PlayLog:Integer;  
  hHook,hPlay:Integer;  
  recOK:Integer;  
  canPlay:Integer;  
  bDelay:Bool;  
  implementation  
   
  {$R   *.DFM}  
  Function   PlayProc(iCode:Integer;wParam:wParam;lParam:lParam):LRESULT;stdcall;  
  begin  
  canPlay:=1;  
  Result:=0;  
   
  if   iCode   <   0   then   //必须将消息传递到消息链的下一个接受单元  
  Result   :=   CallNextHookEx(hPlay,iCode,wParam,lParam)  
  else   if   iCode   =   HC_SYSMODALON   then  
  canPlay:=0  
  else   if   iCode   =   HC_SYSMODALOFF   then  
  canPlay:=1  
  else   if   ((canPlay   =1   )and(iCode=HC_GETNEXT))   then   begin  
  if   bDelay   then   begin  
  bDelay:=False;  
  Result:=50;  
  end;  
  pEventMSG(lParam)^:=EventArr[PlayLog];  
  end  
  else   if   ((canPlay   =   1)and(iCode   =   HC_SKIP))then   begin  
  bDelay   :=   True;  
  PlayLog:=PlayLog+1;  
  end;  
  if   PlayLog>=EventLog   then   begin  
  UNHookWindowsHookEx(hPlay);  
  end;  
  end;  
   
  function   HookProc(iCode:Integer;wParam:wParam;lParam:lParam):LRESULT;stdcall;  
  begin  
  recOK:=1;  
  Result:=0;  
   
  if   iCode   <   0   then  
  Result   :=   CallNextHookEx(hHook,iCode,wParam,lParam)  
  else   if   iCode   =   HC_SYSMODALON   then  
  recOK:=0  
  else   if   iCode   =   HC_SYSMODALOFF   then  
  recOK:=1  
  else   if   ((recOK>0)   and   (iCode   =   HC_ACTION))   then   begin  
  EventArr[EventLog]:=pEventMSG(lParam)^;  
  EventLog:=EventLog+1;  
   
  if   EventLog>=1000   then   begin  
  UnHookWindowsHookEx(hHook);  
  end;  
  end;  
  end;  
   
  procedure   TForm1.FormCreate(Sender:   TObject);  
  begin  
  Button1.Caption:='纪录';  
  Button2.Caption:='停止';  
  Button3.Caption:='回放';  
  Button4.Caption:='范例';  
  Button2.Enabled:=False;  
  Button3.Enabled:=False;  
  end;  
   
  procedure   TForm1.Button1Click(Sender:   TObject);  
  begin  
  EventLog:=0;  
  //建立键盘鼠标操作消息纪录链  
  hHook:=SetwindowsHookEx(WH_JOURNALRECORD,HookProc,HInstance,0);  
  Button2.Enabled:=True;  
  Button1.Enabled:=False;  
  end;  
   
  procedure   TForm1.Button2Click(Sender:   TObject);  
  begin  
  UnHookWindowsHookEx(hHook);  
  hHook:=0;  
   
  Button1.Enabled:=True;  
  Button2.Enabled:=False;  
  Button3.Enabled:=True;  
  end;  
   
  procedure   TForm1.Button3Click(Sender:   TObject);  
  begin  
  PlayLog:=0;  
  //建立键盘鼠标操作消息纪录回放链  
  hPlay:=SetwindowsHookEx(WH_JOURNALPLAYBACK,PlayProc,  
  HInstance,0);  
   
  Button3.Enabled:=False;  
  end;  
   
  end.  
   
  代码添加完毕后,运行程序,点击“纪录”按钮开始纪录操作,这时你可以在文本控件中输入一些文字或者点击  
  “范例”按钮,然后点击“停止”按钮停止纪录,再点击“回放”按钮就可以讲先前所做的操作回放。  
  在上面的程序中,HookProc是纪录操作的消息函数,每当有鼠标键盘消息发生时,系统都会调用该函数,消息信  
  息就保存在地址lParam中,我们可以讲消息保存在一个数组中。PlayProc是消息回放函数,当系统可以执行消息回放  
  时调用该函数,程序就将先前纪录的消息值返回到lParam指向的区域中,系统就会执行该消息,从而实现了消息回放。  
  Top

8 楼yhec(@_@ 俺是贫农俺怕谁)回复于 2001-03-07 09:48:00 得分 0

关注!Top

9 楼netlark(云雀)回复于 2001-03-07 16:03:00 得分 0

可是我并不需要回放,我只要您提供如何改变输入的键值?Top

10 楼Nicky_he(尼克)回复于 2001-03-08 11:17:00 得分 50

你把hook到的‘1’键键值改成‘g’的键值,纪录,回放。  
  稍微改动一下不就行了?  
  Top

11 楼Haha_kylix()回复于 2001-03-08 20:55:00 得分 16

告诉我,你是需要对其他的程序的输入作呢还是只针对自己的程序这样作?  
  如果你是对其他的程序的键盘输入作改动的话,你需要全局钩子,否则局部钩子就可以了。  
  注意有的钩子不能对消息作出修改,因为在你改好时消息都发过去了。  
  要查看清楚MSDN上怎么说Top

12 楼bbdog(贝贝狗)回复于 2001-08-29 21:18:11 得分 0

gzTop

相关问题

  • 钩子用DLL实现,当截获键盘按键后如何传递给主控程序(EXE)?在线等侯
  • 键盘HOOK如何能截获DOS程序的按键?
  • Hook钩子问题。
  • 如何编写钩子(HOOK)?
  • 关于全局钩子(HOOK)
  • hook钩子丢失问题
  • 我想用系统钩子截获WM_SHOWWINDOW消息
  • 鼠标钩子截获鼠标滚轴信息?
  • 请教如何用键盘钩子互换两个按键?
  • 用钩子截获了WM_IME_CHAR消息,如何得到其中的汉字?

关键词

  • 函数
  • 消息
  • 监视
  • 键盘
  • 鼠标
  • vk
  • 钩子
  • 按键
  • 程序
  • 纪录

得分解答快速导航

  • 帖主:netlark
  • Nicky_he
  • Haha_kylix

相关链接

  • Delphi类图书
  • Delphi类源码下载
  • Delphi控件下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo