'键盘钩子 ===========
'启动窗口中放：HookKeyboard
'关闭窗口中放：UnhookWindowsHookEx(KeyboardHandle)
'Function KeyboardCallback(ByVal nCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
'    Dim HOOKSTRUCT(0 To 4) As Long
'nnCode:指示挂钩类型
'若nCode的值小于0,则此挂钩处理过程必须将该消息不加处理地传送给函数CallNextHookEx 并返回其返回值.
'   If (nCode = 0) Then
'                                    '这条鉴别Windows的消息来源，实际上我们之前已经将HC_ACTION定义为0了，
'                                   '所以所有键盘消息都将从此通过，那么，这个鉴别的意义何在呢？因为有可能还有
'                                    '别的键盘拦截程序等待着这些消息，我们不应该将这些消息据为己有，而是该交还给系统。
'    Call CopyMemory(HOOKSTRUCT(0), ByVal lParam, 20)
'     FF_MemCopy( lParam , VarPtr(HOOKSTRUCT(0)), 20 )
'     '０按下　１放开
'     键盘钩子返回 HOOKSTRUCT(0), HOOKSTRUCT(1), wParam - 256
'     键盘钩子返回(虚拟键码 As Long, 扫描码 As Long, 功能键状态 As Long)
'     'If Hookstruct.vkCode = vbKeyA Then
'                                      '我们自己定义的一个函数，该函数过滤了我们不希望出现的键盘码，
'                                      '比如说我们现在就是要不允许用户输入A，那么就可以在IsHooked里
'                                      '将A吞噬掉，那么键盘就永远打不出A来了。该函数返回0或者1，1表示
'                                      '此键确为我们不想要的字符，那么吃掉这条消息，不将它交还系统，
'                                      'Exit Function直接退出函数。如果不是，则略过。
'       KeyboardCallback = 1
'       Exit Function
'     'End If
'   End If
'SendDate("键盘钩子", wParam , lParam )
'   Function = CallNextHookEx(KeyboardHandle, nCode, wParam, lParam)
'                                    '表示：如果前面的条件都不成立，那么说明这条消息并非我们需要的消息，
'                                    '此时我们将此消息释放，用CallNextHookEx交还给系统。
'End Function
'SetWindowsHookEx(
'  idHook: Integer;   {钩子类型}
'  lpfn: TFNHookProc; {函数指针}
'  hmod: HINST;       {包含钩子函数的模块(EXE、DLL)句柄; 一般是 HInstance; 如果是当前线程这里可以是 0}
'  dwThreadId: DWORD  {关联的线程; 可用 GetCurrentThreadId 获取当前线程; 0 表示是系统级钩子}
'): HHOOK;            {返回钩子的句柄; 0 表示失败}
'//钩子类型 idHook 选项:
'WH_MSGFILTER       = -1; {线程级; 截获用户与控件交互的消息}
'WH_JOURNALRECORD   = 0;  {系统级; 记录所有消息队列从消息队列送出的输入消息, 在消息从队列中清除时发生; 可用于宏记录}
'WH_JOURNALPLAYBACK = 1;  {系统级; 回放由 WH_JOURNALRECORD 记录的消息, 也就是将这些消息重新送入消息队列}
'WH_KEYBOARD        = 2;  {系统级或线程级; 截获键盘消息}
'WH_GETMESSAGE      = 3;  {系统级或线程级; 截获从消息队列送出的消息}
'WH_CALLWNDPROC     = 4;  {系统级或线程级; 截获发送到目标窗口的消息, 在 SendMessage 调用时发生}
'WH_CBT             = 5;  {系统级或线程级; 截获系统基本消息, 譬如: 窗口的创建、激活、关闭、最大最小化、移动等等}
'WH_SYSMSGFILTER    = 6;  {系统级; 截获系统范围内用户与控件交互的消息}
'WH_MOUSE           = 7;  {系统级或线程级; 截获鼠标消息}
'WH_HARDWARE        = 8;  {系统级或线程级; 截获非标准硬件(非鼠标、键盘)的消息}
'WH_DEBUG           = 9;  {系统级或线程级; 在其他钩子调用前调用, 用于调试钩子}
'WH_SHELL           = 10; {系统级或线程级; 截获发向外壳应用程序的消息}
'WH_FOREGROUNDIDLE  = 11; {系统级或线程级; 在程序前台线程空闲时调用}
'WH_CALLWNDPROCRET  = 12; {系统级或线程级; 截获目标窗口处理完毕的消息, 在 SendMessage 调用后发生}
'函数功能:该函数将一个应用程序定义的挂钩处理过程安装到挂钩链中去,您可以通过安装挂钩处理过程来对系统的某些类型事件进行监控,这些事件与某个特定的线程或系统中的所有事件相关.
'函数原形:HHOOK SetWindowsHookEx( int idHook, HOOKPROC lpfn,HINSTANCE hMod,DWORD dwThreadId );
'参数:
'idHook:指示欲被安装的挂钩处理过程之类型,此参数可以是以下值之一:
'WH_CALLWNDPROC(4): 安装一个挂钩处理过程,在系统将消息发送至目标窗口处理过程之前,对该消息进行监视,详情参见CallWndProc挂钩处理过程.
'WH_CALLWNDPROCRET(12) :安装一个挂钩处理过程,它对已被目标窗口处理过程处理过了的消息进行监视,详情参见 CallWndRetProc 挂钩处理过程.
'WH_CBT(5) :安装一个挂钩处理过程,接受对CBT应用程序有用的消息 ,详情参见 CBTProc 挂钩处理过程.
'WH_DEBUG(9):安装一个挂钩处理过程以便对其他挂钩处理过程进行调试, 详情参见DebugProc挂钩处理过程.
'WH_FOREGROUNDIDLE(11):安装一个挂钩处理过程,该挂钩处理过程当应用程序的前台线程即将进入空闲状态时被调用,它有助于在空闲时间内执行低优先级的任务.
'WH_GETMESSAGE(3):安装一个挂钩处理过程对寄送至消息队列的消息进行监视,详情参见 GetMsgProc 挂钩处理过程.
'WH_JOURNALPLAYBACK(1):安装一个挂钩处理过程,对此前由WH_JOURNALRECORD 挂钩处理过程纪录的消息进行寄送.详情参见 JournalPlaybackProc挂钩处理过程.
'WH_JOURNALRECORD(0):安装一个挂钩处理过程,对寄送至系统消息队列的输入消息进行纪录.详情参见JournalRecordProc挂钩处理过程.
'WH_KEYBOARD(2):安装一个挂钩处理过程对击键消息进行监视. 详情参见KeyboardProc挂钩处理过程.
'WH_KEYBOARD_LL(13):此挂钩只能在Windows NT中被安装,用来对底层的键盘输入事件进行监视.详情参见LowLevelKeyboardProc挂钩处理过程.
'WH_MOUSE(7):安装一个挂钩处理过程,对鼠标消息进行监视. 详情参见 MouseProc挂钩处理过程.
'WH_MOUSE_LL(14):此挂钩只能在Windows NT中被安装,用来对底层的鼠标输入事件进行监视.详情参见LowLevelMouseProc挂钩处理过程.
'WH_MSGFILTER(-1):安装一个挂钩处理过程, 以监视由对话框、消息框、菜单条、或滚动条中的输入事件引发的消息.详情参见MessageProc挂钩处理过程.
'WH_SHELL(10):安装一个挂钩处理过程以接受对外壳应用程序有用的通知, 详情参见 ShellProc挂钩处理过程.
'WH_SYSMSGFILTER(6):安装一个挂钩处理过程,以监视由对话框、消息框、菜单条、或滚动条中的输入事件引发的消息.这个挂钩处理过程对系统中所有应用程序的这类消息都进行监视.详情参见 SysMsgProc挂钩处理过程.
'lpfn:指向相应的挂钩处理过程.若参数dwThreadId为0或者指示了一个其他进程创建的线程之标识符,则参数lpfn必须指向一个动态链接中的挂钩处理过程.否则,参数lpfn可以指向一个与当前进程相关的代码中定义的挂钩处理过程.
'hMod:指示了一个动态链接的句柄,该动态连接库包含了参数lpfn 所指向的挂钩处理过程.若参数dwThreadId指示的线程由当前进程创建,并且相应的挂钩处理过程定义于当前进程相关的代码中,则参数hMod必须被设置为NULL(0).
'dwThreadId:指示了一个线程标识符,挂钩处理过程与线程相关.若此参数值为0,则该挂钩处理过程与所有现存的线程相关.
'返回值:若此函数执行成功,则返回值就是该挂钩处理过程的句柄;若此函数执行失败,则返回值为NULL(0).若想获得更多错误信息,请调用GetLasError函数.
'备注:若参数hMod为NULL,而参数dwThreadld为0或者指示了一个其他进程创建的线程标识符,则会产生错误.
'对函数CallNextHookEx进行调用以下链接下一个挂钩处理过程是可选的,但也是被推荐的否则,其他安装了此挂钩的应用程序将无法获得此挂钩通知,从而可能导致错误的行为.除非您确实希望防止其他应用程序看到此挂钩通知,您应当调用函数CallNextHookEx.
'在终止一个应用程序之前,必须调用函数UnhookWindowsHookEx以释放与此挂钩相关的系统资源.
'挂钩的作用域依赖与挂钩的类型.一些挂钩只能被设置成系统作用域,其他挂钩(如下所示)还可以被设置为某一特定线程的作用域:
'WH_CALLWNDPROC 线程或系统
'WH_CALLWNDPROCRET 线程或系统
'WH_CBT 线程或系统
'WH_DEBUG 线程或系统
'WH_FOREGROUNDIDLE 线程或系统
'WH_GETMESSAGE 线程或系统
'WH_JOURNALPLAYBACK 系统
'WH_JOURNALRECORD 系统
'WH_KEYBOARD 线程或系统
'WH_KEYBOARD_LL 线程或系统
'WH_MOUSE 线程或系统
'WH_MOUSE_LL 线程或系统
'WH_MSGFILTER 线程或系统
'WH_SHELL 线程或系统
'WH_SYSMSGFILTER 系统
'对于一个特定的挂钩类型,现成的挂钩先被调用,然后才是系统挂钩被调用.
'系统挂钩作为共享资源,安装一次就对所用应用程序产生影响.所有的系统挂钩函数必须在库中.系统挂钩应当被限制用于一些特殊用途的应用程序或者用来作为应用程序调试的辅助工具.不再需要挂钩的库应当将相应的挂钩处理过程删除掉.
'速查:Windows NT:3.1以及以上版本,Windows :95以及以上版本,Windows CE 不支持,头文件winuser.h,库文件:用户自定义,Unicode,在Windows NT上实现了Unicode和ANSI的版本.
'ShellProc
'函数功能:挂钩处理过程是应用程序或库中定义的回调函数,它与函数 SetWindowsHookEx搭配使用.此函数从系统接受外壳(shell)通知.类型HOOKPROC定义了指向此类回调函数的指针.ShellProc时应用程序或库中定义的相应回调的位置标志符.
'函数原形:LRESULT CALLBACK ShellProc( int nCode, WPARAM wParam,LPARAM lParam );
'参数:
'nCode:指示挂钩类型,该参数可以是以下值之一:
'HSHELL_ACCESSIBILITYSTATE: 对Windows NT5.0或以上版本有效,指示"可访问性"已被改变.
'HSHELL_ACTIVATESHELLWINDOW: shell应当激活其主窗口.
'HSHELL_GETMINRECT: Windows 95 only: 一个窗口正在被最小化或者最大化,系统需要该窗口被最小化时的矩形坐标.
'HSHELL_LANGUAGE : Windows 95 only: 键盘语言被改变或者一个新的键盘布局被加载.
'来源：(http://blog.sina.com.cn/s/blog_626a27090100f0m3.html) - 钩子函数大全_老代码_新浪博客
'HSHELL_REDRAW: Windows 95 only: 一个窗口在任务条上的标题已被重画.
'HSHELL_TASKMAN: Windows 95 only: 用户已选择其任务列表.一个提供了任务的列表的shell应用程序当返回TRUE,以阻止Windows开始(执行)其任务列表.
'HSHELL_WINDOWACTIVATED: Windows 95 only: 激活状态已被转移给一个不同的顶层无属性主窗口.
'HSHELL_WINDOWCREATED: 一个顶层无属性主窗口已被创建.当系统调用一个SheProc函数时,该窗口存在.
'HSHELL_WINDOWDESTROYED:一个顶层无属性主窗口即将销毁.当系统调用SheProc 函数时.该窗口仍然存在.
'若nCode的值小于0,则此挂钩处理过程必须将该消息不加处理地传送给函数CallNextHookEx 并返回其返回值.
'wParam: 此参数的值依赖于参数nCode,其依赖关系如下所示:
'HSHELL_ACCESSIBILITYSTATE: 指示哪一个可以访问特征已被改变了状态,可以是以下值之一:
'ACCESS_FILTERKYS,ACCESS_MOUSEKEYS,ACCESS_STICKKEYS.
'HSHELL_GETMINRECT:被最小化或者最大化的窗口句柄.HSHELL_LANGUAGE: 窗口的句柄.
'HSHELL_REDRAW:被重画的窗口的句柄.HSHELL_WINDOWACTIVATED:被激活的窗口的句柄.
'HSHELL_WINDOWCREATED:被创建的窗口的句柄.HSHELL_WINDOWDESTROYED:被销毁的窗口的句柄.
'lParam:此参数的值依赖于参数nCode,其依赖关系如下所示:
'HSHELL_GETMINRECT:指向该RECT结构的指针.HSHELL_LANGUAGE: 键盘布局的句柄.
'HSHELL_REDRAW: 若该窗口正在闪现,则其值为TRUE,否则为FALSE.
'HSHELL_WINDOWACTIVATED: 若该窗口是全屏模式,则其值为TRUE,否则为FALSE.返回值:返回值应为0.
'备注:此挂钩处理过程通过调用函数SetWindowsHookEx ,指定WH_SHLL挂钩类型及其相应挂钩处理过程首地址来安装.
'速查:Windows NT:3.1以及以上版本,Windows :95以及以上版本,Windows CE 不支持,头文件winuser.h,库文件,用户自定义.
'SysMsgProc
'函数功能:挂钩处理过程是应用程序或库中定义的回调函数,它与函数 SetWindowsHookEx搭配使用.当一个对话框、消息框、菜单条、或滚动条中的输入事件发生，且由此引发的消息尚未被处理之前,系统对此挂钩处理过程进行调用.此函数可以对系统中所有的对话框、消息框、菜单条、或滚动条消息进行监视.
'类型HOOKPROC定义了指向此类回调函数的指针.SysMsgProc 是库中相应回调函数名的位置标志符.
'函数原形:LRESULT CALLBACK SysMsgProc(int nCode,WPARAM wParam,LPARAM lParam);
'参数:
'nCode:指示产生此消息的输入事件类型.此参数可以是以下值之一:
'MSGF_DIALOGBOX: 输入事件由一个消息框或者对话框产生.
'MSGF_MENU: 输入事件由一个菜单条产生.
'MSGF_SCROLLBAR: 输入事件由一个滚动条产生.
'MSGF_NEXTWINDOW: 输入事件由于用户摁下组合键<Alt+Tab>以激活另一个窗口而产生.
'若nCode的值小于0,则此挂钩处理过程必须将该消息不加处理地传送给函数 CallNextHookEx 并返回其返回值.
'wParam: 为NULL(0).
'lParam: 指向MSG结构的[指针].
'返回值:若nCode的值小于0,则此挂钩处理过程必须返回CallNextHookEx 的返回值.若nCode的值大于或等于0,并且此挂钩处理过程未对该消息进行处理,则调用函数CallNextHookEx 并返回其返回值是被推荐的.否则,其他安装了WH_SYSMSGFILTER挂钩的应用程序将无法收到此挂钩通知,并可能由此导致错误的行为.若此挂钩处理过程处理了此消息,它应返回一个非零值以避免系统再将此消息传送给目标窗口处理过程.
'备注:一个应用程序通过调用函数SetWindowsHookEx 指定 WH_SYSMSGFILTER挂钩类型及相应挂钩处理过程首地址来安装此挂钩.
'速查:Windows NT:3.1以及以上版本,Windows :95以及以上版本,Windows CE 不支持,头文件winuser.h,库文件,用户自定义.
'UnhookWindowsHookEx
'函数功能: 该函数将一个由SetWindowsHookEx 安装的挂钩处理过程从挂钩链中删除.
'函数原形: BOOL UnhookWindowsHookEx(HHOOK hhk);
'参数:
'hhk: 被删除的挂钩的句柄.此参数是一个挂钩句柄,该句柄是此前函数SetWindowsHookEx的返回值.
'返回值:该函数执行成功返回非0值,失败返回0.
'备注:即使UnhookWindowsHookEx 函数返回之后,该钩子处理过程也可能正处于被其它线程调用的状态.若当前未调用该钩子处理过程,则在 UnhookWindowsHookEx 函数返回之前该钩子处理过程被立即删除.
'DelHookProc:该函数已过时,它仅仅是用来与Windows的16位版本兼容.在32位Windows系统中应当使用函数CallNextHookEx.
'SetWindowsHook:该函数已过时,它仅仅是用来与Windows的16位版本兼容.在32位Windows系统中应当使用函数SetWindowsHookEx.
'UnhookWindowsHook:该函数已过时,它仅仅是用来与Windows的16位版本兼容.在32位Windows系统中应当使用函数UnhookWindowsHookEx.
'CallMsgFilter
'函数功能:该函数将特定消息和挂钩代码发送给与挂钩 WH_SYSMSGFILTER和WH_MSGFILTER 相联系的挂钩处理过程,一个 WH_SYSMSGFILTER 或者 WH_MSGFILTER挂钩处理过程是指应用程序定义的回调函数,这些回调函数负责检查,并可有选择地修改关于对话框、消息框、菜单条、滚动条的消息。
'函数原形：BOOL CallMsgFilter(LPMSG lpMsg, int nCode);
'参数：
'lpMsg：指向一个MSG结构,该结构包含发送给挂钩处理过程的消息.
'nCode:指定挂钩处理过程需要使用的应用程序定义的代码,以确定如何对消息进行处理,该代码切忌采用与系统预定义的与WH_SYSMSGFILTER和WH_MSGFILTER挂钩相关的挂钩代码(MSGF_ 和 HC_开头)相同的值.
'返回值:若该应用程序可对消息作进一步处理,则返回值为0,若该应用程序不能对该消息作进一步处理,则返回值为非0值.
'备注:系统对CallMsgFilter进行调用,以使得应用程序能够检查和控制在对对话框、消息框、菜单条、滚动条的内部处理过程中产生的,或是由用户按下<Alt+Tab>组合键以激活不同窗口时产生的消息流.
'可通过调用函数SetWindowsHookEx来安装此挂钩处理过程.
'速查:Windows NT:3.1以及以上版本,Windows :95以及以上版本,Windows CE 不支持,头文件:winuser.h,库文件:user32.lib,Unicode:在Windows NT上实现了Unicode和ANSI的版本.
Common Shared  KeyboardHandle as HHOOK
Function HookKeyboard(ByVal TID as ULong) as HHOOK  '定义键盘钩子
   KeyboardHandle = SetWindowsHookEx(WH_KEYBOARD, @KeyboardCallback, App.hInstance, TID)
   '1 钩子类型
   '2 回调函数地址
   '3 实例句柄
   '4 线程ID  =0 钩全部
   Function = KeyboardHandle
End Function
