关于键盘Hook的问题(100分)

  • 主题发起人 主题发起人 BlueFish
  • 开始时间 开始时间
B

BlueFish

Unregistered / Unconfirmed
GUEST, unregistred user!
&nbsp; 为什么我编的一个键盘监控的程序,键盘消息被Hook 截获后,不能传递给<br>Windows原来的处理过程,程序主要过程:<br>function KeyboardHook(iCode:integer;wParam:WPARAM;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lParam:LPARAM):LRESULT;stdcall;export;<br>const<br>&nbsp; _KeyPressMask = $80000000;<br>var<br>&nbsp; tmpReg:TRegistry;<br>&nbsp; RecordFile:TextFile;<br>begin<br>&nbsp; result:=0;<br>&nbsp; if iCode&lt;0 then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; CallNextHookEx(hNextHookProc,iCode,wParam,lParam);<br>&nbsp; &nbsp; &nbsp; exit;<br>&nbsp; &nbsp; end;<br>&nbsp; if ((lParam and _KeyPressMask) = 0) then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; AssignFile(RecordFile,FilePath);<br>&nbsp; &nbsp; &nbsp; Append(RecordFile);<br>&nbsp; &nbsp; &nbsp; write(RecordFile,char(wparam));<br>&nbsp; &nbsp; &nbsp; if GetKeyState(VK_RETURN)&lt;0 then<br>&nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; writeln(RecordFile);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; write(RecordFile,char(wparam));<br>&nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; Closefile(RecordFile);<br>&nbsp; &nbsp; end;<br>&nbsp; &nbsp; MessageDlg(inttostr(hNextHookProc),mtInformation,[mbok],0);<br>&nbsp; &nbsp; CallNextHookEx(hNextHookProc,iCode,wParam,lParam);<br>&nbsp; &nbsp; result:=1;<br>end;<br><br>&nbsp; 弹出的窗口显示hNextHookProc的值为0,而在该过程外值为一非零值<br>顺便问一下,如何使程序每1ms执行一个动作.
 
可是我用这段代码显示为非零值的,可能是过程外某个地方有调用有误<br><br>var<br>&nbsp; hNextHookProc: HHook;<br><br>function EnableHotKeyHook: BOOL; export;<br>begin<br>&nbsp; Result := False;<br>&nbsp; if hNextHookProc &lt;&gt; 0 then Exit;<br>&nbsp; hNextHookProc := SetWindowsHookEx(WH_KEYBOARD,KeyboardHookHandler,HInstance, 0);<br>&nbsp; Result := hNextHookProc &lt;&gt; 0;<br>end;<br><br>function DisableHotKeyHook: BOOL; export;<br>begin<br>&nbsp; if hNextHookProc &lt;&gt; 0 then<br>&nbsp; begin<br>&nbsp; &nbsp; UnhookWindowshookEx(hNextHookProc);<br>&nbsp; &nbsp; hNextHookProc := 0;<br>&nbsp; end;<br>&nbsp; Result := hNextHookProc = 0;<br>end;<br>再另上上面的,是这样的吗?<br>2. 可用Timer或WM_TIMER消息
 
&nbsp; 是啊,在这两个过程中,hNextHookProc显示的是非零值,但在主过程中<br>却为零,是不是和函数声明的类型有关?我再调试看看
 
你在DFW搜索以下Hook,解答一大堆。...... &nbsp; &nbsp; &nbsp; &nbsp; :(
 
我试用在主过程中为非零值呀,不知你的怎么会为零
 
&nbsp; &nbsp;Timer好像只能精确定时到55ms,如果要每隔1ms甚至1ms以下取一次<br>时间,如何实现?
 
&nbsp; &nbsp;怎么试都不行,能不能把你调用的函数及函数声明,贴出来看看?<br>
 
&nbsp; 修改了一下,把最后两句合并为<br>&nbsp;result:=CallNextHookEx(hNextHookProc,iCode,wParam,lParam);<br>虽然 hNextHookProc 仍然显示为零,但是可以传递给原来的处理过程.<br>不知道这是什么原因.
 
我用它测试,hNextHookProco为非零值的,不懂?<br>Timer能精确到1MS吧,我看过它的源代码,要非常精确不如用线程<br>implementation<br><br>{$R *.DFM}<br><br>var<br>&nbsp; hNextHookProc: HHook;<br><br>function KeyboardHook(iCode:integer;wParam:WPARAM;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lParam:LPARAM):LRESULT;stdcall;export;<br>const<br>&nbsp; _KeyPressMask = $80000000;<br>var<br>&nbsp; tmpReg:TRegistry;<br>&nbsp; RecordFile:TextFile;<br>begin<br>&nbsp; result:=0;<br>&nbsp; if iCode&lt;0 then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; CallNextHookEx(hNextHookProc,iCode,wParam,lParam);<br>&nbsp; &nbsp; &nbsp; exit;<br>&nbsp; &nbsp; end;<br>&nbsp; if ((lParam and _KeyPressMask) = 0) then<br>&nbsp; &nbsp; begin<br>&nbsp; // &nbsp; &nbsp;AssignFile(RecordFile,FilePath);<br>&nbsp; &nbsp;// &nbsp; Append(RecordFile);<br>&nbsp; &nbsp;// &nbsp; write(RecordFile,char(wparam));<br>&nbsp;// &nbsp; &nbsp; if GetKeyState(VK_RETURN)&lt;0 then<br>&nbsp;// &nbsp; &nbsp; &nbsp; begin<br>&nbsp;// &nbsp; &nbsp; &nbsp; &nbsp; writeln(RecordFile);<br>&nbsp; // &nbsp; &nbsp; &nbsp; &nbsp;write(RecordFile,char(wparam));<br>&nbsp; // &nbsp; &nbsp; &nbsp;end;<br>&nbsp; // &nbsp; &nbsp;Closefile(RecordFile);<br>&nbsp; ;<br>&nbsp; &nbsp; end;<br>&nbsp; &nbsp; MessageDlg(inttostr(hNextHookProc),mtInformation,[mbok],0);<br>&nbsp; &nbsp; CallNextHookEx(hNextHookProc,iCode,wParam,lParam);<br>&nbsp; &nbsp; result:=1;<br>end;<br><br>function EnableHotKeyHook: BOOL; export;<br>begin<br>&nbsp; Result := False;<br>&nbsp; if hNextHookProc &lt;&gt; 0 then Exit;<br>&nbsp; hNextHookProc := SetWindowsHookEx(WH_KEYBOARD,KeyboardHook,HInstance, 0);<br>&nbsp; Result := hNextHookProc &lt;&gt; 0;<br>end;<br><br>function DisableHotKeyHook: BOOL; export;<br>begin<br>&nbsp; if hNextHookProc &lt;&gt; 0 then<br>&nbsp; begin<br>&nbsp; &nbsp; UnhookWindowshookEx(hNextHookProc);<br>&nbsp; &nbsp; hNextHookProc := 0;<br>&nbsp; end;<br>&nbsp; Result := hNextHookProc = 0;<br>end;<br><br><br>procedure TForm1.Button1Click(Sender: TObject);<br>begin<br>&nbsp;EnableHotKeyHook;<br>end;<br><br>procedure TForm1.Button2Click(Sender: TObject);<br>begin<br>&nbsp;DisableHotKeyHook<br>end;
 
&nbsp; &nbsp; &nbsp;你是在一个Project里调用Hook的<br>&nbsp; &nbsp; &nbsp; 我是把那三个过程编成一个dll, 新建了一个Project来调用。<br><br>&nbsp; 另外,现编了一个程序,把 Timer 的 interval 设为 1,但是每秒钟大概<br>只能执行18次操作,线程好像也不行吧,有没有API可以实现呢?
 
当然是在DLL,我只是给你测试下,在DLL里同样为非零。<br>&gt;&gt;把 Timer 的 interval 设为 1,但是每秒钟大概只能执行18次操作,线程好像也不行吧<br>设为1时,每1MS都会响应的呀,大概是你的操作耗时的问题吧,我做了个实验:<br>将Timer.interval:=1;放上个ProgressBar.Max:=1000;<br>var<br>&nbsp;tm: SYSTEMTIME ;<br>&nbsp;i: integer=0;<br><br>procedure TForm1.Timer1Timer(Sender: TObject);<br>begin<br>&nbsp;GetSystemTime(tm);<br>&nbsp;ProgressBar1.Position:=tm.wMilliseconds;<br>&nbsp;edit1.text:=inttostr(tm.wMilliseconds);<br>end;<br>看看,每1MS当响应的。
 
多人接受答案了。
 
后退
顶部