200分 真的不想麻烦大家,其实就是为了getmsgproc ,我到处找资料,大多是C的,我东转西拼的,结果可以用但却没效果。(200分)

  • 主题发起人 主题发起人 telliu
  • 开始时间 开始时间
T

telliu

Unregistered / Unconfirmed
GUEST, unregistred user!
本来是想做一个全局的钩子检测close这个消息的。下面是我的程序,我东拼西拼的,就是变量都搞乱了<br>,麻烦大家帮帮我<br>unit liu;<br><br>interface<br>uses<br>Windows,Messages,Dialogs; <br>var <br>&nbsp; hHk: HHOOK;<br>&nbsp; <br>&nbsp; function GetMsgProc(nCode: Integer;WParam: WPARAM;LParam: LPARAM):LRESULT;stdcall;<br>&nbsp; function Enablegetmsgproc:Boolean; stdcall; export;<br>&nbsp; function Disablegetmsgproc:Boolean; stdcall; export;<br><br>implementation<br>function GetMsgProc(nCode: Integer;WParam: WPARAM;LParam: LPARAM):LRESULT;stdcall;<br><br>begin<br>Result := 0;<br>&nbsp; if Lparam = WM_CLOSE then<br>showmessage('要关闭了') //在这里,如果自己弹出来的这个窗口又关闭,就是永远不会结束了,是吗?其实我只是想知道我收到了消息没有,先不管它。<br>else &nbsp;<br>&nbsp;CallNextHookEx(hhk, nCode, wParam, lParam );<br>end;<br><br>function Enablegetmsgproc:Boolean; stdcall; export;<br>begin<br>&nbsp; if hHk = 0 then //为了安全,必须判断一下再设置钩子。<br>&nbsp; begin<br><br>&nbsp; &nbsp; hHk := SetWindowsHookEx(WH_GETMESSAGE,@GetMsgProc,hInstance,0);<br>&nbsp; &nbsp; Result := True;<br>&nbsp; end <br>&nbsp; else <br>&nbsp; &nbsp; Result := False; <br>end;<br><br>function Disablegetmsgproc:Boolean; stdcall; export;<br>begin <br>&nbsp; if hHk &lt;&gt; 0 then //如果有钩子就卸掉他。 <br>&nbsp; begin <br>&nbsp; &nbsp; UnHookWindowsHookEx(hHk); <br>&nbsp; &nbsp; hHk := 0; <br>&nbsp; &nbsp; Result := True; <br>&nbsp; end <br>&nbsp; else <br>&nbsp; &nbsp; Result := False; <br>end;<br><br>end.
 
var<br>&nbsp; MsgStruct: ^CWPSTRUCT;//再增加个变量<br><br>function GetMsgProc(nCode: Integer;WParam: WPARAM;LParam: LPARAM):LRESULT;stdcall;<br>begin<br>&nbsp; if nCode &gt;= 0 then begin<br>&nbsp; &nbsp; MsgStruct := pointer(lParam);<br>&nbsp; &nbsp; case MsgStruct^.message of &nbsp;<br>&nbsp; &nbsp; &nbsp; wm_close:begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;showmessage('关闭了'); //在这里做相应的操作 &nbsp; &nbsp;<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; end;<br>&nbsp; end;<br>&nbsp; Result := CallNextHookEx(hhk, nCode, wParam, lParam );<br>end;<br><br>好了,你试试看吧!
 
to:quejian <br>&nbsp; &nbsp;好惨啊。。运行后<br>我电脑死--》我就反它重起了5次 &nbsp;发现下面特征..(非典,,:( )<br>我的程序放在E:/get目录下。<br>按照你的指点,我改了,把dll又放回到system里去了。<br>我从文件夹下面双击调用钩子的程序,运行<br>&nbsp;if Enablegetmsgproc then<br>&nbsp; &nbsp;ShowMessage('启动钩子成功'); &nbsp;这段代码(难道这句会是错的)<br>这时我关闭任何窗口都没反应。(不会弹出窗口,说明没收到!)<br>除了E:/get这个文件夹窗口----------&gt;这个窗口一关就会非法操作,然后就死机<br>再提一句,我在win98.....<br>是哪里出错昵。。。<br>我不清楚我是否还要提示些什么,,请富翁们指点<br>
 
case MsgStruct^.message of &nbsp;<br>&nbsp; &nbsp; &nbsp;wm_close:begin<br>&nbsp; &nbsp; &nbsp; &nbsp; showmessage('关闭了'); &nbsp; <br>&nbsp; &nbsp; &nbsp;end;<br><br>错误在showmessage('关闭了'); <br>不要在hook里用showmessage,否则很惨<br>你可以使用sendmessage发消息<br><br>看看下面的代码:<br><br>function GetMsgProc(nCode: integer; wParam, lParam: longint): LRESULT;<br>&nbsp; stdcall;<br>var<br>&nbsp; pInfo: TMsg;<br>begin<br>&nbsp; if nCode &lt; 0 then<br>&nbsp; begin<br>&nbsp; &nbsp; Result := CallNextHookEx(hhk, nCode, wParam, lParam);<br>&nbsp; &nbsp; exit;<br>&nbsp; end;<br><br>&nbsp; if (nCode = HC_ACTION) and (wParam = PM_REMOVE) then<br>&nbsp; &nbsp;begin<br>&nbsp; &nbsp; pInfo := TMsg(PMsg(lparam)^);<br>&nbsp; &nbsp; &nbsp; if pInfo.message = WM_CLOSE then<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; //做你想做的,不过一般是使用sendmessage来发送消息的<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; end;<br>&nbsp; Result := CallNextHookEx(hhk, nCode, wParam, lParam);<br>end;
 
to:<br>我试过了,还是非法操作内容如下:<br>EXPLORER 在 0167:bff9dfc5 的模块<br>&nbsp;KERNEL32.DLL 中导致无效页错误。<br>Registers:<br>EAX=c00309f4 CS=0167 EIP=bff9dfc5 EFLGS=00010216<br>EBX=0124f9ac SS=016f ESP=0120fe5c EBP=012100f8<br>ECX=00000000 DS=016f ESI=817ac4e0 FS=5e47<br>EDX=bff768d5 ES=016f EDI=012101d0 GS=0000<br>Bytes at CS:EIP:<br>53 8b 15 e4 ad fc bf 56 89 4d e4 57 89 4d dc 89 <br>Stack dump:<br>
 
原码改成如下:<br>unit liu;<br><br>interface<br>uses<br>Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,<br>&nbsp; Dialogs, StdCtrls;<br>var <br>&nbsp; hHk: HHOOK;<br>&nbsp; MsgStruct: ^CWPSTRUCT;//再增加个变量<br>&nbsp; function GetMsgProc(nCode: Integer;WParam: WPARAM;LParam: LPARAM):LRESULT;stdcall;<br>&nbsp; function Enablegetmsgproc:Boolean; stdcall; export;<br>&nbsp; function Disablegetmsgproc:Boolean; stdcall; export;<br><br>implementation<br>function GetMsgProc(nCode: Integer;WParam: WPARAM;LParam: LPARAM):LRESULT;stdcall;<br><br>begin<br>Result := 0;<br>&nbsp;if nCode &gt;= 0 then begin<br>&nbsp; &nbsp;MsgStruct := pointer(lParam);<br>&nbsp; &nbsp;case MsgStruct^.message of &nbsp;<br>&nbsp; &nbsp; &nbsp;wm_close:begin<br>&nbsp; &nbsp; &nbsp; &nbsp; //showmessage('关闭了'); //在这里做相应的操作<br>&nbsp; &nbsp; &nbsp; &nbsp;SendMessage(Application.Handle, WM_SYSCOMMAND, SC_MONITORPOWER, 0);//我在调用钩子的地方,把SetFocus传给了下一个解黑屏的,只要回车就能解了。<br>&nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp;end;<br>&nbsp;end;<br>&nbsp;Result := CallNextHookEx(hhk, nCode, wParam, lParam );<br><br>end;<br><br>function Enablegetmsgproc:Boolean; stdcall; export;<br>begin<br>&nbsp; if hHk = 0 then //为了安全,必须判断一下再设置钩子。<br>&nbsp; begin<br><br>&nbsp; &nbsp; hHk := SetWindowsHookEx(WH_GETMESSAGE,@GetMsgProc,hInstance,0);<br>&nbsp; &nbsp; Result := True;<br>&nbsp; end <br>&nbsp; else <br>&nbsp; &nbsp; Result := False; <br>end;<br><br>function Disablegetmsgproc:Boolean; stdcall; export;<br>begin <br>&nbsp; if hHk &lt;&gt; 0 then //如果有钩子就卸掉他。 <br>&nbsp; begin <br>&nbsp; &nbsp; UnHookWindowsHookEx(hHk); <br>&nbsp; &nbsp; hHk := 0; <br>&nbsp; &nbsp; Result := True; <br>&nbsp; end <br>&nbsp; else <br>&nbsp; &nbsp; Result := False; <br>end;<br><br>end.
 
什么啊:<br>SendMessage(Application.Handle, WM_SYSCOMMAND, SC_MONITORPOWER, 0);<br>怎么能这样用<br><br>看看这个:<br>http://www.delphibbs.com/delphibbs/dispq.asp?lid=1893890
 
好的,马上去看,就是不能解决问题也散分,感谢你们的回答
 
系统核心方面的没看过书。看了你的讲解,头晕中。<br>你能否直接说出我的错误在哪,你的讲解,我要慢慢看 :(<br>拜托你了
 
to:wbtvc<br>老大不是哪个的错。<br>我试过就是得到关闭消息什么事也不做。也照样出错。
 
function GetMsgProc(nCode: Integer;WParam: WPARAM;LParam: LPARAM):LRESULT;stdcall;<br>里的代码改成我上面我写的看看
 
对啊,,我copy过去的,一个标点都没错<br>unit liu;<br><br>interface<br>uses<br>Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,<br>&nbsp; Dialogs, StdCtrls;<br>var<br>&nbsp; hHk: HHOOK;<br>&nbsp; MsgStruct: ^CWPSTRUCT;//再增加个变量<br>&nbsp; function GetMsgProc(nCode: Integer;WParam: WPARAM;LParam: LPARAM):LRESULT;stdcall;<br>&nbsp; function Enablegetmsgproc:Boolean; stdcall; export;<br>&nbsp; function Disablegetmsgproc:Boolean; stdcall; export;<br><br>implementation<br><br>function GetMsgProc(nCode: integer; wParam, lParam: longint): LRESULT;<br>&nbsp;stdcall;<br>var<br>&nbsp;pInfo: TMsg;<br>begin<br>&nbsp;if nCode &lt; 0 then<br>&nbsp;begin<br>&nbsp; &nbsp;Result := CallNextHookEx(hhk, nCode, wParam, lParam);<br>&nbsp; &nbsp;exit;<br>&nbsp;end;<br><br>&nbsp;if (nCode = HC_ACTION) and (wParam = PM_REMOVE) then<br>&nbsp; begin<br>&nbsp; &nbsp;pInfo := TMsg(PMsg(lparam)^);<br>&nbsp; &nbsp; &nbsp;if pInfo.message = WM_CLOSE then<br>&nbsp; &nbsp; &nbsp;begin<br>&nbsp; &nbsp; &nbsp; &nbsp;//做你想做的,不过一般是使用sendmessage来发送消息的<br>&nbsp; &nbsp; &nbsp;end;<br>&nbsp; &nbsp;end;<br>&nbsp;Result := CallNextHookEx(hhk, nCode, wParam, lParam);<br>end;<br><br><br>function Enablegetmsgproc:Boolean; stdcall; export;<br>begin<br>&nbsp; if hHk = 0 then //为了安全,必须判断一下再设置钩子。<br>&nbsp; begin<br><br>&nbsp; &nbsp; hHk := SetWindowsHookEx(WH_GETMESSAGE,@GetMsgProc,hInstance,0);<br>&nbsp; &nbsp; Result := True;<br>&nbsp; end <br>&nbsp; else<br>&nbsp; &nbsp; Result := False; <br>end;<br><br>function Disablegetmsgproc:Boolean; stdcall; export;<br>begin<br>&nbsp; if hHk &lt;&gt; 0 then //如果有钩子就卸掉他。 <br>&nbsp; begin <br>&nbsp; &nbsp; UnHookWindowsHookEx(hHk); <br>&nbsp; &nbsp; hHk := 0; <br>&nbsp; &nbsp; Result := True;<br>&nbsp; end <br>&nbsp; else <br>&nbsp; &nbsp; Result := False; <br><br>&nbsp; &nbsp; end;<br><br>end.
 
不要显示窗口了,可以使用 windows.Beep(1000,500) 来听声音就可以了<br>(win9x不能听到你设置的1000hz500毫秒,只能听到普通的beep一声,nt/win2000/xp就可以)<br>CallNextHookEx应该这样:<br>if nCode&lt;0 then<br>&nbsp; result:=CallNextHookEx(hhk, nCode, wParam, lParam )<br>&nbsp;else<br>&nbsp; result:=0
 
DLL 代码:<br>library Mhook;<br><br>uses<br>Main in 'Main.pas',<br><br>windows,<br>messages,<br>Classes,<br>sysutils;<br><br>procedure DLLEntryPoint(dwReason: DWORD);<br>begin<br>case dwReason of<br>&nbsp; DLL_PROCESS_ATTACH: OpenShareData;<br>&nbsp; DLL_PROCESS_DETACH: CloseShareData;<br>end;<br>end;<br>exports<br>EnableHook,<br>DisableHook;<br>begin<br><br>procExit := ExitProc;<br>ExitProc := @HookExit;<br>DLLProc := @DLLEntryPoint;<br>DLLEntryPoint(DLL_PROCESS_ATTACH);<br>end.<br>=======================================================================<br><br>unit Main;<br><br>interface<br>uses<br>windows,<br>messages,<br>Classes,<br>sysutils;<br><br>type<br><br>PServerData = ^ServerData;<br>ServerData = record<br>&nbsp; Wnd: HWND;<br>&nbsp; UniqueMsgID: Cardinal;<br>&nbsp; hHk: HHOOK;<br>end;<br><br>var<br><br>procExit: pointer;<br>SData: PServerData;<br>MapServerHandle: THandle;<br>const<br><br>cMMServerData: PChar = 'ServerMapData';<br><br><br>function EnableHook(h: HWND): Boolean; stdcall;<br>function DisableHook(): Boolean; stdcall;<br><br>procedure HookExit; far;<br>procedure OpenShareData();<br>procedure CloseShareData();<br><br>function GetMsgProc(nCode: integer; wParam, lParam: longint): LRESULT; stdcall;<br><br>implementation<br><br>procedure OpenShareData();<br>var<br>Size: integer;<br>begin<br>Size := Sizeof(SData);<br>MapServerHandle := CreateFileMapping(DWORD(-1), nil, PAGE_READWRITE, 0, Size,<br>&nbsp; cMMServerData);<br>SData := MapViewOfFile(MapServerHandle, FILE_MAP_ALL_ACCESS, 0, 0, Size);<br>end;<br><br><br>procedure CloseShareData();<br>begin<br>UnmapViewOfFile(SData);<br>CloseHandle(MapServerHandle);<br>end;<br><br>function EnableHook(h: HWND): Boolean; stdcall;<br>begin<br>if SData.hHk &lt;&gt; 0 then<br>begin<br>&nbsp; Result := false;<br>&nbsp; exit;<br>end;<br>SData.Wnd := h;<br>SData.UniqueMsgID := RegisterWindowMessage('RWM1');<br><br>SData.hHk := SetWindowsHookEx(WH_GETMESSAGE, @GetMsgProc, hInstance, 0);<br><br>Result := SData.hHk &lt;&gt; 0;<br>end;<br><br>function DisableHook(): Boolean; stdcall;<br>begin<br>//注销挂钩<br>Result := false;<br>if UnhookWindowsHookEx(SData.hHk) then<br>begin<br>&nbsp; SData.hHk := 0;<br>&nbsp; Result := true;<br>end;<br>end;<br><br>procedure HookExit;<br>begin<br>if SData.hHk &lt;&gt; 0 then<br>&nbsp; DisableHook;<br>ExitProc := procExit;<br>end;<br><br><br>function GetMsgProc(nCode: integer; wParam, lParam: longint): LRESULT;<br>stdcall;<br>var<br>pInfo: TMsg;<br>begin<br>if nCode &lt; 0 then<br>begin<br>&nbsp; Result := CallNextHookEx(hhk, nCode, wParam, lParam);<br>&nbsp; exit;<br>end;<br><br>if (nCode = HC_ACTION) and (wParam = PM_REMOVE) then<br>&nbsp;begin<br>&nbsp; pInfo := TMsg(PMsg(lparam)^);<br>&nbsp; &nbsp; if pInfo.message = WM_CLOSE then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; //做你想做的,不过一般是使用sendmessage来发送消息的<br>&nbsp; &nbsp; &nbsp;SendMessage(SData.Wnd, SData.UniqueMsgID, 0, 0); &nbsp; <br>&nbsp; &nbsp; end;<br>&nbsp; end;<br>Result := CallNextHookEx(hhk, nCode, wParam, lParam);<br>end;<br><br>=======================================================================<br>主程序:<br><br>unit Unit1;<br><br>interface<br><br>uses<br>Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,<br>Dialogs, StdCtrls, ExtCtrls;<br><br>type<br>TForm1 = class(TForm)<br>&nbsp; Label1: TLabel;<br>&nbsp; Button1: TButton;<br>&nbsp; Edit1: TEdit;<br>&nbsp; procedure FormCreate(Sender: TObject);<br>&nbsp; procedure FormDestroy(Sender: TObject);<br>private<br>&nbsp; { Private declarations }<br>&nbsp; procedure WndProc(var Msg: TMessage); override;<br>public<br>&nbsp; { Public declarations }<br>end;<br><br>function EnableHook(h: HWND): Boolean; stdcall;<br>function DisableHook(): Boolean; stdcall;<br><br>var<br>Form1: TForm1;<br>UniqueMsgID: Cardinal;<br><br>implementation<br>function EnableHook; external 'MHook.dll' name 'EnableHook';<br>function DisableHook; external 'MHook.dll' name 'DisableHook';<br><br><br>{$R *.dfm}<br><br>procedure TForm1.WndProc(var Msg: TMessage);<br>var<br>ptMousePos: Tpoint;<br>begin<br>if Msg.msg = UniqueMsgID then<br>begin<br>&nbsp; GetCursorPos(ptMousePos);<br>&nbsp; label1.Caption := 'X:' + inttostr(ptMousePos.X) + ' &nbsp;Y:' + inttostr(ptMousePos.Y);<br>end;<br>inherited WndProc(Msg); ;<br>end;<br><br>procedure TForm1.FormCreate(Sender: TObject);<br>var<br>h: HWND;<br>begin<br>UniqueMsgID := RegisterWindowMessage('RWM1');<br>EnableHook(Handle);<br>end;<br><br>procedure TForm1.FormDestroy(Sender: TObject);<br>begin<br>DisableHook;<br>end;<br><br>end.<br>
 
谢谢各位。我先给分。不行再来。反正还有分。<br>
 
hHk 不能保存于一般的全局变量,应该放在共享的空间<br>见:http://www.delphibbs.com/delphibbs/dispq.asp?lid=635375
 

Similar threads

后退
顶部