In my application I'm catching keystrokes and when the keystrokes are not part of a barcode I want to send them to the application. The keystrokes need to be sent to the application itself.
I tried different methods but without success.
internal class InputSimulator
{
#pragma warning disable SA1305 // Field names should not use Hungarian notation
#pragma warning disable SA1307 // Accessible fields should begin with upper-case letter
#pragma warning disable SA1400 // Access modifier should be declared
[DllImport("user32.dll", SetLastError = true)]
private static extern uint SendInput(uint nInputs, INPUT[] pInputs, int cbSize);
[DllImport("user32.dll")]
internal static extern uint MapVirtualKey(uint uCode, uint uMapType);
struct INPUT
{
public INPUTType type;
public INPUTUnion Event;
}
[StructLayout(LayoutKind.Explicit)]
struct INPUTUnion
{
[FieldOffset(0)]
internal MOUSEINPUT mi;
[FieldOffset(0)]
internal KEYBDINPUT ki;
[FieldOffset(0)]
internal HARDWAREINPUT hi;
}
[StructLayout(LayoutKind.Sequential)]
struct MOUSEINPUT
{
public int dx;
public int dy;
public int mouseData;
public int dwFlags;
public uint time;
public IntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
struct KEYBDINPUT
{
public ushort wVk;
public ushort wScan;
public KEYEVENTF dwFlags;
public int time;
public IntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
struct HARDWAREINPUT
{
public int uMsg;
public short wParamL;
public short wParamH;
}
enum INPUTType : uint
{
INPUT_KEYBOARD = 1
}
[Flags]
enum KEYEVENTF : uint
{
EXTENDEDKEY = 0x0001,
KEYUP = 0x0002,
SCANCODE = 0x0008,
UNICODE = 0x0004
}
public static void ProcessKeys(Key[] keys)
{
INPUT[] inputs = new INPUT[keys.Length + 1];
for (int i = 0; i < keys.Length; i++)
{
var virtualKey = KeyInterop.VirtualKeyFromKey(keys[i]);
uint skey = MapVirtualKey((uint)virtualKey, 0x0);
inputs[i].type = INPUTType.INPUT_KEYBOARD;
inputs[i].Event.ki.dwFlags = KEYEVENTF.SCANCODE;
inputs[i].Event.ki.wScan = (ushort)skey;
}
inputs[keys.Length].type = INPUTType.INPUT_KEYBOARD;
inputs[keys.Length].Event.ki.dwFlags = KEYEVENTF.UNICODE;
inputs[keys.Length].Event.ki.dwFlags |= KEYEVENTF.KEYUP;
uint cSuccess = SendInput((uint)inputs.Length, inputs, Marshal.SizeOf(typeof(INPUT)));
}
public static void Send(Key key)
{
if (Keyboard.PrimaryDevice != null)
{
if (Keyboard.PrimaryDevice.ActiveSource != null)
{
var e = new KeyEventArgs(Keyboard.PrimaryDevice, Keyboard.PrimaryDevice.ActiveSource, 0, key)
{
RoutedEvent = Keyboard.PreviewKeyDownEvent
};
InputManager.Current.ProcessInput(e);
}
}
}
#pragma warning restore SA1305 // Field names should not use Hungarian
notation
#pragma warning restore SA1307 // Accessible fields should begin with
upper-case letter
#pragma warning restore SA1400 // Access modifier should be declared
}
In the code below are two methods ProcessKeys
and Send
but they don't work. What am I doing wrong? Is there another way to achieve this? At the moment I use System.Windows.Forms.SendKeys.SendWait
but I prefer a way without references to System.Windows.Forms
EDIT: My question has been tagged a a possible duplicate : SendKeys.Send Method in WPF application I tried both solutions but none of them works, maybe there's something wrong in my SendInput implementation, but I can't find out what's wrong