4

vb.NET 2008 で、アプリケーションが (グローバルに) 最小化されていても、バックグラウンドでキーボードをリッスンするプログラムを作成したいと考えています。ユーザーが特定のキーを押した場合、ユーザーがその特定のキーを再度押すまで、一定の時間間隔で他の 2 つのキーを発射し続ける必要があります。

vb.NET 2008 でこれを行うにはどうすればよいですか?

4

2 に答える 2

16

出典:こちら

使用法: フックの作成

Private WithEvents kbHook As New KeyboardHook

次に、各イベントを処理できます。

Private Sub kbHook_KeyDown(ByVal Key As System.Windows.Forms.Keys) Handles kbHook.KeyDown
    Debug.WriteLine(Key.ToString) 
End Sub 
Private Sub kbHook_KeyUp(ByVal Key As System.Windows.Forms.Keys) Handles kbHook.KeyUp 
    Debug.WriteLine(Key) 
End Sub

キーボード フック クラス:

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
于 2013-02-23T09:03:40.647 に答える
0

KeyboardHook クラスを使用する場合は、プログラムをビルドしてから使用してください。特定のキーの質問に関しては、KeyDown または KeyUp イベントでトリガーできます。ただし、その前に sendkeys を使用してアクティブなウィンドウにキーを送信する必要があります。

SendKeys.Send("L") '文字 L をアクティブ ウィンドウに送信します。

次に、次のコードを実行できます。以下は、文字「a」が押されているかどうかを確認します。

Private Sub kbHook_KeyDown(ByVal Key As System.Windows.Forms.Keys) Handles kbHook.KeyDown
    Debug.WriteLine(Key.ToString) 
    if Key.ToString() = "a" then
     'trigger your sendkeys
    end if
End Sub 

スイッチ ボタンのような特定のキーをトリガーするには、boolean 変数を宣言して、ボタンが切り替えられたかどうかを確認します。グローバルに宣言できます。

ブール値としての薄暗いスイッチ = false

押された文字をチェックする条件を設定した領域を更新するだけです。以下のようになります。

if Key.ToString() = "a" then
  if switch = false then
    switch = true
    'trigger send keys
  else
    switch = false
    'deactivate send keys
  end if
end if

キーの送信に特定の時間を設定するには、timer を使用します。お役に立てば幸いです。

于 2016-10-18T09:46:39.233 に答える