gpt4 book ai didi

.net - 如何在单独的线程上设置全局键盘 Hook ?

转载 作者:行者123 更新时间:2023-12-03 13:05:21 25 4
gpt4 key购买 nike

经过多次搜索后,我最终使用此类进行全局键盘 Hook 。链接:Global Hook post

Imports System.Runtime.InteropServices

Public Class KeyboardHook

<DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)> _
Private Overloads Shared Function SetWindowsHookEx(ByVal idHook As Integer, ByVal HookProc As KBDLLHookProc, ByVal hInstance As IntPtr, ByVal wParam As Integer) As Integer
End Function
<DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)> _
Private Overloads Shared Function CallNextHookEx(ByVal idHook As Integer, ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
End Function
<DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)> _
Private Overloads Shared Function UnhookWindowsHookEx(ByVal idHook As Integer) As Boolean
End Function

<StructLayout(LayoutKind.Sequential)> _
Private Structure KBDLLHOOKSTRUCT
Public vkCode As UInt32
Public scanCode As UInt32
Public flags As KBDLLHOOKSTRUCTFlags
Public time As UInt32
Public dwExtraInfo As UIntPtr
End Structure

<Flags()> _
Private Enum KBDLLHOOKSTRUCTFlags As UInt32
LLKHF_EXTENDED = &H1
LLKHF_INJECTED = &H10
LLKHF_ALTDOWN = &H20
LLKHF_UP = &H80
End Enum

Public Shared Event KeyDown(ByVal Key As Keys)
Public Shared Event KeyUp(ByVal Key As Keys)

Private Const WH_KEYBOARD_LL As Integer = 13
Private Const HC_ACTION As Integer = 0
Private Const WM_KEYDOWN = &H100
Private Const WM_KEYUP = &H101
Private Const WM_SYSKEYDOWN = &H104
Private Const WM_SYSKEYUP = &H105

Private Delegate Function KBDLLHookProc(ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer

Private KBDLLHookProcDelegate As KBDLLHookProc = New KBDLLHookProc(AddressOf KeyboardProc)
Private HHookID As IntPtr = IntPtr.Zero

Private Function KeyboardProc(ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
If (nCode = HC_ACTION) Then
Dim struct As KBDLLHOOKSTRUCT
Select Case wParam
Case WM_KEYDOWN, WM_SYSKEYDOWN
RaiseEvent KeyDown(CType(CType(Marshal.PtrToStructure(lParam, struct.GetType()), KBDLLHOOKSTRUCT).vkCode, Keys))
Case WM_KEYUP, WM_SYSKEYUP
RaiseEvent KeyUp(CType(CType(Marshal.PtrToStructure(lParam, struct.GetType()), KBDLLHOOKSTRUCT).vkCode, Keys))
End Select
End If
Return CallNextHookEx(IntPtr.Zero, nCode, wParam, lParam)
End Function

Public Sub New()
HHookID = SetWindowsHookEx(WH_KEYBOARD_LL, KBDLLHookProcDelegate, System.Runtime.InteropServices.Marshal.GetHINSTANCE(System.Reflection.Assembly.GetExecutingAssembly.GetModules()(0)).ToInt32, 0)
If HHookID = IntPtr.Zero Then
Throw New Exception("Could not set keyboard hook")
End If
End Sub

Protected Overrides Sub Finalize()
If Not HHookID = IntPtr.Zero Then
UnhookWindowsHookEx(HHookID)
End If
MyBase.Finalize()
End Sub

End Class

它工作得很好。

我的应用程序正在执行需要几秒钟才能完成的操作(ftp 每隔一段时间上传小文件),在此期间钩子(Hook)喜欢键盘。这我当然不想要

我现在不能跳到 Async FtpWebRequest 因为它需要很多更改,所以我认为解决方案是让钩子(Hook)在另一个线程中存在。

我该怎么做?

编辑:一个建议是将我的耗时操作(上传)移动到另一个线程。这样做后我面临其他问题。因为耗时的任务(上传)在一个计时器中,所以我将不得不重写大部分以便同步文件->保存与文件->上传,我不介意应用程序锁定 3-4 秒。我介意的是松开 kayboard 3-4 秒...

最佳答案

不要让钩子(Hook)在不同的线程上运行(我认为你不能,它基于消息循环);相反,只需在另一个线程中运行您的任务。这可能是最简单的方法:

Call New Thread(Sub()
' Do stuff here
End Sub) With {.IsBackground = True}.Start()

关于.net - 如何在单独的线程上设置全局键盘 Hook ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10375106/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com