为什么这段代码运行出错,高手请进,问题描述内详!(100分)

  • 主题发起人 主题发起人 cqwty
  • 开始时间 开始时间
C

cqwty

Unregistered / Unconfirmed
GUEST, unregistred user!
我写的一个钩子程序,准备拦截指定的窗体的WM_Enable消息,关键代码如下:<br>钩子部分代码(从论坛上copy的),所以连名字都还没有修改。<br>library MouseHook;<br>uses<br> &nbsp;MouseIdle in 'MouseIdle.pas';<br>Exports<br> &nbsp;CreateHook,<br> &nbsp;RemoveHook;<br>{$R *.res}<br>begin<br> &nbsp;whHelp := 0;<br> &nbsp;procSaveExit := ExitProc;<br> &nbsp;ExitProc := @HelpHookExit;<br>end.<br>MouseIdle.pas代码:<br>unit MouseIdle;<br>interface<br>uses<br> &nbsp;Windows, Messages, SysUtils;<br>var<br> &nbsp;whHelp: HHook;<br> &nbsp;procSaveExit: Pointer;<br> &nbsp;function CreateHook(HookHandle:LongWORD): Boolean; export;<br> &nbsp;function RemoveHook: Boolean; export;<br> &nbsp;procedure HelpHookExit; far;<br> &nbsp;function HelpProc(iCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; export;<br>implementation<br>function CreateHook(HookHandle:LongWORD): Boolean;<br>//HookHandle主要是指定要拦截的窗体句柄<br>var<br> &nbsp;ThreadID:LongWord;//获得拥有该窗体的线程句柄<br>begin<br> &nbsp;Result := false;<br> &nbsp;if whHelp &lt;&gt; 0 then Exit;<br> &nbsp;ThreadID := GetWindowThreadProcessId(HookHandle, nil);<br> &nbsp;whHelp := SetWindowsHookEx(WH_CALLWNDPROC, @HelpProc, Hinstance, ThreadID);<br> &nbsp;Result := whHelp &lt;&gt; 0;<br>end;<br><br>function RemoveHook: Boolean;<br>begin<br> &nbsp;if whHelp &lt;&gt; 0 then<br> &nbsp;begin<br> &nbsp; &nbsp;UnHookWindowsHookEx(whHelp);<br> &nbsp; &nbsp;whHelp := 0;<br> &nbsp;end;<br> &nbsp;Result := whHelp = 0;<br>end;<br><br>procedure HelpHookExit;<br>begin<br> &nbsp;if whHelp &lt;&gt; 0 then<br> &nbsp; &nbsp;RemoveHook;<br> &nbsp;Exitproc := procSaveExit;<br>end;<br><br>function HelpProc(iCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; export;<br>var<br> &nbsp;HandleStr : string;<br>begin<br> &nbsp;Result := 0;<br> &nbsp;if iCode &lt; 0 then Result := CallNextHookEx(whHelp, iCode, wParam, lParam);<br> &nbsp; &nbsp;if pcwpstruct(lParam)^.message = WM_enable then<br>//如果拦截到的消息是WM_Enable,那么做如下的处理<br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;HandleStr := inttostr(pcwpstruct(lparam)^.hwnd);<br> &nbsp; &nbsp; &nbsp; &nbsp;Messagebox(0, Pchar('click on:'+HandleStr), 'Hook', 0+64);<br> &nbsp; &nbsp;end;<br>end;<br>end.<br>调用dll的project的代码:<br>procedure TSpyWindowForm.Button1Click(Sender: TObject);<br>begin<br> &nbsp; &nbsp;CreateHook(13894624);//对指定的窗体安装钩子<br>end;<br><br>procedure TSpyWindowForm.Button2Click(Sender: TObject);<br>begin<br> &nbsp; &nbsp;RemoveHook;//卸载钩子<br>end;<br>劳烦高手帮我看看怎么回事,总是在启动钩子的时候拦截到程序本身的窗口的消息,以及application的消息,而且还有出错的地方,郁闷了。
 
顺便再说,如果我不指定窗体,将这一句<br>SetWindowsHookEx(WH_CALLWNDPROC, @HelpProc, Hinstance, ThreadID);<br>改成<br>SetWindowsHookEx(WH_CALLWNDPROC, @HelpProc, Hinstance, 0);<br>也就是成为一个全局的钩子,那么不会出错,而且拦截到的消息也不是自己的。但是系统变慢了,因为处理的消息都多了,而且这个位置的拦截是在消息达到相应的应用程序之前获得的。所以为了不影响系统,打算针对指定的窗体进行拦截。<br>望高手指点一二,小弟不胜感激!
 
SetWindowsHookEx(WH_CALLWNDPROC, @HelpProc, Hinstance, ThreadID);<br>WH_CALLWNDPROC 换这个钩子 WH_CALLWNDPROCRET 试试
 
我试了一下,没问题。<br><br>不知楼主锁的问题详细的描述是什么?
 
另外,你的hook在dll文件中SetWindowsHookEx(WH_CALLWNDPROC, @HelpProc, Hinstance, 0); 就是对全局的,对所有程序都影响,若在你自己程序中则只影响你自己程序.<br>和ThreadID是否为0无关.指定它表示和这个线程相关.为0则和现存的所有线程相关.<br>而GetWindowThreadProcessId(HookHandle, nil);得到的是创建指定窗口的线程标识.<br>你换成GetCurrentThreadld试试. 我对这一块也不熟,以前玩游戏时写过一些简单挂机的程序.说错了别见笑
 
to xiammy:<br>我遇到的问题就是运行的时候,一安装钩子,就会钩到自己窗体和自己的应用程序,然后就有一个错误,接下来才会钩到指定的窗口的消息。
 
当直接运行这个拦截程序的时候,这里就是指定的窗口句柄随便,然后就先跳出两个对话框,一个显示的是本窗体句柄的,一个显示的是本应用程序id的,然后点确定后,出现错误对话框:<br>access violation at address 0003064e.read of address 0003064e.
 
你在调试状态下进入dll的第一局,按 ctrl+alt+c,在代码上右键选goto address,输入$3064e回车,然后就可以知道你那句代码出错了
 
调试状态是按f7还是f8?嘿嘿,谢谢哦!
 
f7就可以了,但必须运行到你的dll的领域.
 
按f7进不去啊,老白,你有qq嘛?qq交流,我的185973142
 
在公司开不了q,你的dll是怎么设置调试的?<br>算了,你在这里加上 <br>begin<br> &nbsp;asm<br> &nbsp; &nbsp;int 3<br> &nbsp;end;<br> &nbsp;whHelp := 0;<br> &nbsp;procSaveExit := ExitProc;<br> &nbsp;ExitProc := @HelpHookExit;<br>end.<br><br>然后按f9运行,程序会自动断在你的dll领域,再按我刚才说的方法去看代码.
 
谢谢,马上测试,有问题继续请教!
 
有了结果就提前吧,要出去一会
 
还是不行,使用上面的汇编代码后,程序根本没有办法运行了!望老白继续指点指点!
 
我找到了出错的那个地址,可是看不出什么东西来。唉,底子太差了,望高手指点,谢谢!
 
多人接受答案了。
 
后退
顶部