vb.NET 2008 で、アプリケーションが (グローバルに) 最小化されていても、バックグラウンドでキーボードをリッスンするプログラムを作成したいと考えています。ユーザーが特定のキーを押した場合、ユーザーがその特定のキーを再度押すまで、一定の時間間隔で他の 2 つのキーを発射し続ける必要があります。
vb.NET 2008 でこれを行うにはどうすればよいですか?
vb.NET 2008 で、アプリケーションが (グローバルに) 最小化されていても、バックグラウンドでキーボードをリッスンするプログラムを作成したいと考えています。ユーザーが特定のキーを押した場合、ユーザーがその特定のキーを再度押すまで、一定の時間間隔で他の 2 つのキーを発射し続ける必要があります。
vb.NET 2008 でこれを行うにはどうすればよいですか?
使用法: フックの作成
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
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 を使用します。お役に立てば幸いです。