前言

  通过 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]调用API获取/设置键盘按键状态的更多相关文章

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

    前言 通过 C# 或 VB.NET,你只需编写少量的代码即可实现一个按键精灵. 第一节 接口 调用系统 API 实现获取或设置指定的按键状态. 获取按键状态 调用 GetAsyncKeyState() ...

  2. Unity3D获取当前键盘按键

    获取当前键盘按键,代码如下: using UnityEngine; using System.Collections; public class GetCurrentKey : MonoBehavio ...

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

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

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

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

  5. vb.net 调用api

    Public Declare Function GetDC Lib "user32" Alias "GetDC" (ByVal hwnd As Integer) ...

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

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

  7. 通过 Windows API 获取鼠标位置等状态信息

    #include <graphics.h> #include <stdio.h> void main() { initgraph(, ); // 初始化绘图窗口 HWND hw ...

  8. 高德地图API获取天气

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

  9. PHP通过Zabbix API获取服务器监控信息

    开源监控系统Zabbix提供了丰富的API,供第三方系统调用. 基本步骤如下: 1.获取合法认证:连接对应Zabbix URL,并提供用户名和密码,HTTP方法为"POST",HT ...

随机推荐

  1. pyserial 16进制显示与发送

    pyserial 16进制显示与发送 http://www.centoscn.com/python/2013/0817/1320.html 十六进制显示的实质是把接收到的字符诸葛转换成其对应的ASCI ...

  2. LINUX 下时间转换为秒数

    linux下时间是从1970.1.1开始算的秒数 //转来自网址 http://blog.csdn.net/wind19/article/details/6579495 $ dateTue Feb 3 ...

  3. Css 相关资源(本篇不定期更新)

    http://www.tuicool.com/articles/3eaINn---<终于搞懂了CSS实现三角形图标的原理>---☆☆☆☆☆.这篇讲的是css中的如何挤出一个三角形,这个讲的 ...

  4. SQL Server 变更数据捕获(CDC)监控表数据

    一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 实现过程(Realization) 补充说明(Addon) 参考文献(References) ...

  5. 禁用SQL Server Management Studio的IntelliSense

    禁用SQL Server Management Studio的IntelliSense 本文版权归作者所有,未经作者同意不得转载.

  6. 删除Mysql数据表中多余的重复记录的sql语句

    数据表 sniper_tb 中存在主键 id,字段url,现需要在url字段上添加 unique,但由于url存在重复记录,导致添加失败. 如何删除表中多余的url重复记录,仅保持一条? 思路一 将 ...

  7. Hadoop学习笔记—1.基本介绍与环境配置

    一.Hadoop的发展历史 说到Hadoop的起源,不得不说到一个传奇的IT公司—全球IT技术的引领者Google.Google(自称)为云计算概念的提出者,在自身多年的搜索引擎业务中构建了突破性的G ...

  8. 迷你MVVM框架 avalonjs 实现上的几个难点

    经过两个星期的性能优化,avalon终于实现在一个页面绑定达到上万个的时候不卡顿的目标(angular的限制是2000).现在稍作休息,总结一下avalon遇到的一些难题. 首先是如何监控的问题.所有 ...

  9. [nRF51822] 10、基础实验代码解析大全 · 实验15 - RTC

    一.实验内容: 配置NRF51822 的RTC0 的TICK 频率为8Hz,COMPARE0 匹配事件触发周期为3 秒,并使能了TICK 和COMPARE0 中断. TICK 中断中驱动指示灯D1 翻 ...

  10. ASP.NET MVC 过滤器(五)

    ASP.NET MVC 过滤器(五) 前言 上篇对了行为过滤器的使用做了讲解,如果在控制器行为的执行中遇到了异常怎么办呢?没关系,还好框架给我们提供了异常过滤器,在本篇中将会对异常过滤器的使用做一个大 ...