[VB.NET]调用API获取/设置键盘按键状态

时间:2023-03-08 19:37:41
[VB.NET]调用API获取/设置键盘按键状态

前言

  通过 C# 或 VB.NET,你只需编写少量的代码,即可模拟按键事件。

第一节 调用接口

  通过调用系统底层 API ,获取或设置指定的按键状态。

  获取按键状态

  调用 GetAsyncKeyState() 获取指定按键的状态,GetActiveKey() 检索指定范围内的按键状态

  合成击键事件

  调用 keybd_event() 可合成一次击键事件,通常两次击键事件间需要设定时间间隔

  对 DirectInput 有效

  调用 MapVirtualKey() 获取指定按键的硬件扫描码,传入 keybd_event() 第二个参数可以对 DirectInput 有效。

第二节 帮助类

  实现一系列的静态方法,由此提供不同的模拟按键功能。

  虚拟键码枚举

''' <summary>
''' 虚拟键码枚举
''' </summary>
Public Enum VirtualKeys
VK_LBUTTON =
VK_RBUTTON =
VK_CANCEL =
VK_MBUTTON =
VK_XBUTTON1 =
VK_XBUTTON2 =
VK_BACK =
VK_TAB =
VK_CLEAR =
VK_RETURN =
VK_SHIFT =
VK_CONTROL =
VK_MENU =
VK_PAUSE =
VK_CAPITAL =
VK_KANA =
VK_HANGUL =
VK_JUNJA =
VK_FINAL =
VK_HANJA =
VK_KANJI =
VK_ESCAPE =
VK_CONVERT =
VK_NONCONVERT =
VK_ACCEPT =
VK_MODECHANGE =
VK_SPACE =
VK_PRIOR =
VK_NEXT =
VK_END =
VK_HOME =
VK_LEFT =
VK_UP =
VK_RIGHT =
VK_DOWN =
VK_SELECT =
VK_PRINT =
VK_EXECUTE =
VK_SNAPSHOT =
VK_INSERT =
VK_DELETE =
VK_HELP =
VK_0 =
VK_1 =
VK_2 =
VK_3 =
VK_4 =
VK_5 =
VK_6 =
VK_7 =
VK_8 =
VK_9 =
VK_A =
VK_B =
VK_C =
VK_D =
VK_E =
VK_F =
VK_G =
VK_H =
VK_I =
VK_J =
VK_K =
VK_L =
VK_M =
VK_N =
VK_O =
VK_P =
VK_Q =
VK_R =
VK_S =
VK_T =
VK_U =
VK_V =
VK_W =
VK_X =
VK_Y =
VK_Z =
VK_LWIN =
VK_RWIN =
VK_APPS =
VK_SLEEP =
VK_NUMPAD0 =
VK_NUMPAD1 =
VK_NUMPAD2 =
VK_NUMPAD3 =
VK_NUMPAD4 =
VK_NUMPAD5 =
VK_NUMPAD6 =
VK_NUMPAD7 =
VK_NUMPAD8 =
VK_NUMPAD9 =
VK_MULTIPLY =
VK_ADD =
VK_SEPARATOR =
VK_SUBTRACT =
VK_DECIMAL =
VK_DIVIDE =
VK_F1 =
VK_F2 =
VK_F3 =
VK_F4 =
VK_F5 =
VK_F6 =
VK_F7 =
VK_F8 =
VK_F9 =
VK_F10 =
VK_F11 =
VK_F12 =
VK_F13 =
VK_F14 =
VK_F15 =
VK_F16 =
VK_F17 =
VK_F18 =
VK_F19 =
VK_F20 =
VK_F21 =
VK_F22 =
VK_F23 =
VK_F24 =
VK_NUMLOCK =
VK_SCROLL =
VK_LSHIFT =
VK_RSHIFT =
VK_LCONTROL =
VK_RCONTROL =
VK_LMENU =
VK_RMENU =
VK_BROWSER_BACK =
VK_BROWSER_FORWARD =
VK_BROWSER_REFRESH =
VK_BROWSER_STOP =
VK_BROWSER_SEARCH =
VK_BROWSER_FAVORITES =
VK_BROWSER_HOME =
VK_VOLUME_MUTE =
VK_VOLUME_DOWN =
VK_VOLUME_UP =
VK_MEDIA_NEXT_TRACK =
VK_MEDIA_PREV_TRACK =
VK_MEDIA_STOP =
VK_MEDIA_PLAY_PAUSE =
VK_LAUNCH_MAIL =
VK_LAUNCH_MEDIA_SELECT =
VK_LAUNCH_APP1 =
VK_LAUNCH_APP2 =
VK_OEM_1 =
VK_OEM_PLUS =
VK_OEM_COMMA =
VK_OEM_MINUS =
VK_OEM_PERIOD =
VK_OEM_2 =
VK_OEM_3 =
VK_OEM_4 =
VK_OEM_5 =
VK_OEM_6 =
VK_OEM_7 =
VK_OEM_8 =
VK_OEM_102 =
VK_PACKET =
VK_PROCESSKEY =
VK_ATTN =
VK_CRSEL =
VK_EXSEL =
VK_EREOF =
VK_PLAY =
VK_ZOOM =
VK_NONAME =
VK_PA1 =
VK_OEM_CLEAR =
End Enum

VB.NET-VirtualKeys

/// <summary>
/// 虚拟键码枚举
/// </summary>
public enum VirtualKeys
{
VK_LBUTTON = ,
VK_RBUTTON = ,
VK_CANCEL = ,
VK_MBUTTON = ,
VK_XBUTTON1 = ,
VK_XBUTTON2 = ,
VK_BACK = ,
VK_TAB = ,
VK_CLEAR = ,
VK_RETURN = ,
VK_SHIFT = ,
VK_CONTROL = ,
VK_MENU = ,
VK_PAUSE = ,
VK_CAPITAL = ,
VK_KANA = ,
VK_HANGUL = ,
VK_JUNJA = ,
VK_FINAL = ,
VK_HANJA = ,
VK_KANJI = ,
VK_ESCAPE = ,
VK_CONVERT = ,
VK_NONCONVERT = ,
VK_ACCEPT = ,
VK_MODECHANGE = ,
VK_SPACE = ,
VK_PRIOR = ,
VK_NEXT = ,
VK_END = ,
VK_HOME = ,
VK_LEFT = ,
VK_UP = ,
VK_RIGHT = ,
VK_DOWN = ,
VK_SELECT = ,
VK_PRINT = ,
VK_EXECUTE = ,
VK_SNAPSHOT = ,
VK_INSERT = ,
VK_DELETE = ,
VK_HELP = ,
VK_0 = ,
VK_1 = ,
VK_2 = ,
VK_3 = ,
VK_4 = ,
VK_5 = ,
VK_6 = ,
VK_7 = ,
VK_8 = ,
VK_9 = ,
VK_A = ,
VK_B = ,
VK_C = ,
VK_D = ,
VK_E = ,
VK_F = ,
VK_G = ,
VK_H = ,
VK_I = ,
VK_J = ,
VK_K = ,
VK_L = ,
VK_M = ,
VK_N = ,
VK_O = ,
VK_P = ,
VK_Q = ,
VK_R = ,
VK_S = ,
VK_T = ,
VK_U = ,
VK_V = ,
VK_W = ,
VK_X = ,
VK_Y = ,
VK_Z = ,
VK_LWIN = ,
VK_RWIN = ,
VK_APPS = ,
VK_SLEEP = ,
VK_NUMPAD0 = ,
VK_NUMPAD1 = ,
VK_NUMPAD2 = ,
VK_NUMPAD3 = ,
VK_NUMPAD4 = ,
VK_NUMPAD5 = ,
VK_NUMPAD6 = ,
VK_NUMPAD7 = ,
VK_NUMPAD8 = ,
VK_NUMPAD9 = ,
VK_MULTIPLY = ,
VK_ADD = ,
VK_SEPARATOR = ,
VK_SUBTRACT = ,
VK_DECIMAL = ,
VK_DIVIDE = ,
VK_F1 = ,
VK_F2 = ,
VK_F3 = ,
VK_F4 = ,
VK_F5 = ,
VK_F6 = ,
VK_F7 = ,
VK_F8 = ,
VK_F9 = ,
VK_F10 = ,
VK_F11 = ,
VK_F12 = ,
VK_F13 = ,
VK_F14 = ,
VK_F15 = ,
VK_F16 = ,
VK_F17 = ,
VK_F18 = ,
VK_F19 = ,
VK_F20 = ,
VK_F21 = ,
VK_F22 = ,
VK_F23 = ,
VK_F24 = ,
VK_NUMLOCK = ,
VK_SCROLL = ,
VK_LSHIFT = ,
VK_RSHIFT = ,
VK_LCONTROL = ,
VK_RCONTROL = ,
VK_LMENU = ,
VK_RMENU = ,
VK_BROWSER_BACK = ,
VK_BROWSER_FORWARD = ,
VK_BROWSER_REFRESH = ,
VK_BROWSER_STOP = ,
VK_BROWSER_SEARCH = ,
VK_BROWSER_FAVORITES = ,
VK_BROWSER_HOME = ,
VK_VOLUME_MUTE = ,
VK_VOLUME_DOWN = ,
VK_VOLUME_UP = ,
VK_MEDIA_NEXT_TRACK = ,
VK_MEDIA_PREV_TRACK = ,
VK_MEDIA_STOP = ,
VK_MEDIA_PLAY_PAUSE = ,
VK_LAUNCH_MAIL = ,
VK_LAUNCH_MEDIA_SELECT = ,
VK_LAUNCH_APP1 = ,
VK_LAUNCH_APP2 = ,
VK_OEM_1 = ,
VK_OEM_PLUS = ,
VK_OEM_COMMA = ,
VK_OEM_MINUS = ,
VK_OEM_PERIOD = ,
VK_OEM_2 = ,
VK_OEM_3 = ,
VK_OEM_4 = ,
VK_OEM_5 = ,
VK_OEM_6 = ,
VK_OEM_7 = ,
VK_OEM_8 = ,
VK_OEM_102 = ,
VK_PACKET = ,
VK_PROCESSKEY = ,
VK_ATTN = ,
VK_CRSEL = ,
VK_EXSEL = ,
VK_EREOF = ,
VK_PLAY = ,
VK_ZOOM = ,
VK_NONAME = ,
VK_PA1 = ,
VK_OEM_CLEAR =
}

C#-VirtualKeys

  虚拟键盘对象,提供一系列按键命令

  (在线工具转换,局部静态变量部分请参考 VB.NET 版本)

''' <summary>
''' 虚拟键盘,提供一系列按键命令
''' </summary>
Public Class VirtualKeyboard
Private Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Integer, ByVal dwExtraInfo As Integer)
Private Declare Function MapVirtualKey Lib "user32" Alias "MapVirtualKeyA" (ByVal wCode As Integer, ByVal wMapType As Integer) As Integer
Private Declare Function GetAsyncKeyState Lib "user32 " (ByVal vKey As Integer) As Integer
''' <summary>
''' 发送一组按键
''' </summary>
Public Shared Sub SendString(str As String, interval As Integer)
Dim strArr() As String = Split(str, ",")
For Each SubStr In strArr
If SubStr.First = "#" Then
System.Threading.Thread.Sleep(CInt(SubStr.Substring()))
Else
For Each SubChar As Char In SubStr
VirtualKeyDown(Asc(SubChar))
System.Threading.Thread.Sleep(interval)
VirtualKeyUp(Asc(SubChar))
Next
End If
Next
End Sub
''' <summary>
''' 发送一组扩展的按键
''' </summary>
Public Shared Sub SendStringEx(str As String, interval As Integer, ParamArray extra() As VirtualKeys)
For Each SubKey In extra
VirtualKeyDown(SubKey)
Next
SendString(str, interval)
For Each SubKey In extra
VirtualKeyUp(SubKey)
Next
End Sub
''' <summary>
''' 发送单个按键
''' </summary>
Public Shared Sub SendKey(vKey As VirtualKeys, interval As Integer)
VirtualKeyDown(vKey)
System.Threading.Thread.Sleep(interval)
VirtualKeyUp(vKey)
End Sub
''' <summary>
''' 同时发送两个按键
''' </summary>
Public Shared Sub SendCouple(vKey1 As VirtualKeys, vKey2 As VirtualKeys, interval As Integer)
VirtualKeyDown(vKey1)
VirtualKeyDown(vKey2)
System.Threading.Thread.Sleep(interval)
VirtualKeyUp(vKey1)
VirtualKeyUp(vKey2)
End Sub
''' <summary>
''' 获取A~Z的按键状态
''' </summary>
Public Shared Function GetActiveKey() As Byte
For i = To 'A~Z的ASICC码
If CurrentKeyState(i) = True Then
Return i
End If
Next
Return
End Function
''' <summary>
''' 获取键盘按键状态
''' </summary>
Private Shared Function CurrentKeyState(ByVal KeyCode As Byte) As Boolean
Static KeyState() As Boolean
Dim temp As Integer = GetAsyncKeyState(KeyCode)
If temp = Then
KeyState(KeyCode) = False
Else
If KeyState(KeyCode) = False Then
KeyState(KeyCode) = True
Return True
End If
KeyState(KeyCode) = True
Return False
End If
Return False
End Function
''' <summary>
''' 按下指定按键
''' </summary>
Private Shared Sub VirtualKeyDown(vKey As VirtualKeys)
keybd_event(vKey, MapVirtualKey(vKey, ), &H1 Or , ) '按下
End Sub
''' <summary>
''' 松开指定按键
''' </summary>
Private Shared Sub VirtualKeyUp(vKey As VirtualKeys)
keybd_event(vKey, MapVirtualKey(vKey, ), &H1 Or &H2, ) '弹起
End Sub
End Class

VB.NET-VirtualKeyboard

using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Runtime.InteropServices;
/// <summary>
/// 虚拟键盘,提供一系列按键命令
/// </summary>
public class VirtualKeyboard
{
[DllImport("user32", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
private static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);
[DllImport("user32", EntryPoint = "MapVirtualKeyA", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
private static extern int MapVirtualKey(int wCode, int wMapType);
[DllImport("user32 ", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
private static extern int GetAsyncKeyState(int vKey);
/// <summary>
/// 发送一组按键
/// </summary>
public static void SendString(string str, int interval)
{
string[] strArr = Strings.Split(str, ",");
foreach (void SubStr_loopVariable in strArr) {
SubStr = SubStr_loopVariable;
if (SubStr.First == "#") {
System.Threading.Thread.Sleep(Convert.ToInt32(SubStr.Substring()));
} else {
foreach (char SubChar in SubStr) {
VirtualKeyDown(Strings.Asc(SubChar));
System.Threading.Thread.Sleep(interval);
VirtualKeyUp(Strings.Asc(SubChar));
}
}
}
}
/// <summary>
/// 发送一组扩展的按键
/// </summary>
public static void SendStringEx(string str, int interval, params VirtualKeys[] extra)
{
foreach (void SubKey_loopVariable in extra) {
SubKey = SubKey_loopVariable;
VirtualKeyDown(SubKey);
}
SendString(str, interval);
foreach (void SubKey_loopVariable in extra) {
SubKey = SubKey_loopVariable;
VirtualKeyUp(SubKey);
}
}
/// <summary>
/// 发送单个按键
/// </summary>
public static void SendKey(VirtualKeys vKey, int interval)
{
VirtualKeyDown(vKey);
System.Threading.Thread.Sleep(interval);
VirtualKeyUp(vKey);
}
/// <summary>
/// 同时发送两个按键
/// </summary>
public static void SendCouple(VirtualKeys vKey1, VirtualKeys vKey2, int interval)
{
VirtualKeyDown(vKey1);
VirtualKeyDown(vKey2);
System.Threading.Thread.Sleep(interval);
VirtualKeyUp(vKey1);
VirtualKeyUp(vKey2);
}
/// <summary>
/// 获取A~Z的按键状态
/// </summary>
public static byte GetActiveKey()
{
//A~Z的ASICC码
for (i = ; i <= ; i++) {
if (CurrentKeyState(i) == true) {
return i;
}
}
return ;
}
static readonly Microsoft.VisualBasic.CompilerServices.StaticLocalInitFlag static_CurrentKeyState_KeyState_Init = new Microsoft.VisualBasic.CompilerServices.StaticLocalInitFlag();
/// <summary>
/// 获取键盘按键状态
/// </summary>
static bool[] static_CurrentKeyState_KeyState;
private static bool CurrentKeyState(byte KeyCode)
{
lock (static_CurrentKeyState_KeyState_Init) {
try {
if (InitStaticVariableHelper(static_CurrentKeyState_KeyState_Init)) {
static_CurrentKeyState_KeyState = new bool[];
}
} finally {
static_CurrentKeyState_KeyState_Init.State = ;
}
}
int temp = GetAsyncKeyState(KeyCode);
if (temp == ) {
static_CurrentKeyState_KeyState(KeyCode) = false;
} else {
if (static_CurrentKeyState_KeyState(KeyCode) == false) {
static_CurrentKeyState_KeyState(KeyCode) = true;
return true;
}
static_CurrentKeyState_KeyState(KeyCode) = true;
return false;
}
return false;
}
/// <summary>
/// 按下指定按键
/// </summary>
private static void VirtualKeyDown(VirtualKeys vKey)
{
keybd_event(vKey, MapVirtualKey(vKey, ), 0x1 | , );
//按下
}
/// <summary>
/// 松开指定按键
/// </summary>
private static void VirtualKeyUp(VirtualKeys vKey)
{
keybd_event(vKey, MapVirtualKey(vKey, ), 0x1 | 0x2, );
//弹起
}
static bool InitStaticVariableHelper(Microsoft.VisualBasic.CompilerServices.StaticLocalInitFlag flag)
{
if (flag.State == ) {
flag.State = ;
return true;
} else if (flag.State == ) {
throw new Microsoft.VisualBasic.CompilerServices.IncompleteInitialization();
} else {
return false;
}
}
}

C#-VirtualKeyboard

附录

  GitHub:AutoHotKey.NET (已失效)