MOUSE HOOK(200分)

C

CJ

Unregistered / Unconfirmed
GUEST, unregistred user!
MOUSE HOOK 例子<br>想了解当前其SHIFT STATUS,是否为RIGHT CLICK<br>那个STRUCT我晕了,懒得研究
 
监测左、右Shift借鉴Dos下的中断(Int 16H),其每个Bit位都有说明。
 
好象CJ 要的是鼠标的状态, 不是键盘状态. 正在研究中, 希望能在睡觉前搞懂.
 
别研究了, MOUSEHOOKSTURCT里没有这个信息. <br>可以调用getkeystate(VK_RBUTTON), 根据返回值判断, 如果返回值最高位为1表示Right<br>button按下了. 否则没有按下
 
Dos下的Int 33H是控制鼠标的,它能监测按钮状态。
 
<br>同意eyes, 我找了三圈也没发现MOUSEHOOKSTURCT中有键态的信息. <br>在MSG中判断MSG类别, WM_LBUTTONDOWN, WM_RBUTTONDOWN中 你看着办<br>试试吧.
 
看清题目, 是在hook里. win32程序没法调16位实模式下的软中断.
 
我说的意思是指: 在截获的一些鼠标消息中本来就有SHIFT STATUS的状态,<br><br>WM_MOUSEMOVE, WM_LBUTTONDOWN, WM_RBUTTONDOWN 等消息可以用下列方法.<br><br>Message.WParam 就代表了SHIFT STATUS的状态<br><br>MK_LBUTTON &nbsp; 1 Set if the left mouse button is down.<br>MK_RBUTTON &nbsp; 2 Set if the right mouse button is down.<br>MK_SHIFT &nbsp; &nbsp; 4 Set if the SHIFT key is down.<br>MK_CONTROL &nbsp; 8 Set if the CTRL key is down.<br>MK_MBUTTON &nbsp; 16 Set if the middle mouse button is down.<br><br>如上所述, 判断右键可以通过判断第2位是否是1, &nbsp;<br>&nbsp;if (WParam and 2)=2 then //判读右键是否按下. <br>
 
seasky, mousehook不提供msg结构给回调程序的(只提供message号-比如WM_MOUSEMOVE, <br>坐标, hittest返回值...).<br>根据message号判断吧:<br>if WM_RBUTTONDOWN then 变量置位<br>else if WM_RBUTTONUP then 变量复位&amp;rightclick了.
 
咦, 我在win32 hlp 中查看 WM_MOUSEMOVE, <br><br>WM_MOUSEMOVE &nbsp;<br>fwKeys = wParam; &nbsp; &nbsp; &nbsp; &nbsp;// key flags <br>xPos = LOWORD(lParam); &nbsp;// horizontal position of cursor <br>yPos = HIWORD(lParam); &nbsp;// vertical position of cursor <br><br>Parameters<br><br>fwKeys<br><br>Value of wParam. Indicates whether various virtual keys are down. This parameter can be any combination of the following values: <br><br>Value Description<br>MK_CONTROL Set if the CTRL key is down.<br>MK_LBUTTON Set if the left mouse button is down.<br>MK_MBUTTON Set if the middle mouse button is down.<br>MK_RBUTTON Set if the right mouse button is down.<br>MK_SHIFT &nbsp; &nbsp; &nbsp; &nbsp; Set if the SHIFT key is down.<br><br>并且, 我也在Delphi中取出了各个键的状态. <br>鼓捣这玩意, 没经验的说, 希望能多学习学习. <br><br>例子如下, <br><br>&nbsp; TForm1 = class(TForm)<br>&nbsp; &nbsp; Edit1: TEdit;<br>&nbsp; &nbsp; Button1: TButton;<br>&nbsp; &nbsp; procedure FormCreate(Sender: TObject);<br>&nbsp; private<br>&nbsp; &nbsp; { Private declarations }<br>&nbsp; public<br>&nbsp; &nbsp; { Public declarations }<br>&nbsp; end;<br><br>var<br>&nbsp; Form1: TForm1;<br>&nbsp; YourHook: HHOOK;<br>function YourHookProc(Code: Integer; WParam: Longint; var Msg: TMsg): Longint; stdcall;<br><br>implementation<br><br>{$R *.DFM}<br>function YourHookProc(Code: Integer; WParam: Longint; var Msg: TMsg): Longint; stdcall;<br>begin<br>&nbsp; &nbsp;if Msg.Message = WM_MOUSEMOVE then &nbsp;begin<br>&nbsp; &nbsp; &nbsp; form1.Edit1.text := inttostr(msg.wParam); &nbsp;//msg.wParam 就是鼠标键和Shift/ctrl的各个状态值.<br>&nbsp; &nbsp;end;<br>&nbsp; &nbsp;Result := CallNextHookEx(YourHook, Code, WParam, Longint(@Msg));<br>end;<br><br>procedure TForm1.FormCreate(Sender: TObject);<br>begin<br>&nbsp; &nbsp;YourHook := SetWindowsHookEx(WH_GETMESSAGE, @YourHookProc, 0, GetCurrentThreadID);<br>end;<br><br>
 
你取到的是msg.wparam吗? 好象不是吧, 根据win32.hlp, 你程序中的Msg指向的是<br>MOUSEHOOKSTRUCT, 在其中相当于Msg结构中wparam位置的值是hwnd吧?<br><br>MOUSEHOOKSTRUCT: &nbsp;&lt;--&gt; &nbsp; &nbsp; &nbsp; MSG:<br>&nbsp; pt.x &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;--&gt; &nbsp; &nbsp; &nbsp; &nbsp;hwnd &nbsp; &nbsp; &nbsp; (4 bytes)<br>&nbsp; pt.y &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;--&gt; &nbsp; &nbsp; &nbsp; &nbsp;messageId &nbsp;(4 bytes)<br>&nbsp; hwnd &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;--&gt; &nbsp; &nbsp; &nbsp; &nbsp;wparam &nbsp; &nbsp; (4 bytes)<br>&nbsp; hittestcode &nbsp; &nbsp; &lt;--&gt; &nbsp; &nbsp; &nbsp; &nbsp;lparam &nbsp; &nbsp; (4 bytes)<br>&nbsp; extraInfo &nbsp; &nbsp; &nbsp; &lt;--&gt; &nbsp; &nbsp; &nbsp; &nbsp;time &nbsp; &nbsp; &nbsp; (4 bytes)<br>&nbsp; &lt;超界&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;--&gt; &nbsp; &nbsp; &nbsp; &nbsp;point.x &nbsp; &nbsp;(4 bytes)<br>&nbsp; &lt;超界&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;--&gt; &nbsp; &nbsp; &nbsp; &nbsp;point.y &nbsp; &nbsp;(4 bytes)
 
<br>可是我的程序完全试成功了, &nbsp;试验情况如下:<br><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Edit1.text值 &nbsp; &nbsp;<br>---------------------------------------<br>当左键按下时拖动鼠标, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1<br>当右键按下时拖动鼠标, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2<br>当中键按下时拖动鼠标, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 16<br>当左、右键按下时拖动鼠标, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;3 <br>当Shift按下时拖动鼠标, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;4<br>当Ctrl按下时拖动鼠标, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 8<br>当左中右键,shift,ctrl全按下脱动鼠标, 31<br><br>另外我看的是Win32 中关于WM_MOUSEMOVE的解释。
 
哦? 关于mousehook的win32 hlp是错误的? 还是我理解上有问题?<br><br>Parameters<br><br>nCode<br><br>Specifies a code the hook procedure uses to determine how to process the message. This parameter can be one of the following values: <br><br>Value Meaning<br>HC_ACTION The wParam and lParam parameters contain information about a mouse message.<br>HC_NOREMOVE The wParam and lParam parameters contain information about a mouse message, and the mouse message has not been removed from the message queue. (An application called the PeekMessage function, specifying the PM_NOREMOVE flag.)<br>&nbsp;<br><br>If nCode is less than zero, the hook procedure must pass the message to the CallNextHookEx function without further processing and should return the value returned by CallNextHookEx. <br><br>wParam<br><br>Specifies the identifier of the mouse message. <br><br>lParam<br><br>Points to a MOUSEHOOKSTRUCT structure. <br>^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^<br><br>??????????
 
To eyes: 先谢谢,没有这个题目, 我也不会捣鼓这东西, 多试验多涨经验值。 <br><br>我截取的消息是WM_MOUSEMOVE, 你取的肯定不是这个消息(没看出来你取的是什么<br>消息,还要请教〕。<br>好象我们说的不是一码事, 自然对不到一块。 <br><br><br>
 
哦, 明白了.<br>你是message hook(WH_GETMESSAGE), 我是mouse hook(WH_MOUSE), 两码事.
 
About how to know mouse button status:<br>一个例子如下:<br>Var<br>&nbsp; bLKDown: boolean;<br><br>Begin<br><br>&nbsp; if (GetSystemMetrics(SM_SWAPBUTTON)&gt;0) then<br>&nbsp; &nbsp; bLKDown := (GetAsyncKeyState(VK_RBUTTON)&gt;0);<br>&nbsp; else<br>&nbsp; &nbsp; bLKDown := (GetAsyncKeyState(VK_LBUTTON)&gt;0);
 
he he, 前三名大抢第四名的分; <br><br>&nbsp; &nbsp;Pega :2171 &nbsp;seasky: 1972 &nbsp;anothereyes :1925 &nbsp; CJ :1580 <br><br>wuwu, 正好差200分的说, &nbsp;:((<br><br>&nbsp; Pega: 照片冲好了吗? 如果冲好我上你那儿瞧瞧去.
 
key and mouse status are both needed:) shift+right click?:)))<br><br>Seasky: 你用 Message Hook? 看来我呀回去试试;<br>eYes: 您老具体点好吗?那个Msg哪里来的?你们怎么一搞我脑子都乱了,Mouse Hook 的帮助和概念好象都没什么错,我试过了;<br>Pegasus 您的例子倒不错,我没来得及试,这东西我不熟,怎么理解你的程序?为什么是 if...else ? 运行以后 bLKDown 里是什么?如果是 true 我怎么知道是左还是右?key status 的有没有?<br>Jams: 如果在 DOS 下,这玩意我熟的很。<br><br>大家抢我的分是好事,就怕没人抢的说:-)<br><br>MOUSE HOOK具体是如下定义:<br><br>LRESULT CALLBACK MouseProc(<br><br>&nbsp; &nbsp; int nCode, // hook code<br>&nbsp; &nbsp; WPARAM wParam, // message identifier &nbsp;// 触发者?<br>&nbsp; &nbsp; LPARAM lParam // mouse coordinates &nbsp; //指向那么个结构<br>);<br><br>typedef struct tagMOUSEHOOKSTRUCT { // ms &nbsp;<br>&nbsp; &nbsp; POINT pt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//point类,返回鼠标位置<br>&nbsp; &nbsp; HWND &nbsp;hwnd; &nbsp; &nbsp; &nbsp; //窗口句柄<br>&nbsp; &nbsp; UINT &nbsp;wHitTestCode; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//测试码<br>&nbsp; &nbsp; DWORD dwExtraInfo; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //不懂,这里面有花头?<br>} <br>
 
犯了低级错误,sorry
 
1) Use low level hook (WH_MOUSE_LL) under NT will help you solve <br>the problem easily. See MSDN for more detailed information<br>2) WH_MOUSE will tell you the mouse action (not status),wParam will be WM_LBUTTONDOWN, WM_LBUTTONUp...etc. Record the data in your <br>program, and read the data later as mouse "status".<br>3) Hook message and handle the WM_MOUSEMOVE is a solution also.<br>Problem: how about the the user use keyboard and did not move the <br>mouse? You will never get the status because no WM_MOUSEMOVE sent <br>out. And the HOOK never get the action notify also.<br>(If there is a "remote control mouse", this issue will happened)<br><br>As Another_eYes said before, getkeystate() is a good choice<br>Problem: The system never "tell" you the status is changed. You should check the status by yourself.<br><br>You can use the two solutions at same time, or use one of them, depend on your project.<br>Hope it helps.<br><br>
 

Similar threads

回复
0
查看
886
不得闲
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
顶部