我使用这块板作为键盘用于演示目的.
无论如何,长话短说一切都很好,除了很少的情况.我使用user32.dll中的SendInput函数发送击键.
所以我的程序看起来像:
static void Main(string[] args)
{
Console.Write("Press enter an on the next secont the key combination shift+end will be send");
Console.Read();
Thread.Sleep(1000);
SendKeyDown(KeyCode.SHIFT);
SendKeyPress(KeyCode.END);
SendKeyUp(KeyCode.SHIFT);
Console.Read();
Console.Read();
}
[DllImport("user32.dll", SetLastError = true)]
private static extern uint SendInput(uint numberOfInputs, INPUT[] inputs, int sizeOfInputStructure);
/// <summary>
/// simulate key press
/// </summary>
/// <param name="keyCode"></param>
public static void SendKeyPress(KeyCode keyCode)
{
INPUT input = new INPUT {
Type = 1
};
input.Data.Keyboard = new KEYBDINPUT() { …Run Code Online (Sandbox Code Playgroud) 我正在尝试为自定义游戏控制器应用程序模拟键盘命令.因为我需要在DirectInput环境中模拟命令,所以大多数常用方法都不起作用.我知道使用一个钩子可以100%工作,但我试图找到一个更容易的实现.
我已经做了很多搜索,发现通过使用带有扫描码的SendInput API而不是虚拟键应该可以工作,但它似乎表现得像键是"坚持".我已经发送了KEYDOWN和KEYUP事件,但是当我尝试在DirectInput环境中发送消息时,游戏就像按下键一样.
例如,如果我模拟"W"按键并将该键映射到第一人称射击游戏中以"向前移动"动作,那么一旦我在游戏中,下面的功能将导致角色向前移动.但是,只需发出一次命令,它就会无限地向前移动角色.
这是我正在调用的SendInput函数的代码片段(在C#中):
[DllImport("user32.dll")]
static extern UInt32 SendInput(UInt32 nInputs, [MarshalAs(UnmanagedType.LPArray, SizeConst = 1)] INPUT[] pInputs, Int32 cbSize);
public static void Test_KeyDown()
{
INPUT[] InputData = new INPUT[2];
Key ScanCode = Microsoft.DirectX.DirectInput.Key.W;
InputData[0].type = 1; //INPUT_KEYBOARD
InputData[0].wScan = (ushort)ScanCode;
InputData[0].dwFlags = (uint)SendInputFlags.KEYEVENTF_SCANCODE;
InputData[1].type = 1; //INPUT_KEYBOARD
InputData[1].wScan = (ushort)ScanCode;
InputData[1].dwFlags = (uint)(SendInputFlags.KEYEVENTF_KEYUP | SendInputFlags.KEYEVENTF_UNICODE);
// send keydown
if (SendInput(2, InputData, Marshal.SizeOf(InputData[1])) == 0)
{
System.Diagnostics.Debug.WriteLine("SendInput failed with code: " +
Marshal.GetLastWin32Error().ToString());
}
}
Run Code Online (Sandbox Code Playgroud)
我不确定这种方法是否是一个失败的原因,或者是否有一些愚蠢的东西我不知道.如果我不需要使用钩子,我讨厌使代码复杂化,但这对我来说也是一个新的领域.
任何人都可以给予任何帮助非常感谢.
谢谢!
我正在使用C#,Framework 4(32位)的Windows窗体应用程序.
我有一个包含鼠标坐标的列表,我可以捕获它们.到现在为止还挺好.
但在某些时候,我想去那些坐标并点击鼠标左键.
这就是它现在的样子:
for (int i = 0; i < coordsX.Count; i++)
{
Cursor.Position = new Point(coordsX[i], coordsY[i]);
Application.DoEvents();
Clicking.SendClick();
}
Run Code Online (Sandbox Code Playgroud)
点击课:
class Clicking
{
private const UInt32 MOUSEEVENTF_LEFTDOWN = 0x0002;
private const UInt32 MOUSEEVENTF_LEFTUP = 0x0004;
private static extern void mouse_event(
UInt32 dwFlags, // motion and click options
UInt32 dx, // horizontal position or change
UInt32 dy, // vertical position or change
UInt32 dwData, // wheel movement
IntPtr dwExtraInfo // application-defined information
);
// public static void …Run Code Online (Sandbox Code Playgroud) 我创建了一个类似于wiimote的设备,我想在Windows(8.1)中将它用作鼠标.设备通过tcp连接到我的Windows计算机上的c ++ win32程序,并发送鼠标光标应移动的位置.我正在使用SetCursorPos函数来设置位置,这对于控制大多数程序非常有用.但是当我尝试控制例如任务管理器时,光标不再移动.当我从任务管理器切换回其他程序时,它再次工作.我也尝试使用具有相同结果的SendInput函数.
这是我的代码与SendInput的代码:
INPUT Input = { 0 };
Input.type = INPUT_MOUSE;
Input.mi.dx = (LONG)posX;
Input.mi.dy = (LONG)posY;
// set move cursor directly
Input.mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE;
SendInput(1, &Input, sizeof(INPUT));
Run Code Online (Sandbox Code Playgroud)
使用SetCursorPos,它只是一行:
SetCursorPos(posX, posY);
Run Code Online (Sandbox Code Playgroud)
谁能告诉我为什么它对某些程序不起作用?我知道必须这样做,因为我尝试了一个控制光标的智能手机应用程序,它适用于所有程序.
在深入钻取网页之后,这是我的代码,遗憾的是,它不会将密钥作为大写发送:/
MapVirtualKey实现:
const uint MAPVK_VK_TO_VSC = 0x00;
const uint MAPVK_VSC_TO_VK = 0x01;
const uint MAPVK_VK_TO_CHAR = 0x02;
const uint MAPVK_VSC_TO_VK_EX = 0x03;
const uint MAPVK_VK_TO_VSC_EX = 0x04;
[DllImport("user32.dll")]
public static extern int MapVirtualKey(uint uCode, uint uMapType);
Run Code Online (Sandbox Code Playgroud)
SendInput实现:
struct INPUT
{
public UInt32 Type;
public MOUSEKEYBDHARDWAREINPUT Data;
Run Code Online (Sandbox Code Playgroud)
}
[StructLayout(LayoutKind.Explicit)]
struct MOUSEKEYBDHARDWAREINPUT
{
[FieldOffset(0)]
public MOUSEINPUT Mouse;
[FieldOffset(0)]
public KEYBDINPUT Keyboard;
[FieldOffset(0)]
public HARDWAREINPUT Hardware;
}
[DllImport("user32.dll", SetLastError = true)]
static extern UInt32 SendInput(UInt32 numberOfInputs, INPUT[] inputs, Int32 sizeOfInputStructure);
Run Code Online (Sandbox Code Playgroud)
现在为方法:
此方法将键发送为字符串,通过远程桌面可以正常工作:
public …Run Code Online (Sandbox Code Playgroud) 下面是我用来通过SendInput API模拟按键的一些代码的摘录.如果我将我的应用程序设置为针对x86 CPU进行编译,则此方法可正常工作,但不适用于x64 CPU编译.
我猜它有一些事情,x64使用双倍大小的指针,但我试图改变这个[FieldOffset(4)],[FieldOffset(8)]但它没有用.
它是否与导入32位版本的user32.dll的事实有关?
#region SendInput API
[DllImport("user32.dll", EntryPoint = "SendInput", SetLastError = true)]
static extern uint SendInput(uint nInputs, INPUT[] pInputs, int cbSize);
[DllImport("user32.dll", EntryPoint = "GetMessageExtraInfo", SetLastError = true)]
static extern IntPtr GetMessageExtraInfo();
private enum KeyEvent
{
KeyUp = 0x0002,
KeyDown = 0x0000,
ExtendedKey = 0x0001
}
private struct KEYBDINPUT
{
public ushort wVk;
public ushort wScan;
public uint dwFlags;
public long time;
public uint dwExtraInfo;
};
[StructLayout(LayoutKind.Explicit, Size = 28)]
private struct …Run Code Online (Sandbox Code Playgroud) 我尝试在Win7上模拟鼠标事件,我的应用程序使用网站http://inputsimulator.codeplex.com/上的开源项目"Windows输入模拟器",它在内部使用以下代码来模拟鼠标事件:
[DllImport("user32.dll", SetLastError = true)]
public static extern UInt32 SendInput(UInt32 numberOfInputs, INPUT[] inputs, Int32 sizeOfInputStructure);
Run Code Online (Sandbox Code Playgroud)
当我使用Visual Studio 2010进行调试时,我的应用程序运行完美.左键单击事件,右键单击事件和鼠标移动事件都可以.但是,当我通过双击.exe应用程序可删除文件从资源管理器启动我的应用程序时,不会发送单击事件.只有鼠标移动事件没问题,如果我尝试模拟左键单击或右键单击,我的应用程序将收到异常并退出.我发现异常是由以下代码抛出:
public void DispatchInput(INPUT[] inputs)
{
if (inputs == null) throw new ArgumentNullException("inputs");
if (inputs.Length == 0) throw new ArgumentException("The input array was empty", "inputs");
var successful = NativeMethods.SendInput((UInt32)inputs.Length, inputs, Marshal.SizeOf(typeof (INPUT)));
if (successful != inputs.Length)
throw new Exception("Some simulated input commands were not sent successfully. The most common reason for this happening are the security features of Windows including User …Run Code Online (Sandbox Code Playgroud) 我正在编写类似于Windows 8中的屏幕键盘.使用Win32的SendInput发送我需要的大多数字符都没有问题.
问题出在新的Windows 8 Emoji上.它们使用Segoe UI Symbol字体从U + 1F600开始.
在Windows 8屏幕键盘上使用Spy ++,我得到了所有表情符号字形的以下输出.
<00001> 000C064A P WM_KEYDOWN nVirtKey:VK_PACKET cRepeat:1 ScanCode:00 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
<00002> 000C064A P WM_CHAR chCharCode:'63' (63) cRepeat:1 ScanCode:00 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
<00003> 000C064A P WM_KEYUP nVirtKey:VK_PACKET cRepeat:1 ScanCode:00 fExtended:0 fAltDown:0 fRepeat:1 fUp:1
<00004> 000C064A P WM_KEYDOWN nVirtKey:VK_PACKET cRepeat:1 ScanCode:00 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
<00005> 000C064A P WM_CHAR chCharCode:'63' (63) cRepeat:1 ScanCode:00 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
<00006> 000C064A P WM_KEYUP nVirtKey:VK_PACKET cRepeat:1 ScanCode:00 fExtended:0 fAltDown:0 fRepeat:1 fUp:1 …Run Code Online (Sandbox Code Playgroud) 我正在使用SendInput()发送鼠标的相对位置.先生病了,你在做什么.
我用手指移动鼠标.因此,首先我在640x480图像中跟踪手指,并获得图像中的像素绝对位置.
然后我将该位置发送到以下方法,以使用发送输入生成相对鼠标位置命令.
当手指移动到左边界(xlim1)或右边界(xlim2)时,光标会根据哪个限制水平向左或向右滚动.问题是当我运行代码时,当光标开始移动时,屏幕变为黑色.
当我评论其他部分if(cx> = prevX && cx> xlim2){....}部分时,它的工作原理..(所以当手指点到图像的右边界时,光标一直水平滚动到右.评论部分启用左水平滚动).
bool first变量将为true,如果这是第一次,我们捕获手指.否则就是假的.
void movMouse(int cx, int cy, bool first){
static int prevX = 0;
static int prevY = 0;
static int leftPrevX;
static int rightPrevX;
int mx,my;
if(first == true){
prevX = cx;
prevY = cy;
}
else{
mx = (cx - prevX);
my = (cy - prevY);
if(cx <= prevX && cx < xlim1){
mx = -20;
INPUT input;
input.type = INPUT_MOUSE;
input.mi.mouseData = 0;
input.mi.dx = -(mx);
input.mi.dy …Run Code Online (Sandbox Code Playgroud) void WriteChar(char c)
{
INPUT input = {0};
input.type = INPUT_KEYBOARD;
input.ki.wVk= VkKeyScanEx(c, GetKeyboardLayout(0) ) ;
SendInput(1,&input, sizeof(INPUT));
}
Run Code Online (Sandbox Code Playgroud)
VkKeyScanEx为'/'和'?'(相同的键)返回不同的键代码,但是如果您尝试使用此方法编写包含'?'的消息,则只会写'/'.我不知道发生了什么事.同样的事情发生在';' 和':'.
我部分不了解密钥代码和扫描代码.大多数角色都有虚拟键码,但我找不到类似问号的东西.它们必须存在,但没有列出?