老话重提。
整个论坛都搜索过了有很多关于《WinKawaks》(一款街机PC模拟器程序)的模拟按键问题都没得到相应的解决。现在的问题是这样,有个a.exe进程,一个b.exe进程。
a.exe进程是WinKawaks。b.exe进程是我们自己的程序。
怎么通过自己程序的逻辑往a.exe程序发送一个按键的操作呢?比如“A”键,键值:"65"Windows API的三种方法
PostMessage
SendMessage
keybd_event
都试过了没有用。驱动级的WinIo.dll也试过了也没有用。高手在哪啊?出来解决问题啦。
整个论坛都搜索过了有很多关于《WinKawaks》(一款街机PC模拟器程序)的模拟按键问题都没得到相应的解决。现在的问题是这样,有个a.exe进程,一个b.exe进程。
a.exe进程是WinKawaks。b.exe进程是我们自己的程序。
怎么通过自己程序的逻辑往a.exe程序发送一个按键的操作呢?比如“A”键,键值:"65"Windows API的三种方法
PostMessage
SendMessage
keybd_event
都试过了没有用。驱动级的WinIo.dll也试过了也没有用。高手在哪啊?出来解决问题啦。
搜下CHAR转10进制
using System.Runtime.InteropServices;//添加引用
[DllImport("USER32.DLL")]
public static extern IntPtr FindWindow(string lpClassName,
string lpWindowName);//调用FindWindow来激活窗体 [DllImport("USER32.DLL")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
private void button1_Click(object sender, EventArgs e)
{
IntPtr calculatorHandle = FindWindow(null,"计算器");
if (calculatorHandle == IntPtr.Zero)
{
MessageBox.Show("Calculator is not running.");
return;
}
try
{
SetForegroundWindow(calculatorHandle);//将计算器窗口置前 SendKeys.SendWait("2"); //发送
Thread.Sleep(10);
SendKeys.SendWait("*");
Thread.Sleep(10);
SendKeys.SendWait("3");
Thread.Sleep(10);
SendKeys.SendWait("=");
}
catch (Exception ex)
{
throw ex;
}
}打开系统的计算器试试。
由于没有激活另一个应用程序的托管方法,因此必须使用本机 Windows 方法强制将焦点放在其他应用程序上摘自MSDN
而WinKawaks是用DXInput了。直接跳过了windows消息层。
敢问一句,查MSDN了么?上面的代码测试了么?
楼上的朋友要是也非常有兴趣可以下载
http://down.paopaoche.net:226/moni/dino.rar
这是模拟器程序,里面自带一款游戏,模拟器可设置投币按键。
然后你试试程序可否向这个窗体投递消息。
我现在PostMessage 100 101 102 过去 A键值“65” 投递过去有反映,但是被WinKawaks给拦截了,弹出个信息框内容“KEY:65”。
假如我要从工具发送F2到游戏窗体, 游戏拦截sendmessage 不响应
但是在游戏里按F2是可以的
于是用OlyDbg打开, bp send, 按下F2跟进去
找到F2的call地址
然后从工具里hook到游戏进程 直接call这个地址就OK了
winio都不行的话,只有26的方法了,只是不会操作啊~
期待26楼的详细讲解~
call的地址就是WinKawaks响应投币action的method入口地址
咱觉得念经比看MOV,,PUSH,之类的有意思多了
OD的教程网上有很多的
WinIo.dll是可以使用的,是我在网上找的WinIo类有错误,所以之前调试无效。
先贴出正确的WinIo.dll封装类。再次感谢参与问题的朋友。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;namespace Client
{
public class WinIo
{
public const int KBC_KEY_CMD = 0x64;
public const int KBC_KEY_DATA = 0x60;
[DllImport("winio.dll")]
public static extern bool InitializeWinIo();
[DllImport("winio.dll")]
public static extern bool GetPortVal(IntPtr wPortAddr, out int pdwPortVal, byte bSize);
[DllImport("winio.dll")]
public static extern bool SetPortVal(uint wPortAddr, IntPtr dwPortVal, byte bSize);
[DllImport("winio.dll")]
public static extern byte MapPhysToLin(byte pbPhysAddr, uint dwPhysSize, IntPtr PhysicalMemoryHandle);
[DllImport("winio.dll")]
public static extern bool UnmapPhysicalMemory(IntPtr PhysicalMemoryHandle, byte pbLinAddr);
[DllImport("winio.dll")]
public static extern bool GetPhysLong(IntPtr pbPhysAddr, byte pdwPhysVal);
[DllImport("winio.dll")]
public static extern bool SetPhysLong(IntPtr pbPhysAddr, byte dwPhysVal);
[DllImport("winio.dll")]
public static extern void ShutdownWinIo();
[DllImport("user32.dll")]
public static extern int MapVirtualKey(uint Ucode, uint uMapType);
public void sendwinio()
{
if (InitializeWinIo())
{
KBCWait4IBE();
} }
///等待键盘缓冲区为空
private void KBCWait4IBE()
{
int dwVal = 0;
do
{
bool flag = GetPortVal((IntPtr)0x64, out dwVal, 1);
}
while ((dwVal & 0x2) > 0);
}
/// 模拟键盘标按下
public void MykeyDown(int vKeyCoad)
{
int btScancode = 0;
btScancode = MapVirtualKey((byte)vKeyCoad, 0);
KBCWait4IBE(); // 等待键盘缓冲区为空
SetPortVal(KBC_KEY_CMD, (IntPtr)0xD2, 1);// 发送命令
KBCWait4IBE();
SetPortVal(KBC_KEY_DATA, (IntPtr)0xe2, 1);// 写入按键信息
KBCWait4IBE(); // '等待键盘缓冲区为空
SetPortVal(KBC_KEY_CMD, (IntPtr)0xD2, 1);// '发送键盘写入命令
KBCWait4IBE();
SetPortVal(KBC_KEY_DATA, (IntPtr)btScancode, 1);// '写入按下键
}
/// 模拟键盘弹出
public void MykeyUp(int vKeyCoad)
{
int btScancode = 0;
btScancode = MapVirtualKey((byte)vKeyCoad, 0);
KBCWait4IBE(); // '等待键盘缓冲区为空
SetPortVal(KBC_KEY_CMD, (IntPtr)0xD2, 1); //'发送键盘写入命令
KBCWait4IBE();
SetPortVal(KBC_KEY_DATA, (IntPtr)0xe0, 1);// '写入按键信息
KBCWait4IBE(); // '等待键盘缓冲区为空
SetPortVal(KBC_KEY_CMD, (IntPtr)0xD2, 1); //'发送写入命令
KBCWait4IBE();
SetPortVal(KBC_KEY_DATA, (IntPtr)btScancode, 1);// '写入释放键
}
/// 模拟鼠标按下
public void MyMouseDown(int vKeyCoad)
{
int btScancode = 0;
btScancode = MapVirtualKey((byte)vKeyCoad, 0);
KBCWait4IBE(); // '等待键盘缓冲区为空
SetPortVal(KBC_KEY_CMD, (IntPtr)0xD3, 1);// '发送写入命令
KBCWait4IBE();
SetPortVal(KBC_KEY_DATA, (IntPtr)(btScancode | 0x80), 1);// '写入信息按下键
}
/// 模拟鼠标弹出
public void MyMouseUp(int vKeyCoad)
{
int btScancode = 0;
btScancode = MapVirtualKey((byte)vKeyCoad, 0);
KBCWait4IBE(); // '等待键盘缓冲区为空
SetPortVal(KBC_KEY_CMD, (IntPtr)0xD3, 1); //'发送写入命令
KBCWait4IBE();
SetPortVal(KBC_KEY_DATA, (IntPtr)(btScancode | 0x80), 1);// '写入信息释放键
}
//----------------------------------------------------------------------------------------------------------------------------
//下面为动作代码,请自行添加
//----------------------------------------------------------------------------------------------------------------------------
public enum Key
{
// 鼠标动代码:
move = 0x0001,
leftdown = 0x0002,
leftup = 0x0004,
rightdown = 0x0008,
rightup = 0x0010,
middledown = 0x0020,
//键盘动作代码:
VK_LBUTTON = 1, //鼠标左键
VK_RBUTTON = 2, //鼠标右键
VK_CANCEL = 3, //Ctrl+Break(通常不需要处理)
VK_MBUTTON = 4, //鼠标中键
VK_BACK = 8, //Backspace
VK_TAB = 9, //Tab
VK_CLEAR = 12, //Num Lock关闭时的数字键盘5
VK_RETURN = 13, //Enter(或者另一个)
VK_SHIFT = 16, //Shift(或者另一个)
VK_CONTROL = 17, //Ctrl(或者另一个)
VK_MENU = 18, //Alt(或者另一个)
VK_PAUSE = 19, //Pause
VK_CAPITAL = 20, //Caps Lock
VK_ESCAPE = 27, //Esc
VK_SPACE = 32, //Spacebar
VK_PRIOR = 33, //Page Up
VK_NEXT = 34, //Page Down
VK_END = 35, //End
VK_HOME = 36, //Home
VK_LEFT = 37, //左箭头
VK_UP = 38, //上箭头
VK_RIGHT = 39, //右箭头
VK_DOWN = 40, //下箭头
VK_SELECT = 41, //可选
VK_PRINT = 42, //可选
VK_EXECUTE = 43, //可选
VK_SNAPSHOT = 44, //Print Screen
VK_INSERT = 45, //Insert
VK_DELETE = 46, //Delete
VK_HELP = 47, //可选
VK_NUM0 = 48, //0
VK_NUM1 = 49, //1
VK_NUM2 = 50, //2
VK_NUM3 = 51, //3
VK_NUM4 = 52, //4
VK_NUM5 = 53, //5
VK_NUM6 = 54, //6
VK_NUM7 = 55, //7
VK_NUM8 = 56, //8
VK_NUM9 = 57, //9
VK_A = 65, //A
VK_B = 66, //B
VK_C = 67, //C
VK_D = 68, //D
VK_E = 69, //E
VK_F = 70, //F
VK_G = 71, //G
VK_H = 72, //H
VK_I = 73, //I
VK_J = 74, //J
VK_K = 75, //K
VK_L = 76, //L
VK_M = 77, //M
VK_N = 78, //N
VK_O = 79, //O
VK_P = 80, //P
VK_Q = 81, //Q
VK_R = 82, //R
VK_S = 83, //S
VK_T = 84, //T
VK_U = 85, //U
VK_V = 86, //V
VK_W = 87, //W
VK_X = 88, //X
VK_Y = 89, //Y
VK_Z = 90, //Z
VK_NUMPAD0 = 96, //0
VK_NUMPAD1 = 97, //1
VK_NUMPAD2 = 98, //2
VK_NUMPAD3 = 99, //3
VK_NUMPAD4 = 100, //4
VK_NUMPAD5 = 101, //5
VK_NUMPAD6 = 102, //6
VK_NUMPAD7 = 103, //7
VK_NUMPAD8 = 104, //8
VK_NUMPAD9 = 105, //9
VK_NULTIPLY = 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_NUMLOCK = 144, //Num Lock
VK_SCROLL = 145, // Scroll Lock
middleup = 0x0040,
xdown = 0x0080,
xup = 0x0100,
wheel = 0x0800,
virtualdesk = 0x4000,
absolute = 0x8000
}
}
}