diff --git a/Directory.Packages.props b/Directory.Packages.props
index 5afa09327e..6734a7f99a 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -33,6 +33,7 @@
+
diff --git a/NOTICE.md b/NOTICE.md
index b7c165b08b..119e359b25 100644
--- a/NOTICE.md
+++ b/NOTICE.md
@@ -308,6 +308,7 @@ SOFTWARE.
- Microsoft.Windows.CsWin32 0.2.46-beta
- Microsoft.Windows.CsWinRT 2.0.2
- Microsoft.Windows.SDK.BuildTools 10.0.22621.755
+- Microsoft.Windows.SDK.Contracts 10.0.19041.1
- Microsoft.WindowsAppSDK 1.3.230502000
- Microsoft.Xaml.Behaviors.WinUI.Managed 2.0.9
- Microsoft.Xaml.Behaviors.Wpf 1.1.39
diff --git a/src/modules/MouseWithoutBorders/App/Class/Common.InitAndCleanup.cs b/src/modules/MouseWithoutBorders/App/Class/Common.InitAndCleanup.cs
index a5b91eb460..2c7f271b61 100644
--- a/src/modules/MouseWithoutBorders/App/Class/Common.InitAndCleanup.cs
+++ b/src/modules/MouseWithoutBorders/App/Class/Common.InitAndCleanup.cs
@@ -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;
diff --git a/src/modules/MouseWithoutBorders/App/Class/InputSimulation.cs b/src/modules/MouseWithoutBorders/App/Class/InputSimulation.cs
index b46dcd9cb9..220da7454e 100644
--- a/src/modules/MouseWithoutBorders/App/Class/InputSimulation.cs
+++ b/src/modules/MouseWithoutBorders/App/Class/InputSimulation.cs
@@ -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;
diff --git a/src/modules/MouseWithoutBorders/App/Class/NativeMethods.cs b/src/modules/MouseWithoutBorders/App/Class/NativeMethods.cs
index 6bc101f6ca..a0b1621c97 100644
--- a/src/modules/MouseWithoutBorders/App/Class/NativeMethods.cs
+++ b/src/modules/MouseWithoutBorders/App/Class/NativeMethods.cs
@@ -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();
diff --git a/src/modules/MouseWithoutBorders/App/MouseWithoutBorders.csproj b/src/modules/MouseWithoutBorders/App/MouseWithoutBorders.csproj
index 60e75ccb63..a526b68449 100644
--- a/src/modules/MouseWithoutBorders/App/MouseWithoutBorders.csproj
+++ b/src/modules/MouseWithoutBorders/App/MouseWithoutBorders.csproj
@@ -217,6 +217,7 @@
all
+