0

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

Sybren
  • 1,071
  • 3
  • 17
  • 51
  • I use the `SendInput` native method in my application and it **works**. So there is nothing wrong with its implementation, it's something wrong with your usage. Apparently, a question like `I use this codez but it isn't working plz help me` is off-topic on StackOverflow. – dymanoid Sep 13 '17 at 11:37
  • I'm not quite sure what you try to do... do you try to generically generate some input for whatever application would receive it when using the actual keyboard or are you trying to inject input into a specific application even when it doesn't have the input focus for the physical input devices? – grek40 Sep 13 '17 at 12:25
  • As I said I intercept all keystrokes and I measure the delay between the keystrokes. If the delay is to big there's it's no barcode scanner input so I can send the intercepted keystrokes to my application. – Sybren Sep 13 '17 at 12:28
  • Funny story... there are reports of professional typing pool employees who technically can't work with certain keyboards because they type to fast... I hope your scanner is not to slow because the fastest writers will be close to 10 keys per second *on average*, so their peek performance for easy accessible keys will be much faster. – grek40 Sep 14 '17 at 10:12

0 Answers0