求教一个参数的取得。谢谢!(20分)

  • 主题发起人 主题发起人 jbas
  • 开始时间 开始时间
J

jbas

Unregistered / Unconfirmed
GUEST, unregistred user!
这是一个hook程序的一部分!我想知道下面的EvnMsg.paramL=20520这个“20520"怎样的到的
,如果我想监视a,b,1,2这样的数,那个evnmsg.paraml=???;哪有介绍呀。delphi找不到那个20520的定义
谢谢!
function rPro(iCode:integer;wParam:wParam;lParam:lParam):LResult;stdcall;
var EvnMsg:TEventMsg;
begin
; ;EvnMsg:=PEventMsg(lParam)^;
; ;if EvnMsg.message=WM_KEYDOWN then
; ;begin
; ; ;if EvnMsg.paramL=20520 then ; ; ;//‘↓’键被按下
; ; ; showmessage('↓');
; ;end;

end;
 
高手们发表一下你的意见!大家应该碰到过吧!
 
我也不会。
 
‘↓’的键值是40,我用ord(key)的到的,但那个”20520“怎样的得到呢?我查了好像是
虚拟键值,我还是不懂,高手们帮忙了,小弟分不多了,只有一颗真诚的求教之心!
 
不知道,应该能查到吧,你查EventMsg试试
 
我都查了,在sdk中查不到的。在delphi中源代码中也没有说明的部分,只有结构!
 
我把20520改为20519或20521,可是都不是‘↓’旁边的键。
再帮帮忙吧!是组合的吧,真是不懂!
 
找到的一点,但因为周围没有相关的书和资料,不能给你好的解释.呵呵,这会儿也没时间.
不过,你可以参考这些键值了.出自jingtao.
unit Unit1;

interface

uses
; Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
; StdCtrls, ExtCtrls;

type
; TForm1 = class(TForm)
; ; ListBox1: TListBox;
; ; Button1: TButton;
; ; Button2: TButton;
; ; procedure FormCreate(Sender: TObject);
; ; procedure Button1Click(Sender: TObject);
; ; procedure Button2Click(Sender: TObject);
; private
; ; function Keyhookresult(lP: integer; wP: integer): pchar;
; ; { Private declarations }
; public
; ; { Public declarations }
; end;
var
; Form1: TForm1;
; hookkey: string;
; hooktimes: word;
; hHook: integer;
implementation
{$R *.DFM}

function TForm1.Keyhookresult(lP: integer; wP: integer): pchar;
begin
; result := '[Print Screen]';
; case lp of
; ; 10688: result := '`';
; ; 561: Result := '1';
; ; 818: result := '2';
; ; 1075: result := '3';
; ; 1332: result := '4';
; ; 1589: result := '5';
; ; 1846: result := '6';
; ; 2103: result := '7';
; ; 2360: result := '8';
; ; 2617: result := '9';
; ; 2864: result := '0';
; ; 3261: result := '-';
; ; 3515: result := '=';
; ; 4177: result := 'Q';
; ; 4439: result := 'W';
; ; 4677: result := 'E';
; ; 4946: result := 'R';
; ; 5204: result := 'T';
; ; 5465: result := 'Y';
; ; 5717: result := 'U';
; ; 5961: result := 'I';
; ; 6223: result := 'O';
; ; 6480: result := 'P';
; ; 6875: result := '[';
; ; 7133: result := ']';
; ; 11228: result := '/';
; ; 7745: result := 'A';
; ; 8019: result := 'S';
; ; 8260: result := 'D';
; ; 8518: result := 'F';
; ; 8775: result := 'G';
; ; 9032: result := 'H';
; ; 9290: result := 'J';
; ; 9547: result := 'K';
; ; 9804: result := 'L';
; ; 10170: result := ';';
; ; 10462: result := '''';
; ; 11354: result := 'Z';
; ; 11608: result := 'X';
; ; 11843: result := 'C';
; ; 12118: result := 'V';
; ; 12354: result := 'B';
; ; 12622: result := 'N';
; ; 12877: result := 'M';
; ; 13244: result := ',';
; ; 13502: result := '.';
; ; 13759: result := '/';
; ; 13840: result := '[Right-Shift]';
; ; 14624: result := '[Space]';
; ; 283: result := '[Esc]';
; ; 15216: result := '[F1]';
; ; 15473: result := '[F2]';
; ; 15730: result := '[F3]';
; ; 15987: result := '[F4]';
; ; 16244: result := '[F5]';
; ; 16501: result := '[F6]';
; ; 16758: result := '[F7]';
; ; 17015: result := '[F8]';
; ; 17272: result := '[F9]';
; ; 17529: result := '[F10]';
; ; 22394: result := '[F11]';
; ; 22651: result := '[F12]';
; ; 10768: Result := '[Left-Shift]';
; ; 14868: result := '[CapsLock]';
; ; 3592: result := '[Backspace]';
; ; 3849: result := '[Tab]';
; ; 7441:
; ; ; if wp > 30000 then
; ; ; ; result := '[Right-Ctrl]'
; ; ; else
; ; ; ; result := '[Left-Ctrl]';
; ; 13679: result := '[Num /]';
; ; 17808: result := '[NumLock]';
; ; 300: result := '[Print Screen]';
; ; 18065: result := '[Scroll Lock]';
; ; 17683: result := '[Pause]';
; ; 21088: result := '[Num0]';
; ; 21358: result := '[Num.]';
; ; 20321: result := '[Num1]';
; ; 20578: result := '[Num2]';
; ; 20835: result := '[Num3]';
; ; 19300: result := '[Num4]';
; ; 19557: result := '[Num5]';
; ; 19814: result := '[Num6]';
; ; 18279: result := '[Num7]';
; ; 18536: result := '[Num8]';
; ; 18793: result := '[Num9]';
; ; 19468: result := '[*5*]';
; ; 14186: result := '[Num *]';
; ; 19053: result := '[Num -]';
; ; 20075: result := '[Num +]';
; ; 21037: result := '[Insert]';
; ; 21294: result := '[Delete]';
; ; 18212: result := '[Home]';
; ; 20259: result := '[End]';
; ; 18721: result := '[PageUp]';
; ; 20770: result := '[PageDown]';
; ; 18470: result := '[UP]';
; ; 20520: result := '[DOWN]';
; ; 19237: result := '
';
; ; 19751: result := '
';
; ; 7181: result := '[Enter]';
; end;
end;

function HookProc(iCode: integer; wParam: wParam; lParam: lParam): LResult; stdcall;
begin
; if (peventmsg(lparam)^.message = WM_KEYDOWN) then
; ; hookkey := hookkey+ Form1.Keyhookresult(peventMsg(lparam)^.paramL, peventmsg(lparam)^.paramH);
; if length(hookkey) > 55 then
; ; begin
; ; ; ;Form1.ListBox1.Items.Add(hookkey);
; ; ; hookkey := TimeToStr(now) + ' ;';
; ; end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
; hooktimes := 0;
; hHook := 0;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
; inc(hooktimes);
; if hooktimes = 1 then
; ; begin
; ; ; hookkey := TimeToStr(now) + ' ;';
; ; ; hHook := SetWindowsHookEx(WH_JOURNALRECORD, HookProc, HInstance, 0);
; ; ; MessageBox(0, '键盘监视启动', '信息', MB_ICONINFORMATION + MB_OK);
; ; end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
; UnHookWindowsHookEx(hHook);
; hHook := 0;
; if hooktimes <> 0 then
; ; begin
; ; ; MessageBox(0, '键盘监视关闭', '信息', MB_ICONINFORMATION + MB_OK);
; ; end;
; hooktimes := 0;
end;

end.​
 
我想,你可以这样,就是你运行程序,在上面设置一个断点,然后运行程序,并且运行的时候,
按A,B,或者C、1、2等等,这些键,这样你就可以在中断的时候查看lParam的值了。
 
sorry
这方面的没接触过
 
to Kingron大侠,谢谢关注!但是我在这个function 中设置断点的时候,程序就死了。。。
to zhangkan大侠,非常感谢,lp真的是没有规律的呀?不然我想jingtao也不会一个一个
列出来了!这些参数就够了,非常感谢各位!就是分数太少了,大家都是富翁应该不会介意的
,谢谢了!
 
OH....这个我也没有接触过。哈哈。
但是我大概花了半个小时查资料,相信问题已经解决了。:)

1. “wParam:wParam;lParam”之类的东西都是Windows的消息处理中用的,这相信大家都知道。

2. 在Delphi中(messages.pas单元),所有的Windows消息被描述成TMessage,如下结构(相信大
家也都知道):
; TMessage = packed record
; ; Msg: Cardinal;
; ; case Integer of
; ; ; 0: (
; ; ; ; WParam: Longint;
; ; ; ; LParam: Longint;
; ; ; ; Result: Longint);
; ; ; 1: (
; ; ; ; WParamLo: Word;
; ; ; ; WParamHi: Word;
; ; ; ; LParamLo: Word;
; ; ; ; LParamHi: Word;
; ; ; ; ResultLo: Word;
; ; ; ; ResultHi: Word);
; end;

3. 在Delphi中(messages.pas单元),WM_KEYDOWN的消息用TWMKey来描述,这就不一定有人知道了。
这个结构如下(我将它与TMessage的结构对应起来,大家就容易看出LParam是什么值了):
; TWMKey = packed record
; ; Msg: Cardinal;
; ; CharCode: Word; ; ; ; ;//WParamLo: Word;
; ; Unused: Word; ; ; ; ; ;//WParamHi: Word;
; ; KeyData: Longint; ; ; ;//LParamLo and LParamHi
; ; Result: Longint; ; ; ; //ResultLo and ResultHi
; end;

4. 打开Delphi帮助,找TWMKey type。从帮助中可知:
KeyData包含repeat count, scan code, extended-key flag, context code等信息。
即WM_KEYDOWN的keystroke message。

5. 进yahoo或者Google,查“keystroke”,可以进入微软在线的MSDN。找到如下标题:
http://msdn.microsoft.com/library/en-us/winui/keybinpt_7wvn.asp

OK. 现在你已经找到你要的东西了。这里有一张图,用来描述paraml的每一个位的意义以
及它们如何组合在一起。
相信不再需要我的帮助了吧?
:)

哈哈,其实告诉你答案不如告诉你方法。如此的话,以后类似于这样查资料的问题你就可
以自己解决了。:)
 
哪,其实你可以这样,不一定要用断点啊,你可以把这个数据Save到一个文件里面啊!这样
就可以从文件里面读取出来了。:)
 
to aimingoo大侠:谢谢你的教导!
我只查了sdk中的WM_KEYDOWN事件里的参数,没见到那些我要的参数,只查到
WM_KEYDOWN ;
nVirtKey = (int) wParam; ; ;// virtual-key code
lKeyData = lParam; ;
那些lkeydata我想是我要的,但是它都是?-?这样的数,
你那个“即WM_KEYDOWN的keystroke message。”我就无从得知了。我看我还的再学学,才能
领会你的思想了!

to Kingron大侠,你说的"把这个数据保存到文件里",是指这些lparam的值保存到文件里吧,再从
文件里读出来吧!不用把这些值写在程序里。谢谢了!
 
to jbas:
---------
下面是Delphi Help中关于TWMKey type的内容:
The KeyData field indicates the repeat count, scan code, extended-key flag,
context code, and so on. See the Windows help system for a keystroke message
; ; ; ; ; ; ; ; ; ; ; ; ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
such as WM_KEYDOWN for details on the possible values.

——“即WM_KEYDOWN的keystroke message。”只是上面那一部分的意思。我并没有将原
文译给你。哈哈。
 
谢谢aimingoo,
小弟我还是不太了解你的思想?你为什么会看到那个TWMKey type呢?至少凭我现在的水平我
想不到的。我只会查wm_keydown,EvnMsg,paramL。看来高手的思维就是不一样。
你上面的第三条,我是想不到的。等我水平高了,说不定能看懂了。
谢谢高手的指导。
 
哈哈哈,这与水平没关系的。如果你要习惯看源代码,你一定得会用grep这个工具,
这个工具可以在delphi/bin这个目录中找到。

你在delphi/source目录中打DOS命令行:
; ; ;../bin/grep -d+ -n+ -i+ wm_keydown *.pas
此时,你得到你信息中就有这样几行(当然也有其它的行,哈哈):
----------------------------------------------------------------------------
File Vcl/controls.pas:
118 ; ; ; CN_KEYDOWN ; ; ; ; ; = CN_BASE + WM_KEYDOWN;
1026 ; ; ; ;procedure WMKeyDown(var Message: TWMKeyDown); message WM_KEYDOWN;
----------------------------------------------------------------------------
这表明在controls.pas单元的第1026行中,一个过程响应了WM_KEYDOWN消息,消息入口采
用TWMKeyDown消息类型。
在Delphi中,消息响应过程的入口被强制成不同的消息类型来处理,事实上它们都是TMessage
这个记录类型的不同影射(它们一定是占用相同大小的内存空间的)。它们的定义都在messages.pas
单元中。

OK. 到这一步,我们只需要到messages.pas中去查找TWMKeyDown类型的定义就好了。它是这样的:
; TWMKeyDown = TWMKey;
哈哈~~~~~这不就找到了吗?

------------
不过,用grep这个程序在源程序中找东东,已经是我一年前用的办法了。哈哈,至于现在,
AM-CodeSearch一直是我手边的必备工具。:)
你在这儿可以下载到这个工具:
; ; ; http://download1.24suns.com/down/mrcodesearch.zip
CodeSearch只是帮助你找到一个关键字在源代码中的位置,至于分析,还是上面的这种思想。

^-^,没想到我省了一步,却弄得你现在还是不明白。哈哈。
 
哇,都是高手,佩服
 
哇!高手呀!你出过书了吗?我一定卖!
小第经过你这么多次的指导,知道了一点点。如有错误,请指正一下!
1,有的windwos中的消息参数,跟delphi定义的不是一样的。如windows中的WM_KEYDOWN在
delphi中就不是WM_KEYDOWN这样子了。在delphi的帮助中查不到WM_KEYDOWN这个词。
2,当delphi中查不到时,可以在windows sdk中查,这个WM_KEYDOWN就可以在这里差到,但是
它不是针对delphi的,所以很有可能你要的信息还是在那里查不到。就不如上面的EvnMsg.paramL=20520
这个“20520"数。
3,如果这些消息方面的定义,参数还查不到。因为delphi的消息参数都定义在messages.pas中
所以可以通过查看messages.pas中的delphi定义的消息参数,来查找,例如WM_KEYDOWN就可以在这里查到
,但是就只有WM_KEYDOWN = $0100;好象没什么用。
4,通过aimingoo大侠的介绍,用那个代码搜索器。
(上面的连接下不来,在这里也有。http://www.newhua.com/MrCodeSearch.htm,还是汉化版的:))
delphi的源代码都在source目录下,所以在source目录下查WM_KEYDOWN,应该选中那个查子目录的选项。
查到一大堆*.pas文件,点击每一个文件,列表框中就会出现高亮的WM_KEYDOWN关键字。
WM_KEYDOWN在好多个pas文件中多有定义,但都是一样的定义。(不会出现不一样的定义吧?
那可完了,我又不会了)下面是定义:
procedure WMKeyDown(var Message: ;TWMKeyDown); message WM_KEYDOWN;
就象aimingoo大侠说的:
这表明在这个单元的中,一个过程响应了WM_KEYDOWN消息,消息入口采
用TWMKeyDown消息类型。
既然消息类型已经找到,delphi的消息类型又全定义在messages.pas中,所以到messages.pas
中查找TWMKeyDown这个消息类型,其中的定义是这样的:TWMKeyDown = TWMKey;可见TWMKeyDown
是通过TWMKey来赋值的。再在messages.pas中查看TWMKEY,得到其结构如下:
;TWMKey = packed record
; ; Msg: Cardinal;
; ; CharCode: Word;
; ; Unused: Word;
; ; KeyData: Longint;
; ; Result: Longint;
; end;
就象aimingoo大侠说的delphi中的消息被描述成Tmessage结构,下面是Tmessage的结构。
TMessage = packed record
; ; Msg: Cardinal;
; ; case Integer of
; ; ; 0: (
; ; ; ; WParam: Longint;
; ; ; ; LParam: Longint;
; ; ; ; Result: Longint);
; ; ; 1: (
; ; ; ; WParamLo: Word;
; ; ; ; WParamHi: Word;
; ; ; ; LParamLo: Word;
; ; ; ; LParamHi: Word;
; ; ; ; ResultLo: Word;
; ; ; ; ResultHi: Word);
; end;
跟那个TWMKey对照起来。可知这里的LparamLo,LparamHi就是那个TWMkey的 KeyData值。
在delphi帮助中查看TWMkey,得到那个keydata的说明如下:
The KeyData field indicates the repeat count, scan code, extended-key flag
,context code, and so on. See the Windows help system for a keystroke message
such as WM_KEYDOWN for details on the possible values.
大意说这个KeyData 需要repeat count,scan code,extended-key flag等这些值,最后还提到
要得到具体的细节内容查看windows 的keystroke message 消息。所以接着就要查那个
keystroke message消息以得到具体的东西。
先查delphi的帮助,没有结果。再查windows sdk,看那个keystroke message事件,果然提到
了WM_keydown事件。但是还没有具体的值,查keystroke message相关的东东,果然,
在sdk中有个keystroke message Flags就是它了。里面详细的介绍了lParam 的取值。
果然这个参数是各个参数拼凑起来的。所以找规律也就难了。那个表介绍的lparam好象有32位
,但这里只有5位,还有4位的,我想是因为其中好多对于WM_KEYDOWN事件来说都可以是0,所以
可以省略掉0吧?
这样那个lparam的参数查找过程也就可以结束了吧。真是一个复杂的过程。我应该多练,才
能真正掌握喔。
再次感谢aimingoo大侠的诲人不倦!谢谢了!
 

Similar threads

后退
顶部