public partial class Form1 : Form
[DllImport("user32.dll", EntryPoint = "keybd_event", SetLastError = true)]
public static extern void keybd_event(Keys bVk, byte bScan, uint dwFlags, uint dwExtraInfo);
private IKeyboardMouseEvents m_GlobalHook;
int x_tmp;
int y_tmp;
public Form1()
InitializeComponent();
Control.CheckForIllegalCrossThreadCalls = false;
Subscribe();
public void Subscribe()
// Note: for the application hook, use the Hook.AppEvents() instead
m_GlobalHook = Hook.GlobalEvents();
m_GlobalHook.MouseMoveExt += M_GlobalHook_MouseMoveExt;
private void M_GlobalHook_MouseMoveExt(object sender, MouseEventExtArgs e)
label1.Text = e.X.ToString() + "," + e.Y.ToString();
if (e.X > x_tmp) {label2.Text = "→"; keybd_event(Keys.D, 0, 0, 0); }
if (e.X < x_tmp) {label2.Text = "←"; ; keybd_event(Keys.A, 0, 0, 0);}
if (e.Y < y_tmp) {label4.Text = "↑";; keybd_event(Keys.W, 0, 0, 0);}
if (e.Y > y_tmp) {label4.Text = "↓";; keybd_event(Keys.S, 0, 0, 0);}
x_tmp = e.X;
y_tmp = e.Y;
但FBA V2.4.0 版本的游戏模拟器油盐不进,对它发消息,它没有反应,SPY++看不到它的任何消息。今天晚上时间不够了,就研究到这里。
------2022.2.20------
仔细看了一下,是SPY++64位32位的问题,确认可以收到消息后,模拟键盘按键给FBA发了键盘消息。又出现了新问题,SPY++可以看到程序发给FBA的消息和实际的消息完全一样,但是FBA不能识别。
可能是因为FBA使用了DIRECTX INPUT,一般的模拟键盘消息对它无效,程序也尝试了线程挂接,只是没再进一步使用HOOK注入。
找到一个WINIO方法,据说可以对付DIRECTX INPUT不识别消息的顽症。
C#的例子程序写的很完整,但是WINIO32.DLL居然网上下载不到,文章地址:
一个C#写的模拟键盘输入的例子_lucky811的专栏-CSDN博客
那么,后面还需要找一个WIN10,VS2019环境下可以使用WINIO32.DLL的DEMO。
-------2022.2.25-----------
WINIO32.DLL这条路不通,在百度搜索 directx input 模拟键盘,在知乎上有个回答,还有一个是WIN10场景最新的场景。看来可行。
-------2022.2.26-----------
今天终于成功了
,用右手控制鼠标控制了一下飞机,但是要达到极致体验,程序还需要调试一下,让鼠标的移动跟上飞机。比如:一个方向一个线程,因为程序只会傻填键盘缓冲区,四个方向都是单独线程控制才比较合理。
全部的C# 代码如下(鼠标中键工作,右键停止):
using Gma.System.MouseKeyHook;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace GetMousePoint
public partial class Form1 : Form
[DllImport("user32.dll")] static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")] static extern bool SetForegroundWindow(IntPtr hWnd);
//----------------------------------------------------------------------
[DllImport("user32 ")]
private static extern IntPtr EnumChildWindows(int hWndParent, EnumWindowsProc lpEnumFunc, int lParam);
public delegate bool EnumWindowsProc(int hWnd, int lParam);
[DllImport("user32.dll", EntryPoint = "GetClassName")]
public static extern int GetClassName(int hWnd, StringBuilder lpString, int nMaxCont);
[DllImport("User32.dll")]
static extern int GetWindowText(IntPtr handle, StringBuilder text, int MaxLen);
//------------------------------------------------------------------------
[DllImport("user32.dll", EntryPoint = "keybd_event", SetLastError = true)]
public static extern void keybd_event(Keys bVk, byte bScan, uint dwFlags, uint dwExtraInfo);
[DllImport("user32.dll")]
static extern byte MapVirtualKey(byte wCode, int wMap);
public static List<WinObject> ListWin = new List<WinObject>();
private IKeyboardMouseEvents m_GlobalHook;
int x_tmp;
int y_tmp;
int mouse_x = 0;
int mouse_y = 0;
bool IsOpen = false;
MouseEventExtArgs gv_e;
public Form1()
InitializeComponent();
//加载全局钩子
Subscribe();
Control.CheckForIllegalCrossThreadCalls = false;
Thread t11 = new Thread(new ThreadStart(Worker11));
t11.Start();
Thread t12 = new Thread(new ThreadStart(Worker12));
t12.Start();
Thread t13 = new Thread(new ThreadStart(Worker13));
t13.Start();
Thread t14 = new Thread(new ThreadStart(Worker14));
t14.Start();
Thread t2 = new Thread(new ThreadStart(Worker2));
t2.Start();
Thread t3 = new Thread(new ThreadStart(Worker3));
t3.Start();
label1.Text = gv_e.X.ToString() + "," + gv_e.Y.ToString();
if (gv_e.X > x_tmp) { label2.Text = "→"; mouse_x = 1; }
if (gv_e.X == x_tmp) { label2.Text = "0"; mouse_x = 0; }
if (gv_e.X < x_tmp) { label2.Text = "←"; mouse_x = -1; }
x_tmp = gv_e.X;
public void Worker3()
while (true)
Thread.Sleep(100);
if (gv_e != null)
if (gv_e.Y < y_tmp) { label4.Text = "↑"; mouse_y = 1; }
if (gv_e.Y == y_tmp) { label4.Text = "0"; mouse_y = 0; }
if (gv_e.Y > y_tmp) { label4.Text = "↓"; mouse_y = -1; }
y_tmp = gv_e.Y;
public void Subscribe()
// Note: for the application hook, use the Hook.AppEvents() instead
m_GlobalHook = Hook.GlobalEvents();
m_GlobalHook.MouseMoveExt += M_GlobalHook_MouseMoveExt;
m_GlobalHook.MouseClick += M_GlobalHook_MouseClick;
private void M_GlobalHook_MouseClick(object sender, MouseEventArgs e)
if (e.Button == MouseButtons.Middle)
EnumChildWindows(0, new EnumWindowsProc(EnumWindowCallBack), 0);
if (ListWin.Count > 0) { label6.Text = "locked windows"; }
SetForegroundWindow(ListWin.FirstOrDefault().hand);
IsOpen = true;
label3.Text = "IsOpen: true";
if (e.Button == MouseButtons.Right)
IsOpen = false;
label3.Text = "IsOpen: false";
label6.Text = "UnLocked windows";
private void M_GlobalHook_MouseMoveExt(object sender, MouseEventExtArgs e)
gv_e = e;
private void MyKey(System.Windows.Forms.Keys x)
keybd_event(x, (byte)MapVirtualKey(Convert.ToByte(x), 0), 0, 0);
Thread.Sleep(5);
keybd_event(x, (byte)MapVirtualKey(Convert.ToByte(x), 0), 0x0002, 0);
public class WinObject
public bool isprocess { get; set; }
public IntPtr hand { get; set; }
public string ClassName { get; set; }
public string text { get; set; }
public static bool EnumWindowCallBack(int hWnd, int lParam)
WinObject one = new WinObject();
one.isprocess = false;
one.hand = (IntPtr)hWnd;
StringBuilder name = new StringBuilder(256);
GetClassName(hWnd, name, 256);
one.ClassName = name.ToString();
StringBuilder text = new StringBuilder(100);
GetWindowText((IntPtr)hWnd, text, 100);
one.text = text.ToString();
if (one.ClassName.Equals("FBA shuffle"))
ListWin.Add(one);
catch { }
return true;
有一些使用DirectX接口的游戏程序,它们在读取键盘操作时绕过了windows的消息机制,而使用DirectInput.这是因为有些游戏对实时性控制的要求比较高,比如赛车游戏,要求以最快速度响应键盘输入。而windows消息由于是队列形式的,消息在传递时会有不少延迟,有时1秒钟也就传递十几条消息,这个速度达不到游戏的要求。而DirectInput则绕过了windows消息,直接与键盘驱动程序打交
Welcome to hLibrary. Here you can find loads of tutorials, downloads, and tools that can help you satisfy all of your programming and hacking needs.
Welcome Penn[Sign Out]
Preferences
Change
//2018.6.15至于为什么想做这个,相信每个看改文章的人都知道,而且目的还会有所不同,先记录下。首先,本来想要模拟按键,使用winapi的hook但是,并不能成功实现鼠标钩子函数。查阅相关资料,因为DirectX游戏是利用DirectInput绕过Windows的消息机制直接和硬件打交道来接收按键信息的。因此,我们必须使用驱动级别的模拟按键。百度过程中,发现了winio,网传此为开源代码,官...
*碰到DX游戏SendMessage 和PostMessage是没办法使用模拟键盘鼠标操作的,这时候我们可以用WinIO的SendInput把键盘鼠标消息放到消息队列里面去实现 代码如下:
模拟鼠标
int SuccessAction1, SuccessAction2, SuccessAction3;
INPUT MouseInput[3];
int x=200,y=200;...
键盘模拟最近下载了《红警3:起义》,发现一个问题:不能连续用键盘按键。于是在制造装备时只能不停的点击鼠标。或者不停的按键盘的快捷键——而且每按下一次键必须松开,不能按下不放。于是想写一个程序,在按下相应键时,向指定窗口模拟发送消息,以造成不停按下、松开的效果。在写程序之前,先了解一下键盘的几个消息:WM_KEYDOWN/WM_KEYUP/WM_CHAR。1.键盘的两个消息:a.WM_KEYDO
二、实现原理
在windows下模拟鼠标的话,咨询Win32各种库吧,这里python中对应的库就是pywin32库啦。
http://sourceforge.net/projects/pywin32/
下载安装后
前段时间花了点时间研究directx9,写了点代码,在这里做个记录。 以下是自己封装的keyboard的代码: cKbState类,保存每次查询的键盘按键信息,提供某个键被按下等查询。 首先是cKbState.h // cKbState.h: interface for the cKbState class.//////////////////////
设备初始化需要GUID,
所有枚举所有设备,由于我的游戏手柄只有1个,所有只取一个GUID
Guid id = new Guid(); foreach (DeviceInstance di in Manager.Get...
< DOCTYPE HTML PUBLIC -WCDTD HTML TransitionalEN> MFC 工程 把以下代码放到你想要响应的函数里面就行 CPoint pt; GetCursorPos(&pt);//获取鼠标在屏幕的当前位置SetCurso...