[MWB] Use UWP API to inject mouse input (#27229)

* [MWB] Use UWP API to inject mouse input
This commit is contained in:
Andrey Nekrasov
2023-07-10 18:32:20 +02:00
committed by GitHub
parent e2d65dcb84
commit c3c15ffad1
6 changed files with 57 additions and 10 deletions

View File

@@ -20,6 +20,7 @@ using System.Threading;
using Microsoft.Win32;
using MouseWithoutBorders.Class;
using MouseWithoutBorders.Form;
using Windows.UI.Input.Preview.Injection;
namespace MouseWithoutBorders
{
@@ -110,6 +111,21 @@ namespace MouseWithoutBorders
Common.Log(e.Message);
}
try
{
InputSimulation.Injector = InputInjector.TryCreate();
if (InputSimulation.Injector != null)
{
InputSimulation.MoveMouseRelative(0, 0);
NativeMethods.InjectMouseInputAvailable = true;
}
}
catch (EntryPointNotFoundException)
{
NativeMethods.InjectMouseInputAvailable = false;
Common.Log($"{nameof(NativeMethods.InjectMouseInputAvailable)} = false");
}
bool dummy = Setting.Values.DrawMouseEx;
Is64bitOS = IntPtr.Size == 8;
tcpPort = Setting.Values.TcpPort;

View File

@@ -15,6 +15,8 @@ using System.Globalization;
using System.Runtime.InteropServices;
using System.ServiceProcess;
using System.Threading.Tasks;
using Windows.UI.Input.Preview.Injection;
using static MouseWithoutBorders.Class.NativeMethods;
[module: SuppressMessage("Microsoft.Portability", "CA1901:PInvokeDeclarationsShouldBePortable", Scope = "member", Target = "MouseWithoutBorders.InputSimulation.#keybd_event(System.Byte,System.Byte,System.UInt32,System.Int32)", MessageId = "3", Justification = "Dotnet port with style preservation")]
[module: SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", Scope = "member", Target = "MouseWithoutBorders.InputSimulation.#InputProcessKeyEx(System.Int32,System.Int32,System.Boolean&)", MessageId = "MouseWithoutBorders.NativeMethods.LockWorkStation", Justification = "Dotnet port with style preservation")]
@@ -23,15 +25,30 @@ namespace MouseWithoutBorders.Class
{
internal class InputSimulation
{
public static InputInjector Injector;
private InputSimulation()
{
}
internal static InjectedInputMouseInfo MouseInputToInjectedInputMouseInfo(MOUSEINPUT mouseInput)
{
var injectedInput = new InjectedInputMouseInfo();
injectedInput.DeltaX = mouseInput.dx;
injectedInput.DeltaY = mouseInput.dy;
injectedInput.MouseData = (uint)mouseInput.mouseData;
injectedInput.MouseOptions = (InjectedInputMouseOptions)mouseInput.dwFlags;
injectedInput.TimeOffsetInMilliseconds = (uint)mouseInput.time;
return injectedInput;
}
private static uint SendInputEx(NativeMethods.INPUT input)
{
Common.PaintCount = 0;
uint rv;
uint rv = 0;
if (Common.Is64bitOS)
{
NativeMethods.INPUT64 input64 = default;
@@ -58,18 +75,27 @@ namespace MouseWithoutBorders.Class
input64.mi.dwExtraInfo = input.mi.dwExtraInfo;
}
NativeMethods.INPUT64[] inputs = { input64 };
// mouse click simulation
// TODO: Find alternative API that simulates mouse input more directly
rv = NativeMethods.SendInput64(1, inputs, Marshal.SizeOf(input64));
if (input.type == 0 && (input.mi.dwFlags & (int)NativeMethods.MOUSEEVENTF.MOVE) != 0 && NativeMethods.InjectMouseInputAvailable)
{
Injector.InjectMouseInput(new[] { MouseInputToInjectedInputMouseInfo(input64.mi) });
}
else
{
NativeMethods.INPUT64[] inputs = { input64 };
rv = NativeMethods.SendInput64(1, inputs, Marshal.SizeOf(input64));
}
}
else
{
NativeMethods.INPUT[] inputs = { input };
// TODO: Find alternative API that simulates mouse input more directly
rv = NativeMethods.SendInput(1, inputs, Marshal.SizeOf(input));
if (input.type == 0 && (input.mi.dwFlags & (int)NativeMethods.MOUSEEVENTF.MOVE) != 0 && NativeMethods.InjectMouseInputAvailable)
{
Injector.InjectMouseInput(new[] { MouseInputToInjectedInputMouseInfo(input.mi) });
}
else
{
NativeMethods.INPUT[] inputs = { input };
rv = NativeMethods.SendInput(1, inputs, Marshal.SizeOf(input));
}
}
return rv;

View File

@@ -576,6 +576,8 @@ namespace MouseWithoutBorders.Class
[DllImport("user32.dll", EntryPoint = "SendInput", SetLastError = true)]
internal static extern uint SendInput64(uint nInputs, INPUT64[] pInputs, int cbSize);
internal static bool InjectMouseInputAvailable { get; set; }
[DllImport("user32.dll", EntryPoint = "GetMessageExtraInfo", SetLastError = true)]
internal static extern IntPtr GetMessageExtraInfo();

View File

@@ -217,6 +217,7 @@
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.Windows.Compatibility" />
<PackageReference Include="Microsoft.Windows.SDK.Contracts" />
<PackageReference Include="StreamJsonRpc" />
</ItemGroup>
<ItemGroup>