这个全局mouse hook (鼠标钩子)为什么不能实现(100分)

  • 主题发起人 主题发起人 luckysun
  • 开始时间 开始时间
L

luckysun

Unregistered / Unconfirmed
GUEST, unregistred user!
也算是老问题,一个监测鼠标空闲时间的钩子程序,我已经做成DLL了,可是还是不能实现全局<br>请问是哪个地方不对?<br>全部代码下载:http://luckysun.y365.com/myhook.zip<br>我从没有编过程序,这个是按照一个VCL修改的,麻烦各位了!<br><br>dll部分代码<br>library MouseHook;<br><br>uses<br>&nbsp; MouseIdle in 'MouseIdle.pas';<br><br>exports<br>&nbsp; LastActivity, IdleTime, IdleMinutes, CreateHooks, RemoveHooks;<br><br>begin<br>&nbsp; WhMouse := 0;<br>&nbsp; procSaveExit := ExitProc;<br>&nbsp; ExitProc := @MouseHookExit;<br>end.<br><br>***********************************<br>unit MouseIdle;<br><br>interface<br><br>uses<br>&nbsp; Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls;<br><br>var<br>&nbsp; GLastActivity: TDateTime;<br>&nbsp; whMouse: HHook;<br>&nbsp; procSaveExit: Pointer;<br><br>procedure CreateHooks; export;<br>procedure RemoveHooks; export;<br>procedure SetLastActivity(const t: TDateTime);<br>procedure MouseHookExit; far;<br><br>function LastActivity: TDateTime; export; //最后停止移动的时刻<br>function IdleTime: TDateTime; export; &nbsp; &nbsp; //空闲的时间<br>function IdleMinutes: Integer; export; &nbsp; &nbsp;//空闲的分钟数<br><br>implementation<br><br>function MouseHookCallBack(Code: integer; Msg: WPARAM;<br>&nbsp; MouseHook: LPARAM): LRESULT; stdcall; export;<br><br>begin<br>// &nbsp;Result := 0;<br>&nbsp; if Code &gt;= 0 then<br>&nbsp; &nbsp; GLastActivity := Now;<br>&nbsp; Result := CallNextHookEx(whMouse, Code, Msg, MouseHook);<br>end;<br><br><br>function HookActive: Boolean;<br>begin<br>&nbsp; Result := whMouse &lt;&gt; 0;<br>end;<br><br>procedure CreateHooks; export;<br>begin<br>&nbsp; if not HookActive then<br>&nbsp; begin<br>&nbsp; &nbsp; whMouse := SetWindowsHookEx(WH_MOUSE, MouseHookCallBack, HInstance, 0);<br>&nbsp; &nbsp; GLastActivity := now;<br>&nbsp; end;<br>end;<br><br>procedure RemoveHooks; export;<br>begin<br>&nbsp; if HookActive then<br>&nbsp; try<br>&nbsp; &nbsp; UnhookWindowsHookEx(whMouse);<br>&nbsp; finally<br>&nbsp; &nbsp; whMouse := 0;<br>&nbsp; end;<br>end;<br><br><br>function LastActivity: TDateTime; export;<br>begin<br>&nbsp; Result := GLastActivity;<br>end;<br><br>procedure SetLastActivity(const t: TDateTime);<br>begin<br>&nbsp; GLastActivity := t;<br>end;<br><br>function IdleTime: TDateTime; export;<br>begin<br>&nbsp; Result := Now - GLastActivity;<br>end;<br><br>function IdleMinutes: Integer; export;<br>begin<br>&nbsp; Result := Trunc(IdleTime * 1440.1);<br>end;<br><br>procedure MouseHookExit;<br>begin<br>&nbsp; // 如果忘了解除 HOOK, 自动代理解除的动作<br>&nbsp; if WhMouse &lt;&gt; 0 then RemoveHooks;<br>&nbsp; ExitProc := procSaveExit;<br>end;<br>end.<br>
 
94. 利用HOOK建立鼠标增强程序<br>在Windows系统中提供了一种系统消息挂钩的(Message hook)功能,使用消息挂钩,可以实时监视处理系统中的各种消息。很多鼠标增强软件就是利用消息挂钩来拦截所有的鼠标消息进行处理的。<br>要设置鼠标消息挂钩,一般先建立一个使用鼠标消息挂钩的动态连接库(DLL)文件,然后就可以在其它程序中使用这个DLL文件处理鼠标消息。<br>下面的程序介绍通过鼠标消息挂钩监视鼠标消息,从而实现类似于一些鼠标增强软件一样的使窗口上下左右滚动的功能。<br>1.建立动态连接库<br>选择菜单 File|New ,选择DLL产生一个DLL模版,保存为 MHook.Dpr<br>//MHook.Dpr源程序<br>library MHook;<br>uses SysUtils,Classes,hkproc in 'hkproc.pas';<br>exports<br>EnableMouseHook,<br>DisableMouseHook;<br>begin<br>hNextHookProc:=0;<br>procSaveExit:=ExitProc;<br>ExitProc:=@HotKeyHookExit;<br>end.<br><br>再选择菜单 File|New ,选择Unit建立一个Pas文件,保存为 HKProc.pas<br>//HKProc.pas源程序<br>unit hkproc;<br>interface<br>uses Windows,Messages;<br>const<br>Move_Up = 0;<br>Move_Down=1;<br>Move_Left=2;<br>Move_Right=3;<br>var<br>hNextHookProc:HHook;<br>procSaveExit:Pointer;<br>M_Direct:Integer;<br>LPoint:TPoint;<br>NowWindow:Integer;<br><br>function MouseProc(iCode:Integer;wParam:WPARAM;lParam:Pointer):<br>LRESULT; stdcall;export;<br>function EnableMouseHook(WndHandle:integer):BOOL;export;<br>function DisableMouseHook:BOOL;export;<br>function GetDirect(FPoint : TPoint;LPoint : TPoint):integer;<br>procedure HotKeyHookExit;far;<br>implementation<br>//GetDirect函数根据光标的移动决定窗口滚动的方向。<br>function GetDirect(FPoint : TPoint;LPoint : TPoint):integer;<br>var<br>iWidth,iHeight:integer;<br>begin<br>iWidth:=LPoint.x-FPoint.x;<br>iHeight:=lPoint.y-FPoint.y;<br>Result:=-1;<br>if ((iWidth=0)or(iHeight=0))then exit;<br>if ((abs(iWidth) div abs(iHeight))&gt;=2) then<br>if iWidth&lt;0 then //Move to left<br>Result:=Move_Left<br>else<br>Result:=Move_Right<br>else if ((abs(iHeight) div abs(iWidth))&gt;=2) then<br>if iHeight&lt;0 then //Move to top<br>Result:=Move_Up<br>else<br>Result:=Move_Down;<br>end;<br><br>function MouseProc(iCode:Integer;wParam:WPARAM;<br>lParam:Pointer):LRESULT; stdcall;export;<br>var<br>pMouse:^MOUSEHOOKSTRUCT;<br>l:integer;<br>begin<br>//如果用户按下鼠标右键同时Scroll Lock键为按下状态则滚动窗口。<br>if ((wParam=WM_RBUTTONDOWN) and Boolean(GetKeyState(145))) then<br>begin<br>pMouse:=lParam;<br>l:=GetDirect(lPoint,pMouse.pt);<br>if l&gt;=0 then M_Direct:=l;<br>lPoint:=pMouse.pt;<br><br>NowWindow:=WindowFromPoint(lPoint);<br>if M_Direct=Move_Up then<br>SendMessage(NowWindow,WM_VSCROLL,SB_PAGEUP,0)<br>else if M_Direct=Move_Down then<br><br>SendMessage(NowWindow,WM_VSCROLL,SB_PAGEDOWN,0)<br>else if M_Direct=Move_Left then<br>SendMessage(NowWindow,WM_HSCROLL,SB_PAGELEFT,0)<br>else if M_Direct=Move_Right then<br>SendMessage(NowWindow,WM_HSCROLL,SB_PAGERIGHT,0);<br>Result:=1;<br>exit;<br>end<br>else if ((wParam=WM_RBUTTONUP) and Boolean(GetKeyState(145))) then<br>Result:=1<br>else<br>begin<br>Result:=0;<br>if iCode&lt;0 then<br>begin<br>Result:=CallNextHookEx(hNextHookProc,iCode,wParam,integer(lParam));<br>Exit;<br>end;<br>end;<br>end;<br>function EnableMouseHook(WndHandle:integer):BOOL;export;<br>begin<br>GetCursorPos(lPoint);<br>Result:=False;<br>if hNextHookProc&lt;&gt;0 then exit;<br>//设置Mouse hook<br>hNextHookProc:=SetWindowsHookEx(WH_MOUSE,@MouseProc,Hinstance,0);<br>Result:=hNextHookProc&lt;&gt;0;<br>end;<br>function DisableMouseHook:BOOL;export;<br>begin<br>if hNextHookProc&lt;&gt;0 then<br>begin<br>UnHookWindowsHookEx(hNextHookProc);<br>hNextHookProc:=0;<br>end;<br>Result:=hNextHookProc=0;<br>end;<br>procedure HotKeyHookExit;<br>begin<br>if hNextHookProc&lt;&gt;0 then<br>DisableMouseHook;<br>ExitProc:=procSaveExit;<br>end;<br>end.<br>在菜单中选择 Project|Build MHook建立DLL文件。<br>2.建立程序调用动态连接库<br>在这里我们还是使用Delphi建立程序,当然也可以使用诸如VB等调用动态连接库。在菜单中选 File|New Application建立一个新程序,将工程文件保存为Project1.dpr<br>//project1的源程序<br>program Project1;<br>uses Forms, Sample1 in 'Sample1.pas' {Form1};<br>{$R *.RES}<br>begin<br>Application.Initialize;<br>//隐藏窗口<br>Application.ShowMainForm := False;<br>Application.CreateForm(TForm1, Form1);<br>Application.Run;<br>end. <br>将Form1的源程序文件保存成Sample1.pas<br>//Form1的源程序<br>unit Sample1;<br>interface<br>uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,<br>StdCtrls, Menus, ImgList,ShellApi, ExtCtrls;<br>const<br>WM_ICONMESSAGE=WM_USER+$100;<br>type<br>TForm1 = class(TForm)<br>procedure FormClose(Sender: TObject; var Action: TCloseAction);<br>procedure FormCreate(Sender: TObject);<br>private<br>procedure WMBarIcon(var Message:TMessage);message WM_ICONMESSAGE;<br>public<br>end;<br>function EnableMouseHook(WndHandle:integer):BOOL;external 'MHook.DLL';<br>function DisableMouseHook:BOOL;external'MHook.DLL';<br>var<br>Form1: TForm1;<br>implementation<br>{$R *.DFM}<br>procedure TForm1.WMBarIcon (var Message:TMessage);<br>begin<br>//用户双击任务栏图标则关闭程序 <br>if Message.LParam = WM_LBUTTONDBLCLK then close;<br>end;<br>procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);<br>var<br>lpData:PNotifyIconData;<br>begin<br>//删除任务栏图标<br>lpData := new(PNotifyIconDataA);<br>lpData.cbSize := 88;//SizeOf(PNotifyIconDataA);<br>lpData.Wnd := Form1.Handle;<br>lpData.hIcon := Form1.Icon.Handle;<br>lpData.uCallbackMessage := WM_ICONMESSAGE;<br>lpData.uID :=0;<br>lpData.szTip := '鼠标演示';<br>lpData.uFlags := NIF_ICON or NIF_MESSAGE or NIF_TIP;<br>Shell_NotifyIcon(NIM_DELETE,lpData);<br>dispose(lpData);<br>//解除Mouse hook<br>DisableMouseHook;<br>end;<br>procedure TForm1.FormCreate(Sender: TObject);<br>var<br>lpData:PNotifyIconData;<br>begin<br>EnableMouseHook(Form1.Handle);<br>Form1.Visible := False;<br>lpData := new(PNotifyIconDataA);<br>lpData.cbSize := 88;//SizeOf(PNotifyIconDataA);<br>lpData.Wnd := Form1.Handle;<br>lpData.hIcon := Form1.Icon.Handle;<br>lpData.uCallbackMessage := WM_ICONMESSAGE;<br>lpData.uID :=0;<br>lpData.szTip := '鼠标演示';<br>lpData.uFlags := NIF_ICON or NIF_MESSAGE or NIF_TIP;<br>Shell_NotifyIcon(NIM_ADD,lpData);<br>dispose(lpData);<br>end;<br>end.<br>运行程序,按下Scroll Lock键使其有效,将光标移动到文本窗口中(如IE、Word),移动鼠标,点击鼠标右键,窗口就可以依上一次移动的方向滚动。<br>利用上面的原理,将程序做一些改动,就可以象专业的鼠标增强程序一样做出例如缩放窗口,运行程序等很多鼠标增强效果来。上面的程序在Windows95,Delphi4.0下运行通过。<br>
 
对不起,这个程序我看过了,而且一般sendmessage的值都可以传过去,可是当<br>主程序要从DLL中取得一个值,当主程序不为当前窗口时就无法获得,麻烦你看<br>一下我的程序有什么不对的地方。
 
还是没有人知道吗?
 
后退
顶部