关键词搜索

源码搜索 ×
×

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

发布2022-06-19浏览1268次

详情内容

vb.net教程https://www.xin3721.com/eschool/vbnetxin3721/

前言

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

第一节 调用接口

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

  获取按键状态

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

  合成击键事件

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

  对 DirectInput 有效

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

第二节 帮助类

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

  虚拟键码枚举

''' <summary>
''' 虚拟键码枚举
''' </summary>
Public Enum VirtualKeys
    VK_LBUTTON = 1
    VK_RBUTTON = 2
    VK_CANCEL = 3
    VK_MBUTTON = 4
    VK_XBUTTON1 = 5
    VK_XBUTTON2 = 6
    VK_BACK = 8
    VK_TAB = 9
    VK_CLEAR = 12
    VK_RETURN = 13
    VK_SHIFT = 16
    VK_CONTROL = 17
    VK_MENU = 18
    VK_PAUSE = 19
    VK_CAPITAL = 20
    VK_KANA = 21
    VK_HANGUL = 21
    VK_JUNJA = 23
    VK_FINAL = 24
    VK_HANJA = 25
    VK_KANJI = 26
    VK_ESCAPE = 27
    VK_CONVERT = 28
    VK_NONCONVERT = 29
    VK_ACCEPT = 30
    VK_MODECHANGE = 31
    VK_SPACE = 32
    VK_PRIOR = 33
    VK_NEXT = 34
    VK_END = 35
    VK_HOME = 36
    VK_LEFT = 37
    VK_UP = 38
    VK_RIGHT = 39
    VK_DOWN = 40
    VK_SELECT = 41
    VK_PRINT = 42
    VK_EXECUTE = 43
    VK_SNAPSHOT = 44
    VK_INSERT = 45
    VK_DELETE = 46
    VK_HELP = 47
    VK_0 = 48
    VK_1 = 49
    VK_2 = 50
    VK_3 = 51
    VK_4 = 52
    VK_5 = 53
    VK_6 = 54
    VK_7 = 55
    VK_8 = 56
    VK_9 = 57
    VK_A = 65
    VK_B = 66
    VK_C = 67
    VK_D = 68
    VK_E = 69
    VK_F = 70
    VK_G = 71
    VK_H = 72
    VK_I = 73
    VK_J = 74
    VK_K = 75
    VK_L = 76
    VK_M = 77
    VK_N = 78
    VK_O = 79
    VK_P = 80
    VK_Q = 81
    VK_R = 82
    VK_S = 83
    VK_T = 84
    VK_U = 85
    VK_V = 86
    VK_W = 87
    VK_X = 88
    VK_Y = 89
    VK_Z = 90
    VK_LWIN = 91
    VK_RWIN = 92
    VK_APPS = 93
    VK_SLEEP = 95
    VK_NUMPAD0 = 96
    VK_NUMPAD1 = 97
    VK_NUMPAD2 = 98
    VK_NUMPAD3 = 99
    VK_NUMPAD4 = 100
    VK_NUMPAD5 = 101
    VK_NUMPAD6 = 102
    VK_NUMPAD7 = 103
    VK_NUMPAD8 = 104
    VK_NUMPAD9 = 105
    VK_MULTIPLY = 106
    VK_ADD = 107
    VK_SEPARATOR = 108
    VK_SUBTRACT = 109
    VK_DECIMAL = 110
    VK_DIVIDE = 111
    VK_F1 = 112
    VK_F2 = 113
    VK_F3 = 114
    VK_F4 = 115
    VK_F5 = 116
    VK_F6 = 117
    VK_F7 = 118
    VK_F8 = 119
    VK_F9 = 120
    VK_F10 = 121
    VK_F11 = 122
    VK_F12 = 123
    VK_F13 = 124
    VK_F14 = 125
    VK_F15 = 126
    VK_F16 = 127
    VK_F17 = 128
    VK_F18 = 129
    VK_F19 = 130
    VK_F20 = 131
    VK_F21 = 132
    VK_F22 = 133
    VK_F23 = 134
    VK_F24 = 135
    VK_NUMLOCK = 144
    VK_SCROLL = 145
    VK_LSHIFT = 160
    VK_RSHIFT = 161
    VK_LCONTROL = 162
    VK_RCONTROL = 163
    VK_LMENU = 164
    VK_RMENU = 165
    VK_BROWSER_BACK = 166
    VK_BROWSER_FORWARD = 167
    VK_BROWSER_REFRESH = 168
    VK_BROWSER_STOP = 169
    VK_BROWSER_SEARCH = 170
    VK_BROWSER_FAVORITES = 171
    VK_BROWSER_HOME = 172
    VK_VOLUME_MUTE = 173
    VK_VOLUME_DOWN = 174
    VK_VOLUME_UP = 175
    VK_MEDIA_NEXT_TRACK = 176
    VK_MEDIA_PREV_TRACK = 177
    VK_MEDIA_STOP = 178
    VK_MEDIA_PLAY_PAUSE = 179
    VK_LAUNCH_MAIL = 180
    VK_LAUNCH_MEDIA_SELECT = 181
    VK_LAUNCH_APP1 = 182
    VK_LAUNCH_APP2 = 183
    VK_OEM_1 = 186
    VK_OEM_PLUS = 187
    VK_OEM_COMMA = 188
    VK_OEM_MINUS = 189
    VK_OEM_PERIOD = 190
    VK_OEM_2 = 191
    VK_OEM_3 = 192
    VK_OEM_4 = 219
    VK_OEM_5 = 220
    VK_OEM_6 = 221
    VK_OEM_7 = 222
    VK_OEM_8 = 223
    VK_OEM_102 = 226
    VK_PACKET = 231
    VK_PROCESSKEY = 229
    VK_ATTN = 246
    VK_CRSEL = 247
    VK_EXSEL = 248
    VK_EREOF = 249
    VK_PLAY = 250
    VK_ZOOM = 251
    VK_NONAME = 252
    VK_PA1 = 253
    VK_OEM_CLEAR = 254
End Enum

/// <summary>
/// 虚拟键码枚举
/// </summary>
public enum VirtualKeys
{
    VK_LBUTTON = 1,
    VK_RBUTTON = 2,
    VK_CANCEL = 3,
    VK_MBUTTON = 4,
    VK_XBUTTON1 = 5,
    VK_XBUTTON2 = 6,
    VK_BACK = 8,
    VK_TAB = 9,
    VK_CLEAR = 12,
    VK_RETURN = 13,
    VK_SHIFT = 16,
    VK_CONTROL = 17,
    VK_MENU = 18,
    VK_PAUSE = 19,
    VK_CAPITAL = 20,
    VK_KANA = 21,
    VK_HANGUL = 21,
    VK_JUNJA = 23,
    VK_FINAL = 24,
    VK_HANJA = 25,
    VK_KANJI = 26,
    VK_ESCAPE = 27,
    VK_CONVERT = 28,
    VK_NONCONVERT = 29,
    VK_ACCEPT = 30,
    VK_MODECHANGE = 31,
    VK_SPACE = 32,
    VK_PRIOR = 33,
    VK_NEXT = 34,
    VK_END = 35,
    VK_HOME = 36,
    VK_LEFT = 37,
    VK_UP = 38,
    VK_RIGHT = 39,
    VK_DOWN = 40,
    VK_SELECT = 41,
    VK_PRINT = 42,
    VK_EXECUTE = 43,
    VK_SNAPSHOT = 44,
    VK_INSERT = 45,
    VK_DELETE = 46,
    VK_HELP = 47,
    VK_0 = 48,
    VK_1 = 49,
    VK_2 = 50,
    VK_3 = 51,
    VK_4 = 52,
    VK_5 = 53,
    VK_6 = 54,
    VK_7 = 55,
    VK_8 = 56,
    VK_9 = 57,
    VK_A = 65,
    VK_B = 66,
    VK_C = 67,
    VK_D = 68,
    VK_E = 69,
    VK_F = 70,
    VK_G = 71,
    VK_H = 72,
    VK_I = 73,
    VK_J = 74,
    VK_K = 75,
    VK_L = 76,
    VK_M = 77,
    VK_N = 78,
    VK_O = 79,
    VK_P = 80,
    VK_Q = 81,
    VK_R = 82,
    VK_S = 83,
    VK_T = 84,
    VK_U = 85,
    VK_V = 86,
    VK_W = 87,
    VK_X = 88,
    VK_Y = 89,
    VK_Z = 90,
    VK_LWIN = 91,
    VK_RWIN = 92,
    VK_APPS = 93,
    VK_SLEEP = 95,
    VK_NUMPAD0 = 96,
    VK_NUMPAD1 = 97,
    VK_NUMPAD2 = 98,
    VK_NUMPAD3 = 99,
    VK_NUMPAD4 = 100,
    VK_NUMPAD5 = 101,
    VK_NUMPAD6 = 102,
    VK_NUMPAD7 = 103,
    VK_NUMPAD8 = 104,
    VK_NUMPAD9 = 105,
    VK_MULTIPLY = 106,
    VK_ADD = 107,
    VK_SEPARATOR = 108,
    VK_SUBTRACT = 109,
    VK_DECIMAL = 110,
    VK_DIVIDE = 111,
    VK_F1 = 112,
    VK_F2 = 113,
    VK_F3 = 114,
    VK_F4 = 115,
    VK_F5 = 116,
    VK_F6 = 117,
    VK_F7 = 118,
    VK_F8 = 119,
    VK_F9 = 120,
    VK_F10 = 121,
    VK_F11 = 122,
    VK_F12 = 123,
    VK_F13 = 124,
    VK_F14 = 125,
    VK_F15 = 126,
    VK_F16 = 127,
    VK_F17 = 128,
    VK_F18 = 129,
    VK_F19 = 130,
    VK_F20 = 131,
    VK_F21 = 132,
    VK_F22 = 133,
    VK_F23 = 134,
    VK_F24 = 135,
    VK_NUMLOCK = 144,
    VK_SCROLL = 145,
    VK_LSHIFT = 160,
    VK_RSHIFT = 161,
    VK_LCONTROL = 162,
    VK_RCONTROL = 163,
    VK_LMENU = 164,
    VK_RMENU = 165,
    VK_BROWSER_BACK = 166,
    VK_BROWSER_FORWARD = 167,
    VK_BROWSER_REFRESH = 168,
    VK_BROWSER_STOP = 169,
    VK_BROWSER_SEARCH = 170,
    VK_BROWSER_FAVORITES = 171,
    VK_BROWSER_HOME = 172,
    VK_VOLUME_MUTE = 173,
    VK_VOLUME_DOWN = 174,
    VK_VOLUME_UP = 175,
    VK_MEDIA_NEXT_TRACK = 176,
    VK_MEDIA_PREV_TRACK = 177,
    VK_MEDIA_STOP = 178,
    VK_MEDIA_PLAY_PAUSE = 179,
    VK_LAUNCH_MAIL = 180,
    VK_LAUNCH_MEDIA_SELECT = 181,
    VK_LAUNCH_APP1 = 182,
    VK_LAUNCH_APP2 = 183,
    VK_OEM_1 = 186,
    VK_OEM_PLUS = 187,
    VK_OEM_COMMA = 188,
    VK_OEM_MINUS = 189,
    VK_OEM_PERIOD = 190,
    VK_OEM_2 = 191,
    VK_OEM_3 = 192,
    VK_OEM_4 = 219,
    VK_OEM_5 = 220,
    VK_OEM_6 = 221,
    VK_OEM_7 = 222,
    VK_OEM_8 = 223,
    VK_OEM_102 = 226,
    VK_PACKET = 231,
    VK_PROCESSKEY = 229,
    VK_ATTN = 246,
    VK_CRSEL = 247,
    VK_EXSEL = 248,
    VK_EREOF = 249,
    VK_PLAY = 250,
    VK_ZOOM = 251,
    VK_NONAME = 252,
    VK_PA1 = 253,
    VK_OEM_CLEAR = 254
}

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

  (在线工具转换,局部静态变量部分请参考 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(1)))
            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 = 65 To 90 'A~Z的ASICC码
            If CurrentKeyState(i) = True Then
                Return i
            End If
        Next
        Return 0
    End Function
    ''' <summary>
    ''' 获取键盘按键状态
    ''' </summary>
    Private Shared Function CurrentKeyState(ByVal KeyCode As Byte) As Boolean
        Static KeyState(255) As Boolean
        Dim temp As Integer = GetAsyncKeyState(KeyCode)
        If temp = 0 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, 0), &H1 Or 0, 0) '按下
    End Sub
    ''' <summary>
    ''' 松开指定按键
    ''' </summary>
    Private Shared Sub VirtualKeyUp(vKey As VirtualKeys)
        keybd_event(vKey, MapVirtualKey(vKey, 0), &H1 Or &H2, 0) '弹起
    End Sub
End Class

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(1)));
            } 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 = 65; i <= 90; i++) {
            if (CurrentKeyState(i) == true) {
                return i;
            }
        }
        return 0;
    }
    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[256];
                }
            } finally {
                static_CurrentKeyState_KeyState_Init.State = 1;
            }
        }
        int temp = GetAsyncKeyState(KeyCode);
        if (temp == 0) {
            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, 0), 0x1 | 0, 0);
        //按下
    }
    /// <summary>
    /// 松开指定按键
    /// </summary>
    private static void VirtualKeyUp(VirtualKeys vKey)
    {
        keybd_event(vKey, MapVirtualKey(vKey, 0), 0x1 | 0x2, 0);
        //弹起
    }
    static bool InitStaticVariableHelper(Microsoft.VisualBasic.CompilerServices.StaticLocalInitFlag flag)
    {
        if (flag.State == 0) {
            flag.State = 2;
            return true;
        } else if (flag.State == 2) {
            throw new Microsoft.VisualBasic.CompilerServices.IncompleteInitialization();
        } else {
            return false;
        }
    }
}

相关技术文章

点击QQ咨询
开通会员
返回顶部
×
微信扫码支付
微信扫码支付
确定支付下载
请使用微信描二维码支付
×

提示信息

×

选择支付方式

  • 微信支付
  • 支付宝付款
确定支付下载