C#中如何正确使用SendInput()模拟鼠标输入
How to use SendInput() properly to simulate mouse input in C#
我试图在 C# .NET 中使用来自 user32 dll 的 SendInput() 来模拟(全局)鼠标点击。
我已经尝试使用 SendInput() 进行键盘输入,并且效果很好。但由于某些原因,它不适用于鼠标输入。
这是我的代码,
为简单起见,我没有给出KEYBDINPUT 和HARDWAREINPUT (struct) 的定义。因为 MOUSEINPUT 仅与此处相关。
[DllImport("user32.dll")]
internal static extern uint SendInput(uint nInputs, [MarshalAs(UnmanagedType.LPArray), In] INPUT[] pInputs, int cbSize);
//main calling method
public static void CLICK()
{
INPUT []i = new INPUT[1];
i[0].type = 0;
i[0].U.mi.time = 0;
i[0].U.mi.dwFlags = MOUSEEVENTF.LEFTDOWN | MOUSEEVENTF.ABSOLUTE;
i[0].U.mi.dwExtraInfo = UIntPtr.Zero;
i[0].U.mi.dx = 1;
i[0].U.mi.dy = 1;
SendInput(1, i, INPUT.Size);
}
[StructLayout(LayoutKind.Sequential)]
public struct INPUT
{
internal uint type;
internal InputUnion U;
internal static int Size
{
get { return Marshal.SizeOf(typeof(INPUT)); }
}
}
[StructLayout(LayoutKind.Explicit)]
internal struct InputUnion
{
[FieldOffset(0)]
internal MOUSEINPUT mi;
[FieldOffset(0)]
internal KEYBDINPUT ki;
[FieldOffset(0)]
internal HARDWAREINPUT hi;
}
[StructLayout(LayoutKind.Sequential)]
internal struct MOUSEINPUT
{
internal long dx;
internal long dy;
internal int mouseData;
internal MOUSEEVENTF dwFlags;
internal uint time;
internal UIntPtr dwExtraInfo;
}
[Flags]
internal enum MOUSEEVENTF : uint
{
ABSOLUTE = 0x8000,
HWHEEL = 0x01000,
MOVE = 0x0001,
MOVE_NOCOALESCE = 0x2000,
LEFTDOWN = 0x0002,
LEFTUP = 0x0004,
RIGHTDOWN = 0x0008,
RIGHTUP = 0x0010,
MIDDLEDOWN = 0x0020,
MIDDLEUP = 0x0040,
VIRTUALDESK = 0x4000,
WHEEL = 0x0800,
XDOWN = 0x0080,
XUP = 0x0100
}
此外,我已经尝试了不同的 x,y 点。和其他 dwFlags(例如 LEFTUP、MOVE..),但到目前为止没有任何效果。
对于 internal long dx;
和 dy
,我有 int
输入我的 struct MOUSEINPUT
。
根据 MOUSEINPUT
documentation dx
和 dy
是 LONG
。
但是 C++ 中的 LONG
是“至少”32 位,而 C# 中的 long
是 64 位。因此它匹配 C# int
。 ()
[StructLayout(LayoutKind.Sequential)]
internal struct MOUSEINPUT
{
internal int dx;
internal int dy;
internal int mouseData;
internal MOUSEEVENTF dwFlags;
internal uint time;
internal UIntPtr dwExtraInfo;
}
我试图在 C# .NET 中使用来自 user32 dll 的 SendInput() 来模拟(全局)鼠标点击。 我已经尝试使用 SendInput() 进行键盘输入,并且效果很好。但由于某些原因,它不适用于鼠标输入。
这是我的代码,
为简单起见,我没有给出KEYBDINPUT 和HARDWAREINPUT (struct) 的定义。因为 MOUSEINPUT 仅与此处相关。
[DllImport("user32.dll")]
internal static extern uint SendInput(uint nInputs, [MarshalAs(UnmanagedType.LPArray), In] INPUT[] pInputs, int cbSize);
//main calling method
public static void CLICK()
{
INPUT []i = new INPUT[1];
i[0].type = 0;
i[0].U.mi.time = 0;
i[0].U.mi.dwFlags = MOUSEEVENTF.LEFTDOWN | MOUSEEVENTF.ABSOLUTE;
i[0].U.mi.dwExtraInfo = UIntPtr.Zero;
i[0].U.mi.dx = 1;
i[0].U.mi.dy = 1;
SendInput(1, i, INPUT.Size);
}
[StructLayout(LayoutKind.Sequential)]
public struct INPUT
{
internal uint type;
internal InputUnion U;
internal static int Size
{
get { return Marshal.SizeOf(typeof(INPUT)); }
}
}
[StructLayout(LayoutKind.Explicit)]
internal struct InputUnion
{
[FieldOffset(0)]
internal MOUSEINPUT mi;
[FieldOffset(0)]
internal KEYBDINPUT ki;
[FieldOffset(0)]
internal HARDWAREINPUT hi;
}
[StructLayout(LayoutKind.Sequential)]
internal struct MOUSEINPUT
{
internal long dx;
internal long dy;
internal int mouseData;
internal MOUSEEVENTF dwFlags;
internal uint time;
internal UIntPtr dwExtraInfo;
}
[Flags]
internal enum MOUSEEVENTF : uint
{
ABSOLUTE = 0x8000,
HWHEEL = 0x01000,
MOVE = 0x0001,
MOVE_NOCOALESCE = 0x2000,
LEFTDOWN = 0x0002,
LEFTUP = 0x0004,
RIGHTDOWN = 0x0008,
RIGHTUP = 0x0010,
MIDDLEDOWN = 0x0020,
MIDDLEUP = 0x0040,
VIRTUALDESK = 0x4000,
WHEEL = 0x0800,
XDOWN = 0x0080,
XUP = 0x0100
}
此外,我已经尝试了不同的 x,y 点。和其他 dwFlags(例如 LEFTUP、MOVE..),但到目前为止没有任何效果。
对于 internal long dx;
和 dy
,我有 int
输入我的 struct MOUSEINPUT
。
根据 MOUSEINPUT
documentation dx
和 dy
是 LONG
。
但是 C++ 中的 LONG
是“至少”32 位,而 C# 中的 long
是 64 位。因此它匹配 C# int
。 (
[StructLayout(LayoutKind.Sequential)]
internal struct MOUSEINPUT
{
internal int dx;
internal int dy;
internal int mouseData;
internal MOUSEEVENTF dwFlags;
internal uint time;
internal UIntPtr dwExtraInfo;
}