前言

  通过 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 (已失效)

[VB.NET][C#]调用API获取或设置键盘按键状态的更多相关文章

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

    1.调用GetAsyncKeyState()获取指定按键的状态,GetActiveKey()检索指定范围内的按键状态 2.调用keybd_event()可合成一次击键事件,通常两次击键事件间需要设定时 ...

  2. 在C#中调用API获取网络信息和流量

    原文 在C#中调用API获取网络信息和流量 最近一项目中要求显示网络流量,而且必须使用C#. 事实上,调用 IpHlpApi.dll 的 GetIfTable API 可以轻易获得网络信息和网络流量. ...

  3. js获取及判断键盘按键的方法

    这篇文章主要介绍了js获取及判断键盘按键的方法,涉及JavaScript键盘事件的获取及键值的判定技巧,具有一定参考借鉴价值,需要的朋友可以参考下   本文实例讲述了js获取及判断键盘按键的方法.分享 ...

  4. [VC6 console]调用API获取手机归属地

    为了完成作业,就偷个懒糊了个获取手机归属地的程序,.我原本写的是MFC版本的,但是由于MFC的代码不是很通用,加上我没有学MFC的时候看别人MFC代码只能干瞪眼,看不懂,所以便改成控制台版本的了.但这 ...

  5. vb.net 动态调用api

    Imports System Imports System.Runtime.InteropServices Public Class DllInvoke Public Sub New(ByVal DL ...

  6. C++调用API获取当前时间

    #include <string> #include<iostream> #include<windows.h> #include <sstream> ...

  7. 第七篇:使用 fcntl 函数 获取,设置文件的状态标志

    前言 当打开一个文件的时候,我们需要指定打开文件的模式( 只读,只写等 ).那么在程序中如何获取,修改这个文件的状态标志呢? 本文将告诉你如何用 fcntl函数 获取指定文件的状态标志. 解决思路 1 ...

  8. 使用 fcntl 函数 获取,设置文件的状态标志

    前言 当打开一个文件的时候,我们需要指定打开文件的模式( 只读,只写等 ).那么在程序中如何获取,修改这个文件的状态标志呢?本文将告诉你如何用 fcntl函数 获取指定文件的状态标志. 解决思路 1. ...

  9. 高德地图API获取天气

    1.建立行政区规划清单表 use edw; drop table if exists dim_prov_city_adcode; create table if not exists dim_prov ...

随机推荐

  1. JDBC方式执行SQL,支持CRUD返回LIST

    背景: 用惯了Mybatis,接收一个老项目使用Hibernate,特别不习惯.新的功能需要系统后台定时执行任务,顾使用JDBC封装工具类执行 源代码 import java.sql.Connecti ...

  2. win10 虚拟机 hyper-v 安装 centos 7

    一.win 10 企业版 自带虚拟机 hyper-v 1.控制面板-->程序和功能-->启用或关闭Windows功能 勾上 hyper-v 确定就ok了 2.安装成功后会发现在 左下角“开 ...

  3. zabbix3.4 修改监控范围

    需求:一段时间内不监控主机的流量(不告警!!!)

  4. Java基础加强之并发(三)Thread中start()和run()的区别

    Thread中start()和run()的区别 start() : 它的作用是启动一个新线程,新线程会执行相应的run()方法.start()不能被重复调用.run()   : run()就和普通的成 ...

  5. kubernetes API Server 权限管理实践

    API Server权限控制方式介绍 API Server权限控制分为三种:Authentication(身份认证).Authorization(授权).AdmissionControl(准入控制). ...

  6. ZCMU 1019: 分金币

    解题思路: 附上刘汝佳老师的解题过程: 首先最终每个人的金币数量可以计算出来,它等于金币总数除以人数n.接下来用M来表示每个人最终拥有的金币数. 现在假设编号为 i 的人初始有Ai 枚金币,对于1号来 ...

  7. Linux Shell常用技巧(五)

    十一.  awk编程:    1.  变量:    在awk中变量无须定义即可使用,变量在赋值时即已经完成了定义.变量的类型可以是数字.字符串.根据使用的不同,未初始化变量的值为0或空白字符串&quo ...

  8. N项阶乘累加求和新算法

    pdf原版链接

  9. Centos7 yum安装Mysql5.7

    1.下载mysql安装源 curl -LO http://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm 2.安装yum源 ...

  10. node vue 开发环境部署时,外部访问页面出现: Invalid Host header 服务器域名访问出现的问题

    这是新版本 webpack-dev-server  出于安全考虑, 默认检查 hostname,如果hostname不是配置内的,将中断访问.顾仅存在于开发环境: npm run dev,打包之后不会 ...