首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VB >

为什么小弟我用VB6+WH_Mouse_LL做的全局钩子,用CallNextHookEx不能把消息传递给下一个钩子

2012-04-13 
为什么我用VB6+WH_Mouse_LL做的全局钩子,用CallNextHookEx不能把消息传递给下一个钩子 - VC/MFC / 进程/线

为什么我用VB6+WH_Mouse_LL做的全局钩子,用CallNextHookEx不能把消息传递给下一个钩子 - VC/MFC / 进程/线程/DLL
为什么我用VB6+WH_Mouse_LL做的全局钩子,用CallNextHookEx不能把消息传递给下一个钩子,代码如下:
--------------------------------------
modPub.bas:
Option   Explicit

Public   hSetWindowsHookEx   As   Long

Public   Function   LowLevelMouseProc(ByVal   nCode   As   Long,   ByVal   wParam   As   Long,   ByVal   lParam   As   Long)   As   Long
        Dim   typMHS   As   MSLLHOOKSTRUCT
        Dim   pt   As   POINTAPI
        Dim   rectWindowPosSize   As   RECT
       

        If   nCode   > =   0   Then
                If   wParam   =   WM_MOUSEMOVE   Then
                        Call   CopyMemory(typMHS,   ByVal   lParam,   LenB(typMHS))
                        pt   =   typMHS.pt
                        With   frmMain
                                .txtX   =   pt.X
                                .txtY   =   pt.Y
                        End   With
                End   If
        End   If
        Debug.Print   CallNextHookEx(hSetWindowsHookEx,   nCode,   wParam,   lParam)
'         Debug.Print   "CallNextHookEx: "   &   hSetWindowsHookEx
'         CallNextHookEx   hSetWindowsHookEx,   nCode,   wParam,   lParam
'         LowLevelMouseProc   =   CallNextHookEx(hSetWindowsHookEx,   nCode,   wParam,   lParam)
        Call   CallNextHookEx(hSetWindowsHookEx,   nCode,   wParam,   lParam)
'         LowLevelMouseProc   =   CallNextHookEx(0,   nCode,   wParam,   lParam)
End   Function
--------------------------------------
frmMain.bas:
Option   Explicit


Private   Sub   Form_Load()
        hSetWindowsHookEx   =   SetWindowsHookEx(WH_MOUSE_LL,   AddressOf   LowLevelMouseProc,   App.hInstance,   0)
End   Sub

Private   Sub   Form_Unload(Cancel   As   Integer)
        UnhookWindowsHookEx   hSetWindowsHookEx
End   Sub

--------------------------------------
modAPI.bas:
Option   Explicit
'###################################################################################################################

'设置窗体位置
Public   Declare   Function   SetWindowPos   Lib   "user32 "   _
        (   _
        ByVal   hwnd   As   Long,   _


        ByVal   hWndInsertAfter   As   Long,   _
        ByVal   X   As   Long,   _
        ByVal   Y   As   Long,   _
        ByVal   cx   As   Long,   _
        ByVal   cy   As   Long,   _
        ByVal   wFlags   As   Long   _
        )   As   Long
       
'--------------------------------------------------------------------
'hWndInsertAfter   Parameter   Value
Public   Const   HWND_BOTTOM   =   1
Public   Const   HWND_BROADCAST   =   &HFFFF&
Public   Const   HWND_DESKTOP   =   0
Public   Const   HWND_NOTOPMOST   =   -2
Public   Const   HWND_TOP   =   0
Public   Const   HWND_TOPMOST   =   -1

'--------------------------------------------------------------------
'wFlags   Paramter   Value
Public   Const   SWP_FRAMECHANGED   =   &H20                 '     The   frame   changed:   send   WM_NCCALCSIZE
Public   Const   SWP_HIDEWINDOW   =   &H80
Public   Const   SWP_NOACTIVATE   =   &H10
Public   Const   SWP_NOCOPYBITS   =   &H100
Public   Const   SWP_NOMOVE   =   &H2
Public   Const   SWP_NOOWNERZORDER   =   &H200             '     Don 't   do   owner   Z   ordering
Public   Const   SWP_NOREDRAW   =   &H8
Public   Const   SWP_NOSIZE   =   &H1
Public   Const   SWP_NOREPOSITION   =   SWP_NOOWNERZORDER
Public   Const   SWP_NOZORDER   =   &H4
Public   Const   SWP_SHOWWINDOW   =   &H40
Public   Const   SWP_DRAWFRAME   =   SWP_FRAMECHANGED
'###################################################################################################################

'类似QQ,窗体自动上浮API

Public   Declare   Function   SetWindowsHookEx   Lib   "user32 "   Alias   "SetWindowsHookExA "   (ByVal   idHook   As   Long,   ByVal   lpfn   As   Long,   ByVal   hmod   As   Long,   ByVal   dwThreadId   As   Long)   As   Long

Public   Declare   Function   CallNextHookEx   Lib   "user32 "   (ByVal   hHook   As   Long,   ByVal   nCode   As   Long,   ByVal   wParam   As   Long,   lParam   As   Any)   As   Long

Public   Declare   Function   UnhookWindowsHookEx   Lib   "user32 "   (ByVal   hHook   As   Long)   As   Long

Public   Type   POINTAPI
        X   As   Long
        Y   As   Long
End   Type

Public   Type   MSLLHOOKSTRUCT
          pt   As   POINTAPI
          mouseData   As   Long
          Flags   As   Long


          time   As   Long
          dwExtraInfo   As   Long
End   Type

Public   Const   WH_MOUSE_LL   As   Long   =   14

Public   Const   WM_MOUSEMOVE   =   &H200

Public   Type   RECT
                Left   As   Long
                Top   As   Long
                Right   As   Long
                Bottom   As   Long
End   Type

Public   Declare   Sub   CopyMemory   Lib   "kernel32 "   Alias   "RtlMoveMemory "   (Destination   As   Any,   Source   As   Any,   ByVal   Length   As   Long)

Public   Declare   Function   GetWindowRect   Lib   "user32 "   (ByVal   hwnd   As   Long,   lpRect   As   RECT)   As   Long

'###########################################################################################################

Public   Declare   Function   ShellExecute   Lib   "shell32.dll "   Alias   "ShellExecuteA "   (   _
                ByVal   hwnd   As   Long,   _
                ByVal   lpOperation   As   String,   _
                ByVal   lpFile   As   String,   _
                ByVal   lpParameters   As   String,   _
                ByVal   lpDirectory   As   String,   _
                ByVal   nShowCmd   As   Long)   As   Long

Public   Const   SW_SHOWNORMAL   =   1


------------------------------------
谢谢大家解答!!!


[解决办法]
在CallNextHookEx前面設置 LowLevelMouseProc 值;試一試!

LowLevelMouseProc=1 '取消原本要完成的動作
LowLevelMouseProc=0 '令待完成的動作繼續完成

Call CallNextHookEx(hSetWindowsHookEx, nCode, wParam, lParam)

[解决办法]
LowLevelMouseProc=0 就是把传给一下程序
LowLevelMouseProc=1 就是本过程抓住这个HOOK不放,当然鼠标指针就不动了。
当然,你可以不加这两句中的任意一句,因为默认LowLevelMouseProc=0,如果当你鼠标移动时,哪两个文本框的坐标注在变,哪说明程序运行正常,而且CallNextHookEx也把消息传递给了下一个钩子
[解决办法]
啊,原来是运行多个实例时的问题是吧
[解决办法]
我把以前写的代码拿出来看了一下,的确有这个问题

想从MSDN里找找答案,看看是不是这个_LL HOOK只能挂一个

结果看晕了过去@_@

然后又用了一下原来在网上下载的那个HOOK例子代码,是把代码放在ActiveX DLL里面再在工程里引用

这个代码就没有那样的问题,多个实例都可以拦截到鼠标事件,不过却不是使用的_LL HOOK.

建议LZ把你所谓 "没问题的 "C#代码发上来,看看是否是使用的_LL HOOK(我很怀疑.)


[解决办法]
'鼠标钩子
Public Function CallMouseHookProc(ByVal code As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
If code <> 0 Then
CallMouseHookProc = CallNextHookEx(lHook, code, wParam, lParam)


End If
End Function

我已经这样了.

然后再把显示坐标的那个EXE运行,再运行这样的一个EXE,那个EXE仍然不正常了.

看来这里面有点问题,研究一下....

同时也希望高人们指点一下.....或者E文好的朋友帮弄弄MSDN.....
[解决办法]
我也来帮顶一下

希望懂的高手讲解一下.....不一定有代码都行....原理..就可以了.....
[解决办法]
老兄,还是不要拿VB做钩子了吧,我搜过很多资料,提到过VB的弱点就是不善于做多线程和钩子,尤其是钩子,出了问题都没法调试的
[解决办法]
汗一个....去年的帖子了,还没有解决?
[解决办法]
这是个低级的钩子,我有本书专门讲解这个钩子的,很不错,是电子版的,谁要?
[解决办法]
以后需再关注,现在先帮你顶一下
[解决办法]
是你的用法有问题
把最后CallNextHookEx那里换成这一句
LowLevelMouseProc = CallNextHookEx(hSetWindowsHookEx, nCode, wParam, Byval lParam)

你的lParam前面少了一个Byval

所以会发生你说的那种情况

加上就好了

热点排行