【发布时间】:2016-04-07 16:45:57
【问题描述】:
我正在尝试使用 SendInput 方法模拟鼠标输入。点击等工作正常,但坐标设置不正确。每次执行输入时,鼠标光标都会移动到屏幕的右下角。我尝试将 MOUSEINPUT X 和 Y 坐标更改为长数据类型as listed in the MSDN documentation,但 SendInput 方法总是返回错误并且输入不执行。
下面是我用来尝试这个的代码。我已经从创建和执行 KEYBDINPUT 结构的类似实现中移植了这段代码。该实现工作完美,所以我很困惑为什么不这样做。我确信它是非常小的东西,因为鼠标点击等成功执行它只是导致问题的坐标。
如果有人对这里出了什么问题有任何见解,我们将不胜感激。
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace SequenceAutomation
{
#region Stucture declarations
public struct MOUSEINPUT
{
public int X;
public int Y;
public uint MouseData;
public uint Flags;
public uint Time;
public IntPtr ExtraInfo;
}
public struct HARDWAREINPUT
{
public uint Msg;
public ushort ParamL;
public ushort ParamH;
}
public struct KEYBDINPUT
{
public ushort KeyCode;
public ushort Scan;
public uint Flags;
public uint Time;
public IntPtr ExtraInfo;
}
[StructLayout(LayoutKind.Explicit)]
public struct MOUSEKEYBDHARDWAREINPUT
{
[FieldOffset(0)]
public MOUSEINPUT Mouse;
[FieldOffset(0)]
public KEYBDINPUT Keyboard;
[FieldOffset(0)]
public HARDWAREINPUT Hardware;
}
public struct INPUT
{
public uint Type;
public MOUSEKEYBDHARDWAREINPUT Data;
}
#endregion
public class PlayRecording
{
#region Variable declarations
public bool stopPlayback;
private RecordingManager recManager;
private float timeFactor;
private Dictionary<long, Dictionary<IntPtr, Dictionary<string, int>>> mouseDict;
private Dictionary<long, INPUT[]> keysToPlay;
private Stopwatch watch;
private long currentEntry;
#endregion
#region Libary importations
// Importation of native libraries
[DllImport("user32.dll", SetLastError = true)]
private static extern uint SendInput(uint numberOfInputs, INPUT[] inputs, int sizeOfInputStructure);
#endregion
#region Public methods
public PlayRecording(string inputJson, float timeFactor)
{
currentEntry = 0;
this.timeFactor = timeFactor;
stopPlayback = false;
watch = new Stopwatch();
recManager = new RecordingManager(inputJson);
recManager.getDictionaries(inputJson);
mouseDict = recManager.mouseDict;
inputsToPlay = new Dictionary<long, INPUT[]>();
prepareInputsToPlay();
}
public void Start()
{
currentEntry = 0;
watch.Reset();
watch.Start();
IEnumerator<long> enumerator = inputsToPlay.Keys.GetEnumerator();
while (enumerator.MoveNext())
{
while (watch.ElapsedTicks < (enumerator.Current * timeFactor)) { }
if (!stopPlayback)
uint err = SendInput((uint)keysToPlay[enumerator.Current].Length, keysToPlay[enumerator.Current], Marshal.SizeOf(typeof(INPUT)));
currentEntry = enumerator.Current;
}
}
public bool Stop()
{
watch.Stop();
return true;
}
#endregion
#region Private methods
private void prepareInputsToPlay()
{
foreach (KeyValuePair<long, Dictionary<IntPtr, Dictionary<string, int>>> kvp in mouseDict)
{
List<INPUT> inputs = new List<INPUT>();
foreach (KeyValuePair<IntPtr, Dictionary<string, int>> kvp2 in kvp.Value)
{
int x = 0;
int y = 0;
foreach (KeyValuePair<string, int> kvp3 in kvp2.Value)
{
if (kvp3.Key == "X")
x = Convert.ToInt32(kvp3.Value);
if (kvp3.Key == "Y")
y = Convert.ToInt32(kvp3.Value);
}
inputs.Add(loadMouse(x, y, getFlags(kvp2.Key)));
}
inputsToPlay.Add(kvp.Key, inputs.ToArray());
}
}
// This is where the flags are set
private uint getFlags(IntPtr activity)
{
string activityInt = Convert.ToString(activity);
switch(activityInt)
{
return 0x0002;
case "512":
return 0x0001;
case "513":
return 0x0002;
case "514":
return 0x0004;
case "516":
return 0x0008;
case "517":
return 0x0010;
case "522":
return 0x0800;
default:
return 0;
}
}
// This is where the input structures are being created
private INPUT loadMouse(int x, int y, uint flags)
{
return new INPUT
{
Type = 0,
Data =
{
Mouse = new MOUSEINPUT
{
X = x,
Y = y,
MouseData = 0,
Flags = flags,
Time = 0,
ExtraInfo = IntPtr.Zero
}
}
};
}
#endregion
}
}
【问题讨论】:
标签: c# .net winforms dictionary