.NET 的 POS |区分(条形码)扫描仪和键盘输入

发布于 2024-10-21 03:05:01 字数 194 浏览 4 评论 0原文

我想区分 WPF 应用程序中的(条形码)扫描仪和键盘输入。 我需要的是每当我的扫描仪提供数据时就会发生的事件。

在我的应用程序中,有一个特殊字段将填充扫描仪的输入。因此,如果用户专注于其他字段,我不想在其中插入扫描代码,而是插入我的特殊字段。

首先,我将扫描仪(通过 USB 连接)的输入模式从“键盘模拟”切换为“原始”。但我现在需要做什么?

I want to differentiate between (barcode) scanner and keyboard input in an WPF application.
What I need is an event which occurs whenever my scanner is providing data.

In my application there is a special field which will be filled with the input from the scanner. So, if the user has focused an other field I don't want to insert the scanned code in that, but my special field.

First of all I switch the input mode of my scanner (connected by USB) from "keyboard emulation" to "raw". But what do I need to do now?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

浅唱々樱花落 2024-10-28 03:05:01

实施 OPOSWEPOSWEB 内容不再可用)具有封装设备驱动程序的 COM 和/或 .Net 组件。这些组件可以在扫描数据时引发事件。这些标准还适用于更多设备,包括磁条读取器、秤、现金抽屉、零钱分配器和 MICR(支票)读取器。

如果未提供 xPOS 驱动程序,您可以获取 USB/串口驱动程序。这使得设备看起来像是通过 rs232 连接到 Windows。然后您可以使用 System.IO.Ports.SerialPort 编写“扫描仪”抽象。

另一种选择是获取 .sys 和 .h 文件。然后你正在做一些涉及的 ​​PInvoke 和可能的一些 C。

Scanners that implement OPOS or WEPOS (WEB CONTENT NOT AVAILABLE ANYMORE) have COM and/or .Net components that wrap the drivers for the devices. These components can raise an event when data is scanned. These standards also apply to much more including magnetic stripe readers, scales, cash drawers, change dispensers, and MICR(check) readers.

If an xPOS driver is not provided, you may get a usb/serial port driver. This makes the device look like it is connected via rs232 to windows. Then you can use System.IO.Ports.SerialPort to write a 'scanner' abstraction.

Another option, is just getting a .sys and .h file. Then you are doing some involved PInvoke and possibly some C.

热血少△年 2024-10-28 03:05:01

我已经放弃了使用 POS for .NET 实现这一点的方法。自己做几乎更容易,因为扫描仪处理它是您感兴趣的框架的唯一相关部分。这基本上是我正在使用的:

public class RawInput
{
    private static IntPtr DispatchMessage(IntPtr lParam, IEnumerable<IntPtr> fromDevices, ref object data)
    {
        var dataSize = UIntPtr.Zero;
        if (Win32.GetRawInputData(lParam, (UIntPtr)CommandFlag.Input, IntPtr.Zero, ref dataSize, (UIntPtr)Marshal.SizeOf(typeof(Win32.RAWINPUTHEADER))) == UIntPtr.Zero)
        {
            var buff = Marshal.AllocHGlobal((int)dataSize);
            var outSize = Win32.GetRawInputData(lParam, (UIntPtr)CommandFlag.Input, buff, ref dataSize, (UIntPtr)Marshal.SizeOf(typeof(Win32.RAWINPUTHEADER)));

            Debug.Assert(outSize == dataSize);
            var input = (Win32.RAWINPUT)Marshal.PtrToStructure(buff, typeof(Win32.RAWINPUT));

            var hDevice = IntPtr.Zero;
            if (fromDevices == null)
                hDevice = input.header.hDevice;
            else
                hDevice = fromDevices.FirstOrDefault(h => h == input.header.hDevice);

            if (hDevice != IntPtr.Zero)
            {
                switch ((Type)input.header.dwType)
                {
                    case Type.HID:
                        var hidData = new HIDDATA()
                        {
                            count = input.hid.dwCount,
                            size = input.hid.dwSizeHid,
                            raw = new byte[input.hid.dwCount * input.hid.dwSizeHid]
                        };

                        Marshal.Copy(
                            new IntPtr(
                                buff.ToInt64() +
                                Marshal.SizeOf(typeof(Win32.RAWINPUTHEADER)) +
                                Marshal.SizeOf(typeof(Win32.RAWHID))
                            ),
                            hidData.raw, 0, hidData.raw.Length
                        );

                        data = hidData;
                        break;
                    case Type.Keyboard:
                        data = new KEYBOARDDATA
                        {
                            makeCode = input.keyboard.MakeCode,
                            flags = (KeyboardFlag)input.keyboard.Flags,
                            vKey = input.keyboard.VKey,
                            message = (MessageContext)input.keyboard.Message,
                            extraInfo = input.keyboard.ExtraInformation
                        };
                        break;
                    case Type.Mouse:
                        var mouseData = new MOUSEDATA
                        {
                            extraInfo = input.mouse.ulExtraInformation,
                            flags = (MouseFlag)input.mouse.usFlags,
                            transitions = (MouseTransition)input.mouse.usButtonFlags,
                            motionX = input.mouse.lLastX,
                            motionY = input.mouse.lLastY
                        };

                        if (mouseData.transitions == MouseTransition.MouseWheel)
                            mouseData.wheelDelta = input.mouse.usButtonData;
                        data = mouseData;
                        break;
                }
            }

            Marshal.FreeHGlobal(buff);
            return hDevice;
        }
        else
            throw new ApplicationException("An error occurred while receiving raw input data.");
    }

    public static bool DispatchMessage(Win32.MSG message, IEnumerable<Device> fromDevices, ref Device source, ref object data)
    {
        var hDevice = IntPtr.Zero;
        if (message.message == MessageContext.Input)
        {
            if (fromDevices != null)
            {
                hDevice = DispatchMessage(message.lParam, fromDevices.Select(h => h.Handle), ref data);
                if (hDevice != IntPtr.Zero)
                    source = fromDevices.First(h => h.Handle == hDevice);
            }
            else
            {
                Func<Device> getRawInputDeviceInfo = () =>
                {
                    var name_size = UIntPtr.Zero;
                    Win32.GetRawInputDeviceInfo(hDevice, (UIntPtr)Win32.RIDI_DEVICENAME, IntPtr.Zero, ref name_size);

                    if (name_size != UIntPtr.Zero)
                    {
                        var name = Marshal.AllocHGlobal((int)name_size);
                        Win32.GetRawInputDeviceInfo(hDevice, (UIntPtr)Win32.RIDI_DEVICENAME, name, ref name_size);
                        string rid_name = (string)Marshal.PtrToStringAnsi(name);

                        var ridSize = (UIntPtr)Marshal.SizeOf(typeof(Win32.RID_DEVICE_INFO));
                        var buff = Marshal.AllocHGlobal((int)ridSize);
                        var outSize = Win32.GetRawInputDeviceInfo(hDevice, (UIntPtr)Win32.RIDI_DEVICEINFO, buff, ref ridSize);
                        Debug.Assert(outSize == ridSize);

                        var rid = (Win32.RID_DEVICE_INFO)Marshal.PtrToStructure(buff, typeof(Win32.RID_DEVICE_INFO));

                        var device = new Device()
                        {
                            Handle = hDevice,
                            ID = rid_name,
                            Type = (Type)rid.dwType,
                            Description = GetRawInputDeviceDescription(rid_name)
                        };

                        Marshal.FreeHGlobal(name);
                        return device;
                    }

                    return null;
                };

                hDevice = DispatchMessage(message.lParam, null, ref data);
                if (hDevice != IntPtr.Zero)
                    source = getRawInputDeviceInfo();
            }
        }

        return hDevice != IntPtr.Zero;
    }

    public static IEnumerable<Device> EnumerateDevices()
    {
        var ridSize = (UIntPtr)Marshal.SizeOf(typeof(Win32.RAWINPUTDEVICELIST));
        var ridCnt = UIntPtr.Zero;
        var list = new List<Device>();

        if (Win32.GetRawInputDeviceList(IntPtr.Zero, ref ridCnt, ridSize) == UIntPtr.Zero)
        {
            var buff = Marshal.AllocHGlobal((int)ridCnt * (int)ridSize);
            Win32.GetRawInputDeviceList(buff, ref ridCnt, ridSize);

            for (int i = 0; i < (int)ridCnt; ++i)
            {
                var rid = (Win32.RAWINPUTDEVICELIST)Marshal.PtrToStructure(
                    new IntPtr((buff.ToInt64() + (int)ridSize * i)),
                    typeof(Win32.RAWINPUTDEVICELIST)
                );

                var nameSize = UIntPtr.Zero;
                Win32.GetRawInputDeviceInfo(rid.hDevice, (UIntPtr)Win32.RIDI_DEVICENAME, IntPtr.Zero, ref nameSize);

                if (nameSize != UIntPtr.Zero)
                {
                    var name = Marshal.AllocHGlobal((int)nameSize);
                    Win32.GetRawInputDeviceInfo(rid.hDevice, (UIntPtr)Win32.RIDI_DEVICENAME, name, ref nameSize);
                    string rid_id = (string)Marshal.PtrToStringAnsi(name);

                    // filter Terminal Services and Remote Desktop devices.
                    if (!rid_id.ToUpper().Contains("ROOT"))
                    {
                        yield return new Device()
                        {
                            Handle = rid.hDevice,
                            ID = rid_id,
                            Type = (Type)rid.dwType,
                            Description = GetRawInputDeviceDescription(rid_id)
                        };

                        Marshal.FreeHGlobal(name);
                    }
                }
            }

            Marshal.FreeHGlobal(buff);
        }
        else
            throw new ApplicationException("An error occurred while retrieving a list of raw input devices");
    }

    public static void Register(IntPtr hwnd, REGISTERCLASS[] regs)
    {
        Debug.Assert(hwnd != IntPtr.Zero);

        // Usage Pages and Usages:
        // http://www.usb.org/developers/devclass_docs/Hut1_12.pdf

        var rid = new Win32.RAWINPUTDEVICE[regs.Length];
        for (int i = 0; i < regs.Length; ++i)
        {
            rid[i].dwFlags = (uint)regs[i].flags;
            rid[i].usUsage = regs[i].usage;
            rid[i].usUsagePage = (ushort)regs[i].usagePage;
            rid[i].hwndTarget = hwnd;
        }

        if (Win32.RegisterRawInputDevices(rid, (UIntPtr)rid.Length, (UIntPtr)Marshal.SizeOf(typeof(Win32.RAWINPUTDEVICE))) == IntPtr.Zero)
            throw new ApplicationException("Failed to register raw input devices");
    }

    public class Device
    {
        public static bool operator ==(Device x, Device y) { if ((object)x != null & (object)y != null) { return x.Handle == y.Handle; } else return (object)x == null && (object)y == null; }
        public static bool operator !=(Device x, Device y) { return !(x == y); }

        public override bool Equals(object obj) { return this == (Device)obj; }
        public override int GetHashCode() { return base.GetHashCode(); }

        public IntPtr Handle { get; set; }
        public Type Type { get; set; }
        public string ID { get; set; }
        public string Description { get; set; }
    }

    public struct HIDDATA
    {
        public uint size;
        public uint count;
        public byte[] raw;
    }

    public struct KEYBOARDDATA
    {
        public ushort makeCode;
        public KeyboardFlag flags;
        public ushort vKey;
        public MessageContext message;
        public uint extraInfo;
    }

    public struct MOUSEDATA
    {
        public MouseFlag flags;
        public MouseTransition transitions;
        public ushort wheelDelta;
        public int motionX;
        public int motionY;
        public uint extraInfo;
    }

    public struct REGISTERCLASS
    {
        public UsagePage usagePage;
        public ushort usage;
        public ModeFlag flags;
    }

    public enum KeyboardFlag : ushort
    {
        KeyUp = Win32.RI_KEY_BREAK,
        KeyDown = Win32.RI_KEY_MAKE,
        KeyLeft = Win32.RI_KEY_E0,
        KeyRight = Win32.RI_KEY_E1
    }

    public enum MouseFlag : ushort
    {
        AttributesChanged = Win32.MOUSE_ATTRIBUTES_CHANGED,
        MoveRelative = Win32.MOUSE_MOVE_RELATIVE,
        MoveAbsolute = Win32.MOUSE_MOVE_ABSOLUTE,
        VirtualDesktop = Win32.MOUSE_VIRTUAL_DESKTOP
    }

    public enum MouseTransition : ushort
    {
        LeftButtonDown = Win32.RI_MOUSE_LEFT_BUTTON_DOWN,
        LeftButtonUp = Win32.RI_MOUSE_LEFT_BUTTON_UP,
        MiddleButtonDown = Win32.RI_MOUSE_MIDDLE_BUTTON_DOWN,
        MiddleButtonUp = Win32.RI_MOUSE_MIDDLE_BUTTON_UP,
        RightButtonDown = Win32.RI_MOUSE_RIGHT_BUTTON_DOWN,
        RightButtonUp = Win32.RI_MOUSE_RIGHT_BUTTON_UP,
        XButton1Down = Win32.RI_MOUSE_BUTTON_4_DOWN,
        XButton1Up = Win32.RI_MOUSE_BUTTON_4_UP,
        XButton2Down = Win32.RI_MOUSE_BUTTON_5_DOWN,
        XButton2Up = Win32.RI_MOUSE_BUTTON_5_UP,
        MouseWheel = Win32.RI_MOUSE_WHEEL
    }

    public enum CommandFlag
    {
        Header = Win32.RID_HEADER,
        Input = Win32.RID_INPUT
    }

    public enum ModeFlag : uint
    {
        Default = 0,
        ApplicationKeys = Win32.RIDEV_APPKEYS,
        CaptureMouse = Win32.RIDEV_CAPTUREMOUSE,
        DeviceNotify = Win32.RIDEV_DEVNOTIFY,
        Exclude = Win32.RIDEV_EXCLUDE,
        ExcludeInputSink = Win32.RIDEV_EXINPUTSINK,
        InputSink = Win32.RIDEV_INPUTSINK,
        NoHotKeys = Win32.RIDEV_NOHOTKEYS,
        NoLegacy = Win32.RIDEV_NOLEGACY,
        PageOnly = Win32.RIDEV_PAGEONLY,
        Remove = Win32.RIDEV_REMOVE
    };

    public enum UsagePage : ushort
    {
        Undefined = 0x00,
        GenericDesktopControls = 0x01,
        SimulationControls = 0x02,
        VRControls = 0x03,
        SportControls = 0x04,
        GameControls = 0x05,
        GenericDeviceControls = 0x06,
        Keyboard = 0x07,
        Keypad = Keyboard,
        LEDs = 0x08,
        Button = 0x09,
        Ordinal = 0x0a,
        Telephony = 0x0b,
        Consumer = 0x0c,
        Digitizer = 0x0d,
        PIDPage = 0x0f,
        Unicode = 0x10,
        AlphanumericDisplay = 0x14,
        MedicalInstruments = 0x40,
        MonitorPage0 = 0x80,
        MonitorPage1 = 0x81,
        MonitorPage2 = 0x82,
        MonitorPage3 = 0x83,
        PowerPage0 = 0x84,
        PowerPage1 = 0x85,
        PowerPage2 = 0x86,
        PowerPage3 = 0x87,
        BarCodeScannerPages = 0x8c,
        Scale = 0x8d,
        MagneticStripeReadingDevices = 0x8e,
        ReservedPointofSalePages = 0x8f,
        CameraControlPage = 0x90,
        ArcadePage = 0x91
    }

    /// <see cref="http://www.usb.org/developers/devclass_docs/pos1_02.pdf"/>
    public enum BarCodeScannerPages : ushort
    {
        BarCodeScanner = 0x0002
    }

    public enum Type : uint
    {
        Mouse = Win32.RIM_TYPEMOUSE,
        Keyboard = Win32.RIM_TYPEKEYBOARD,
        HID = Win32.RIM_TYPEHID
    }

    private static string GetRawInputDeviceDescription(string deviceid)
    {
        string[] id = deviceid.Substring(4).Split('#');

        // get registry entry by appropriate key
        return ((string)Registry.LocalMachine.OpenSubKey(string.Format(
            @"System\CurrentControlSet\Enum\{0}\{1}\{2}",
            id[0], id[1], id[2]), false
        ).GetValue("DeviceDesc")).Split(';')[1];
    }
}

class Win32 导入使用的Win32 API 函数并包含它们使用的一些常量:

public static class Win32
{
    // mouse state flags
    public const ushort MOUSE_ATTRIBUTES_CHANGED = 4, // Mouse attributes changed; application needs to query the mouse attributes.
                        MOUSE_MOVE_RELATIVE = 0, // Mouse movement data is relative to the last mouse position.
                        MOUSE_MOVE_ABSOLUTE = 1, // Mouse movement data is based on absolute position.
                        MOUSE_VIRTUAL_DESKTOP = 2; // Mouse coordinates are mapped to the virtual desktop (for a multiple monitor system).

    // mouse transition state flags
    public const ushort RI_MOUSE_LEFT_BUTTON_DOWN = 0x0001, // Left button changed to down.
                        RI_MOUSE_LEFT_BUTTON_UP = 0x0002, // Left button changed to up.
                        RI_MOUSE_MIDDLE_BUTTON_DOWN = 0x0010, // Middle button changed to down.
                        RI_MOUSE_MIDDLE_BUTTON_UP = 0x0020, // Middle button changed to up.
                        RI_MOUSE_RIGHT_BUTTON_DOWN = 0x0004, // Right button changed to down.
                        RI_MOUSE_RIGHT_BUTTON_UP = 0x0008, // Right button changed to up.
                        RI_MOUSE_BUTTON_1_DOWN = 0x0001, // RI_MOUSE_LEFT_BUTTON_DOWN
                        RI_MOUSE_BUTTON_1_UP = 0x0002, // RI_MOUSE_LEFT_BUTTON_UP
                        RI_MOUSE_BUTTON_2_DOWN = 0x0004, // RI_MOUSE_RIGHT_BUTTON_DOWN
                        RI_MOUSE_BUTTON_2_UP = 0x0008, // RI_MOUSE_RIGHT_BUTTON_UP
                        RI_MOUSE_BUTTON_3_DOWN = 0x0010, // RI_MOUSE_MIDDLE_BUTTON_DOWN
                        RI_MOUSE_BUTTON_3_UP = 0x0020, // RI_MOUSE_MIDDLE_BUTTON_UP
                        RI_MOUSE_BUTTON_4_DOWN = 0x0040, // XBUTTON1 changed to down.
                        RI_MOUSE_BUTTON_4_UP = 0x0080, // XBUTTON1 changed to up.
                        RI_MOUSE_BUTTON_5_DOWN = 0x0100, // XBUTTON2 changed to down.
                        RI_MOUSE_BUTTON_5_UP = 0x0200, // XBUTTON2 changed to up.
                        RI_MOUSE_WHEEL = 0x0400; // Raw input comes from a mouse wheel. The wheel delta is stored in usButtonData.

    // keyboard scan code flags
    public const ushort RI_KEY_BREAK = 1,
                        RI_KEY_E0 = 2,
                        RI_KEY_E1 = 4,
                        RI_KEY_MAKE = 0;

    // device types
    public const int RIM_TYPEMOUSE = 0,
                     RIM_TYPEKEYBOARD = 1,
                     RIM_TYPEHID = 2;

    public const int RIDI_PREPARSEDDATA = 0x20000005,
                     RIDI_DEVICENAME = 0x20000007, // the return valus is the character length, not the byte size
                     RIDI_DEVICEINFO = 0x2000000b;

    // mode flags
    public const int RIDEV_REMOVE = 0x00000001,
                     RIDEV_EXCLUDE = 0x00000010,
                     RIDEV_PAGEONLY = 0x00000020,
                     RIDEV_NOLEGACY = 0x00000030,
                     RIDEV_INPUTSINK = 0x00000100,
                     RIDEV_CAPTUREMOUSE = 0x00000200, // effective when mouse nolegacy is specified, otherwise it would be an error
                     RIDEV_NOHOTKEYS = 0x00000200, // effective for keyboard.
                     RIDEV_APPKEYS = 0x00000400, // effective for keyboard.
                     RIDEV_EXINPUTSINK = 0x00001000,
                     RIDEV_DEVNOTIFY = 0x00002000,
                     RIDEV_EXMODEMASK = 0x000000F0;

    // command flag
    public const int RID_HEADER = 0x10000005,
                     RID_INPUT = 0x10000003;    

    /// <summary>
    /// Contains information about a raw input device.
    /// </summary>
    /// <remarks>
    /// typedef struct tagRAWINPUTDEVICELIST {
    ///     HANDLE hDevice;
    ///     DWORD  dwType;
    /// } RAWINPUTDEVICELIST, *PRAWINPUTDEVICELIST;
    /// </remarks>
    [StructLayout(LayoutKind.Sequential)]
    public struct RAWINPUTDEVICELIST
    {
        public IntPtr hDevice;
        [MarshalAs(UnmanagedType.U4)]
        public uint dwType;
    }

    /// <summary>
    /// Defines information for the raw input devices.
    /// </summary>
    /// <remarks>
    /// typedef struct tagRAWINPUTDEVICE {
    ///     USHORT usUsagePage;
    ///     USHORT usUsage;
    ///     DWORD  dwFlags;
    ///     HWND   hwndTarget;
    /// } RAWINPUTDEVICE, *PRAWINPUTDEVICE, *LPRAWINPUTDEVICE;
    /// </remarks>
    [StructLayout(LayoutKind.Sequential)]
    public struct RAWINPUTDEVICE
    {
        [MarshalAs(UnmanagedType.U2)]
        public ushort usUsagePage;
        [MarshalAs(UnmanagedType.U2)]
        public ushort usUsage;
        [MarshalAs(UnmanagedType.U4)]
        public uint dwFlags;
        public IntPtr hwndTarget;
    }

    /// <summary>
    /// Contains information about the state of the mouse.
    /// </summary>
    /// <remarks>
    /// typedef struct tagRAWMOUSE {
    ///     USHORT usFlags;
    ///     union {
    ///         ULONG  ulButtons;
    ///         struct {
    ///             USHORT usButtonFlags;
    ///             USHORT usButtonData;
    ///         };
    ///     };
    ///     ULONG  ulRawButtons;
    ///     LONG   lLastX;
    ///     LONG   lLastY;
    ///     ULONG  ulExtraInformation;
    /// } RAWMOUSE, *PRAWMOUSE, *LPRAWMOUSE;
    /// </remarks>
    [StructLayout(LayoutKind.Explicit)]
    public struct RAWMOUSE
    {
        [FieldOffset(0), MarshalAs(UnmanagedType.U2)]
        public ushort usFlags;
        [FieldOffset(4), MarshalAs(UnmanagedType.U4)]
        public uint ulButtons;
        [FieldOffset(4), MarshalAs(UnmanagedType.U2)]
        public ushort usButtonFlags;
        [FieldOffset(6), MarshalAs(UnmanagedType.U2)]
        public ushort usButtonData;
        [FieldOffset(8), MarshalAs(UnmanagedType.U4)]
        public uint ulRawButtons;
        [FieldOffset(12), MarshalAs(UnmanagedType.I4)]
        public int lLastX;
        [FieldOffset(16), MarshalAs(UnmanagedType.I4)]
        public int lLastY;
        [FieldOffset(20), MarshalAs(UnmanagedType.U4)]
        public uint ulExtraInformation;
    }

    /// <summary>
    /// Contains information about the state of the keyboard.
    /// </summary>
    /// <remarks>
    /// typedef struct tagRAWKEYBOARD {
    ///     USHORT MakeCode;
    ///     USHORT Flags;
    ///     USHORT Reserved;
    ///     USHORT VKey;
    ///     UINT   Message;
    ///     ULONG  ExtraInformation;
    /// } RAWKEYBOARD, *PRAWKEYBOARD, *LPRAWKEYBOARD;
    /// </remarks>
    [StructLayout(LayoutKind.Sequential)]
    public struct RAWKEYBOARD
    {
        [MarshalAs(UnmanagedType.U2)]
        public ushort MakeCode;
        [MarshalAs(UnmanagedType.U2)]
        public ushort Flags;
        [MarshalAs(UnmanagedType.U2)]
        public ushort Reserved;
        [MarshalAs(UnmanagedType.U2)]
        public ushort VKey;
        [MarshalAs(UnmanagedType.SysUInt)]
        public UIntPtr Message;
        [MarshalAs(UnmanagedType.U4)]
        public uint ExtraInformation;
    }

    /// <summary>
    /// Describes the format of the raw input from a Human Interface Device (HID).
    /// </summary>
    /// <remarks>
    /// typedef struct tagRAWHID {
    ///     DWORD dwSizeHid;
    ///     DWORD dwCount;
    ///     BYTE  bRawData[1];
    /// } RAWHID, *PRAWHID, *LPRAWHID;
    /// </remarks>
    [StructLayout(LayoutKind.Sequential)]
    public struct RAWHID
    {
        [MarshalAs(UnmanagedType.U4)]
        public uint dwSizeHid;
        [MarshalAs(UnmanagedType.U4)]
        public uint dwCount;
    }

    /// <summary>
    /// Contains the header information that is part of the raw input data.
    /// </summary>
    /// <remarks>
    /// typedef struct tagRAWINPUTHEADER {
    ///     DWORD  dwType;
    ///     DWORD  dwSize;
    ///     HANDLE hDevice;
    ///     WPARAM wParam;
    /// } RAWINPUTHEADER, *PRAWINPUTHEADER;
    /// </remarks>
    [StructLayout(LayoutKind.Sequential)]
    public struct RAWINPUTHEADER
    {
        [MarshalAs(UnmanagedType.U4)]
        public uint dwType;
        [MarshalAs(UnmanagedType.U4)]
        public uint dwSize;
        public IntPtr hDevice;
        [MarshalAs(UnmanagedType.SysUInt)]
        public UIntPtr wParam;
    }

    /// <summary>
    /// Contains the raw input from a device.
    /// </summary>
    /// <remarks>
    /// typedef struct tagRAWINPUT {
    ///     RAWINPUTHEADER header;
    ///     union {
    ///         RAWMOUSE    mouse;
    ///         RAWKEYBOARD keyboard;
    ///         RAWHID      hid;
    ///     } data;
    /// } RAWINPUT, *PRAWINPUT, *LPRAWINPUT;
    /// </remarks>
    [StructLayout(LayoutKind.Explicit)]
    public struct RAWINPUT
    {
        [FieldOffset(0)]
        public RAWINPUTHEADER header;
#if IA32
        [FieldOffset(16)]
        public RAWMOUSE mouse;
        [FieldOffset(16)]
        public RAWKEYBOARD keyboard;
        [FieldOffset(16)]
        public RAWHID hid;
#elif INTEL64
        [FieldOffset(24)]
        public RAWMOUSE mouse;
        [FieldOffset(24)]
        public RAWKEYBOARD keyboard;
        [FieldOffset(24)]
        public RAWHID hid;
#endif
    }

    /// <summary>
    /// Defines the raw input data coming from the specified keyboard.
    /// </summary>
    /// <remarks>
    /// typedef struct tagRID_DEVICE_INFO_KEYBOARD {
    ///     DWORD dwType;
    ///     DWORD dwSubType;
    ///     DWORD dwKeyboardMode;
    ///     DWORD dwNumberOfFunctionKeys;
    ///     DWORD dwNumberOfIndicators;
    ///     DWORD dwNumberOfKeysTotal;
    /// } RID_DEVICE_INFO_KEYBOARD, *PRID_DEVICE_INFO_KEYBOARD;
    /// </remarks>
    [StructLayout(LayoutKind.Sequential)]
    public struct RID_DEVICE_INFO_KEYBOARD
    {
        [MarshalAs(UnmanagedType.U4)]
        public uint dwType;
        [MarshalAs(UnmanagedType.U4)]
        public uint dwSubType;
        [MarshalAs(UnmanagedType.U4)]
        public uint dwKeyboardMode;
        [MarshalAs(UnmanagedType.U4)]
        public uint dwNumberOfFunctionKeys;
        [MarshalAs(UnmanagedType.U4)]
        public uint dwNumberOfIndicators;
        [MarshalAs(UnmanagedType.U4)]
        public uint dwNumberOfKeysTotal;
    }

    /// <summary>
    /// Defines the raw input data coming from the specified mouse.
    /// </summary>
    /// <remarks>
    /// typedef struct tagRID_DEVICE_INFO_MOUSE {
    ///     DWORD dwId;
    ///     DWORD dwNumberOfButtons;
    ///     DWORD dwSampleRate;
    ///     BOOL  fHasHorizontalWheel;
    /// } RID_DEVICE_INFO_MOUSE, *PRID_DEVICE_INFO_MOUSE;
    /// </remarks>
    [StructLayout(LayoutKind.Sequential)]
    public struct RID_DEVICE_INFO_MOUSE
    {
        [MarshalAs(UnmanagedType.U4)]
        public uint dwId;
        [MarshalAs(UnmanagedType.U4)]
        public uint dwNumberOfButtons;
        [MarshalAs(UnmanagedType.U4)]
        public uint dwSampleRate;
        [MarshalAs(UnmanagedType.SysInt)]
        public IntPtr fHasHorizontalWheel;
    }

    /// <summary>
    /// Defines the raw input data coming from the specified Human Interface Device (HID).
    /// </summary>
    /// <remarks>
    /// typedef struct tagRID_DEVICE_INFO_HID {
    ///     DWORD  dwVendorId;
    ///     DWORD  dwProductId;
    ///     DWORD  dwVersionNumber;
    ///     USHORT usUsagePage;
    ///     USHORT usUsage;
    /// } RID_DEVICE_INFO_HID, *PRID_DEVICE_INFO_HID;
    /// </remarks>
    [StructLayout(LayoutKind.Sequential)]
    public struct RID_DEVICE_INFO_HID
    {
        [MarshalAs(UnmanagedType.U4)]
        public uint dwVendorId;
        [MarshalAs(UnmanagedType.U4)]
        public uint dwProductId;
        [MarshalAs(UnmanagedType.U4)]
        public uint dwVersionNumber;
        [MarshalAs(UnmanagedType.U2)]
        public ushort usUsagePage;
        [MarshalAs(UnmanagedType.U2)]
        public ushort usUsage;
    }

    /// <summary>
    /// Defines the raw input data coming from any device.
    /// </summary>
    /// <remarks>
    /// typedef struct tagRID_DEVICE_INFO {
    ///     DWORD cbSize;
    ///     DWORD dwType;
    ///     union {
    ///         RID_DEVICE_INFO_MOUSE    mouse;
    ///         RID_DEVICE_INFO_KEYBOARD keyboard;
    ///         RID_DEVICE_INFO_HID      hid;
    ///     } ;
    /// } RID_DEVICE_INFO, *PRID_DEVICE_INFO, *LPRID_DEVICE_INFO;
    /// </remarks>
    [StructLayout(LayoutKind.Explicit)]
    public struct RID_DEVICE_INFO
    {
        [FieldOffset(0), MarshalAs(UnmanagedType.U4)]
        public uint cbSize;
        [FieldOffset(4), MarshalAs(UnmanagedType.U4)]
        public uint dwType;
        [FieldOffset(8)]
        public RID_DEVICE_INFO_MOUSE mouse;
        [FieldOffset(8)]
        public RID_DEVICE_INFO_KEYBOARD keyboard;
        [FieldOffset(8)]
        public RID_DEVICE_INFO_HID hid;
    }

    /// <summary>
    /// The POINT structure defines the x- and y- coordinates of a point.
    /// </summary>
    /// <remarks>
    /// typedef struct tagPOINT {
    ///     LONG x;
    ///     LONG y;
    /// } POINT, *PPOINT;
    /// </remarks>
    [StructLayout(LayoutKind.Sequential)]
    public struct POINT
    {
        [MarshalAs(UnmanagedType.U4)]
        public long x;
        [MarshalAs(UnmanagedType.U4)]
        public long y;
    } 

    /// <summary>
    /// Contains message information from a thread's message queue.
    /// </summary>
    /// <remarks>
    /// typedef struct tagMSG {
    ///     HWND   hwnd;
    ///     UINT   message;
    ///     WPARAM wParam;
    ///     LPARAM lParam;
    ///     DWORD  time;
    ///     POINT  pt;
    /// } MSG, *PMSG, *LPMSG;
    /// </remarks>
    [StructLayout(LayoutKind.Sequential)]
    public struct MSG
    {
        public IntPtr hwnd;
        [MarshalAs(UnmanagedType.SysUInt)]
        public MessageContext message;
        public IntPtr wParam;
        public IntPtr lParam;
        [MarshalAs(UnmanagedType.U4)]
        public ulong time;
        public POINT pt;
    }

    [DllImport("user32.dll")]
    public static extern bool SetForegroundWindow(IntPtr hWnd);     
    // ...
    // Import other API functions used above
    // ...
}

I've discarded my approach to realize this with POS for .NET. It's almost easier to do it yourself, in so far as you the scanner handling it the only relevant part of the framework you were interested in. Here's basically what I'm using:

public class RawInput
{
    private static IntPtr DispatchMessage(IntPtr lParam, IEnumerable<IntPtr> fromDevices, ref object data)
    {
        var dataSize = UIntPtr.Zero;
        if (Win32.GetRawInputData(lParam, (UIntPtr)CommandFlag.Input, IntPtr.Zero, ref dataSize, (UIntPtr)Marshal.SizeOf(typeof(Win32.RAWINPUTHEADER))) == UIntPtr.Zero)
        {
            var buff = Marshal.AllocHGlobal((int)dataSize);
            var outSize = Win32.GetRawInputData(lParam, (UIntPtr)CommandFlag.Input, buff, ref dataSize, (UIntPtr)Marshal.SizeOf(typeof(Win32.RAWINPUTHEADER)));

            Debug.Assert(outSize == dataSize);
            var input = (Win32.RAWINPUT)Marshal.PtrToStructure(buff, typeof(Win32.RAWINPUT));

            var hDevice = IntPtr.Zero;
            if (fromDevices == null)
                hDevice = input.header.hDevice;
            else
                hDevice = fromDevices.FirstOrDefault(h => h == input.header.hDevice);

            if (hDevice != IntPtr.Zero)
            {
                switch ((Type)input.header.dwType)
                {
                    case Type.HID:
                        var hidData = new HIDDATA()
                        {
                            count = input.hid.dwCount,
                            size = input.hid.dwSizeHid,
                            raw = new byte[input.hid.dwCount * input.hid.dwSizeHid]
                        };

                        Marshal.Copy(
                            new IntPtr(
                                buff.ToInt64() +
                                Marshal.SizeOf(typeof(Win32.RAWINPUTHEADER)) +
                                Marshal.SizeOf(typeof(Win32.RAWHID))
                            ),
                            hidData.raw, 0, hidData.raw.Length
                        );

                        data = hidData;
                        break;
                    case Type.Keyboard:
                        data = new KEYBOARDDATA
                        {
                            makeCode = input.keyboard.MakeCode,
                            flags = (KeyboardFlag)input.keyboard.Flags,
                            vKey = input.keyboard.VKey,
                            message = (MessageContext)input.keyboard.Message,
                            extraInfo = input.keyboard.ExtraInformation
                        };
                        break;
                    case Type.Mouse:
                        var mouseData = new MOUSEDATA
                        {
                            extraInfo = input.mouse.ulExtraInformation,
                            flags = (MouseFlag)input.mouse.usFlags,
                            transitions = (MouseTransition)input.mouse.usButtonFlags,
                            motionX = input.mouse.lLastX,
                            motionY = input.mouse.lLastY
                        };

                        if (mouseData.transitions == MouseTransition.MouseWheel)
                            mouseData.wheelDelta = input.mouse.usButtonData;
                        data = mouseData;
                        break;
                }
            }

            Marshal.FreeHGlobal(buff);
            return hDevice;
        }
        else
            throw new ApplicationException("An error occurred while receiving raw input data.");
    }

    public static bool DispatchMessage(Win32.MSG message, IEnumerable<Device> fromDevices, ref Device source, ref object data)
    {
        var hDevice = IntPtr.Zero;
        if (message.message == MessageContext.Input)
        {
            if (fromDevices != null)
            {
                hDevice = DispatchMessage(message.lParam, fromDevices.Select(h => h.Handle), ref data);
                if (hDevice != IntPtr.Zero)
                    source = fromDevices.First(h => h.Handle == hDevice);
            }
            else
            {
                Func<Device> getRawInputDeviceInfo = () =>
                {
                    var name_size = UIntPtr.Zero;
                    Win32.GetRawInputDeviceInfo(hDevice, (UIntPtr)Win32.RIDI_DEVICENAME, IntPtr.Zero, ref name_size);

                    if (name_size != UIntPtr.Zero)
                    {
                        var name = Marshal.AllocHGlobal((int)name_size);
                        Win32.GetRawInputDeviceInfo(hDevice, (UIntPtr)Win32.RIDI_DEVICENAME, name, ref name_size);
                        string rid_name = (string)Marshal.PtrToStringAnsi(name);

                        var ridSize = (UIntPtr)Marshal.SizeOf(typeof(Win32.RID_DEVICE_INFO));
                        var buff = Marshal.AllocHGlobal((int)ridSize);
                        var outSize = Win32.GetRawInputDeviceInfo(hDevice, (UIntPtr)Win32.RIDI_DEVICEINFO, buff, ref ridSize);
                        Debug.Assert(outSize == ridSize);

                        var rid = (Win32.RID_DEVICE_INFO)Marshal.PtrToStructure(buff, typeof(Win32.RID_DEVICE_INFO));

                        var device = new Device()
                        {
                            Handle = hDevice,
                            ID = rid_name,
                            Type = (Type)rid.dwType,
                            Description = GetRawInputDeviceDescription(rid_name)
                        };

                        Marshal.FreeHGlobal(name);
                        return device;
                    }

                    return null;
                };

                hDevice = DispatchMessage(message.lParam, null, ref data);
                if (hDevice != IntPtr.Zero)
                    source = getRawInputDeviceInfo();
            }
        }

        return hDevice != IntPtr.Zero;
    }

    public static IEnumerable<Device> EnumerateDevices()
    {
        var ridSize = (UIntPtr)Marshal.SizeOf(typeof(Win32.RAWINPUTDEVICELIST));
        var ridCnt = UIntPtr.Zero;
        var list = new List<Device>();

        if (Win32.GetRawInputDeviceList(IntPtr.Zero, ref ridCnt, ridSize) == UIntPtr.Zero)
        {
            var buff = Marshal.AllocHGlobal((int)ridCnt * (int)ridSize);
            Win32.GetRawInputDeviceList(buff, ref ridCnt, ridSize);

            for (int i = 0; i < (int)ridCnt; ++i)
            {
                var rid = (Win32.RAWINPUTDEVICELIST)Marshal.PtrToStructure(
                    new IntPtr((buff.ToInt64() + (int)ridSize * i)),
                    typeof(Win32.RAWINPUTDEVICELIST)
                );

                var nameSize = UIntPtr.Zero;
                Win32.GetRawInputDeviceInfo(rid.hDevice, (UIntPtr)Win32.RIDI_DEVICENAME, IntPtr.Zero, ref nameSize);

                if (nameSize != UIntPtr.Zero)
                {
                    var name = Marshal.AllocHGlobal((int)nameSize);
                    Win32.GetRawInputDeviceInfo(rid.hDevice, (UIntPtr)Win32.RIDI_DEVICENAME, name, ref nameSize);
                    string rid_id = (string)Marshal.PtrToStringAnsi(name);

                    // filter Terminal Services and Remote Desktop devices.
                    if (!rid_id.ToUpper().Contains("ROOT"))
                    {
                        yield return new Device()
                        {
                            Handle = rid.hDevice,
                            ID = rid_id,
                            Type = (Type)rid.dwType,
                            Description = GetRawInputDeviceDescription(rid_id)
                        };

                        Marshal.FreeHGlobal(name);
                    }
                }
            }

            Marshal.FreeHGlobal(buff);
        }
        else
            throw new ApplicationException("An error occurred while retrieving a list of raw input devices");
    }

    public static void Register(IntPtr hwnd, REGISTERCLASS[] regs)
    {
        Debug.Assert(hwnd != IntPtr.Zero);

        // Usage Pages and Usages:
        // http://www.usb.org/developers/devclass_docs/Hut1_12.pdf

        var rid = new Win32.RAWINPUTDEVICE[regs.Length];
        for (int i = 0; i < regs.Length; ++i)
        {
            rid[i].dwFlags = (uint)regs[i].flags;
            rid[i].usUsage = regs[i].usage;
            rid[i].usUsagePage = (ushort)regs[i].usagePage;
            rid[i].hwndTarget = hwnd;
        }

        if (Win32.RegisterRawInputDevices(rid, (UIntPtr)rid.Length, (UIntPtr)Marshal.SizeOf(typeof(Win32.RAWINPUTDEVICE))) == IntPtr.Zero)
            throw new ApplicationException("Failed to register raw input devices");
    }

    public class Device
    {
        public static bool operator ==(Device x, Device y) { if ((object)x != null & (object)y != null) { return x.Handle == y.Handle; } else return (object)x == null && (object)y == null; }
        public static bool operator !=(Device x, Device y) { return !(x == y); }

        public override bool Equals(object obj) { return this == (Device)obj; }
        public override int GetHashCode() { return base.GetHashCode(); }

        public IntPtr Handle { get; set; }
        public Type Type { get; set; }
        public string ID { get; set; }
        public string Description { get; set; }
    }

    public struct HIDDATA
    {
        public uint size;
        public uint count;
        public byte[] raw;
    }

    public struct KEYBOARDDATA
    {
        public ushort makeCode;
        public KeyboardFlag flags;
        public ushort vKey;
        public MessageContext message;
        public uint extraInfo;
    }

    public struct MOUSEDATA
    {
        public MouseFlag flags;
        public MouseTransition transitions;
        public ushort wheelDelta;
        public int motionX;
        public int motionY;
        public uint extraInfo;
    }

    public struct REGISTERCLASS
    {
        public UsagePage usagePage;
        public ushort usage;
        public ModeFlag flags;
    }

    public enum KeyboardFlag : ushort
    {
        KeyUp = Win32.RI_KEY_BREAK,
        KeyDown = Win32.RI_KEY_MAKE,
        KeyLeft = Win32.RI_KEY_E0,
        KeyRight = Win32.RI_KEY_E1
    }

    public enum MouseFlag : ushort
    {
        AttributesChanged = Win32.MOUSE_ATTRIBUTES_CHANGED,
        MoveRelative = Win32.MOUSE_MOVE_RELATIVE,
        MoveAbsolute = Win32.MOUSE_MOVE_ABSOLUTE,
        VirtualDesktop = Win32.MOUSE_VIRTUAL_DESKTOP
    }

    public enum MouseTransition : ushort
    {
        LeftButtonDown = Win32.RI_MOUSE_LEFT_BUTTON_DOWN,
        LeftButtonUp = Win32.RI_MOUSE_LEFT_BUTTON_UP,
        MiddleButtonDown = Win32.RI_MOUSE_MIDDLE_BUTTON_DOWN,
        MiddleButtonUp = Win32.RI_MOUSE_MIDDLE_BUTTON_UP,
        RightButtonDown = Win32.RI_MOUSE_RIGHT_BUTTON_DOWN,
        RightButtonUp = Win32.RI_MOUSE_RIGHT_BUTTON_UP,
        XButton1Down = Win32.RI_MOUSE_BUTTON_4_DOWN,
        XButton1Up = Win32.RI_MOUSE_BUTTON_4_UP,
        XButton2Down = Win32.RI_MOUSE_BUTTON_5_DOWN,
        XButton2Up = Win32.RI_MOUSE_BUTTON_5_UP,
        MouseWheel = Win32.RI_MOUSE_WHEEL
    }

    public enum CommandFlag
    {
        Header = Win32.RID_HEADER,
        Input = Win32.RID_INPUT
    }

    public enum ModeFlag : uint
    {
        Default = 0,
        ApplicationKeys = Win32.RIDEV_APPKEYS,
        CaptureMouse = Win32.RIDEV_CAPTUREMOUSE,
        DeviceNotify = Win32.RIDEV_DEVNOTIFY,
        Exclude = Win32.RIDEV_EXCLUDE,
        ExcludeInputSink = Win32.RIDEV_EXINPUTSINK,
        InputSink = Win32.RIDEV_INPUTSINK,
        NoHotKeys = Win32.RIDEV_NOHOTKEYS,
        NoLegacy = Win32.RIDEV_NOLEGACY,
        PageOnly = Win32.RIDEV_PAGEONLY,
        Remove = Win32.RIDEV_REMOVE
    };

    public enum UsagePage : ushort
    {
        Undefined = 0x00,
        GenericDesktopControls = 0x01,
        SimulationControls = 0x02,
        VRControls = 0x03,
        SportControls = 0x04,
        GameControls = 0x05,
        GenericDeviceControls = 0x06,
        Keyboard = 0x07,
        Keypad = Keyboard,
        LEDs = 0x08,
        Button = 0x09,
        Ordinal = 0x0a,
        Telephony = 0x0b,
        Consumer = 0x0c,
        Digitizer = 0x0d,
        PIDPage = 0x0f,
        Unicode = 0x10,
        AlphanumericDisplay = 0x14,
        MedicalInstruments = 0x40,
        MonitorPage0 = 0x80,
        MonitorPage1 = 0x81,
        MonitorPage2 = 0x82,
        MonitorPage3 = 0x83,
        PowerPage0 = 0x84,
        PowerPage1 = 0x85,
        PowerPage2 = 0x86,
        PowerPage3 = 0x87,
        BarCodeScannerPages = 0x8c,
        Scale = 0x8d,
        MagneticStripeReadingDevices = 0x8e,
        ReservedPointofSalePages = 0x8f,
        CameraControlPage = 0x90,
        ArcadePage = 0x91
    }

    /// <see cref="http://www.usb.org/developers/devclass_docs/pos1_02.pdf"/>
    public enum BarCodeScannerPages : ushort
    {
        BarCodeScanner = 0x0002
    }

    public enum Type : uint
    {
        Mouse = Win32.RIM_TYPEMOUSE,
        Keyboard = Win32.RIM_TYPEKEYBOARD,
        HID = Win32.RIM_TYPEHID
    }

    private static string GetRawInputDeviceDescription(string deviceid)
    {
        string[] id = deviceid.Substring(4).Split('#');

        // get registry entry by appropriate key
        return ((string)Registry.LocalMachine.OpenSubKey(string.Format(
            @"System\CurrentControlSet\Enum\{0}\{1}\{2}",
            id[0], id[1], id[2]), false
        ).GetValue("DeviceDesc")).Split(';')[1];
    }
}

The class Win32 imports the used Win32 API functions and contains some constants used by them:

public static class Win32
{
    // mouse state flags
    public const ushort MOUSE_ATTRIBUTES_CHANGED = 4, // Mouse attributes changed; application needs to query the mouse attributes.
                        MOUSE_MOVE_RELATIVE = 0, // Mouse movement data is relative to the last mouse position.
                        MOUSE_MOVE_ABSOLUTE = 1, // Mouse movement data is based on absolute position.
                        MOUSE_VIRTUAL_DESKTOP = 2; // Mouse coordinates are mapped to the virtual desktop (for a multiple monitor system).

    // mouse transition state flags
    public const ushort RI_MOUSE_LEFT_BUTTON_DOWN = 0x0001, // Left button changed to down.
                        RI_MOUSE_LEFT_BUTTON_UP = 0x0002, // Left button changed to up.
                        RI_MOUSE_MIDDLE_BUTTON_DOWN = 0x0010, // Middle button changed to down.
                        RI_MOUSE_MIDDLE_BUTTON_UP = 0x0020, // Middle button changed to up.
                        RI_MOUSE_RIGHT_BUTTON_DOWN = 0x0004, // Right button changed to down.
                        RI_MOUSE_RIGHT_BUTTON_UP = 0x0008, // Right button changed to up.
                        RI_MOUSE_BUTTON_1_DOWN = 0x0001, // RI_MOUSE_LEFT_BUTTON_DOWN
                        RI_MOUSE_BUTTON_1_UP = 0x0002, // RI_MOUSE_LEFT_BUTTON_UP
                        RI_MOUSE_BUTTON_2_DOWN = 0x0004, // RI_MOUSE_RIGHT_BUTTON_DOWN
                        RI_MOUSE_BUTTON_2_UP = 0x0008, // RI_MOUSE_RIGHT_BUTTON_UP
                        RI_MOUSE_BUTTON_3_DOWN = 0x0010, // RI_MOUSE_MIDDLE_BUTTON_DOWN
                        RI_MOUSE_BUTTON_3_UP = 0x0020, // RI_MOUSE_MIDDLE_BUTTON_UP
                        RI_MOUSE_BUTTON_4_DOWN = 0x0040, // XBUTTON1 changed to down.
                        RI_MOUSE_BUTTON_4_UP = 0x0080, // XBUTTON1 changed to up.
                        RI_MOUSE_BUTTON_5_DOWN = 0x0100, // XBUTTON2 changed to down.
                        RI_MOUSE_BUTTON_5_UP = 0x0200, // XBUTTON2 changed to up.
                        RI_MOUSE_WHEEL = 0x0400; // Raw input comes from a mouse wheel. The wheel delta is stored in usButtonData.

    // keyboard scan code flags
    public const ushort RI_KEY_BREAK = 1,
                        RI_KEY_E0 = 2,
                        RI_KEY_E1 = 4,
                        RI_KEY_MAKE = 0;

    // device types
    public const int RIM_TYPEMOUSE = 0,
                     RIM_TYPEKEYBOARD = 1,
                     RIM_TYPEHID = 2;

    public const int RIDI_PREPARSEDDATA = 0x20000005,
                     RIDI_DEVICENAME = 0x20000007, // the return valus is the character length, not the byte size
                     RIDI_DEVICEINFO = 0x2000000b;

    // mode flags
    public const int RIDEV_REMOVE = 0x00000001,
                     RIDEV_EXCLUDE = 0x00000010,
                     RIDEV_PAGEONLY = 0x00000020,
                     RIDEV_NOLEGACY = 0x00000030,
                     RIDEV_INPUTSINK = 0x00000100,
                     RIDEV_CAPTUREMOUSE = 0x00000200, // effective when mouse nolegacy is specified, otherwise it would be an error
                     RIDEV_NOHOTKEYS = 0x00000200, // effective for keyboard.
                     RIDEV_APPKEYS = 0x00000400, // effective for keyboard.
                     RIDEV_EXINPUTSINK = 0x00001000,
                     RIDEV_DEVNOTIFY = 0x00002000,
                     RIDEV_EXMODEMASK = 0x000000F0;

    // command flag
    public const int RID_HEADER = 0x10000005,
                     RID_INPUT = 0x10000003;    

    /// <summary>
    /// Contains information about a raw input device.
    /// </summary>
    /// <remarks>
    /// typedef struct tagRAWINPUTDEVICELIST {
    ///     HANDLE hDevice;
    ///     DWORD  dwType;
    /// } RAWINPUTDEVICELIST, *PRAWINPUTDEVICELIST;
    /// </remarks>
    [StructLayout(LayoutKind.Sequential)]
    public struct RAWINPUTDEVICELIST
    {
        public IntPtr hDevice;
        [MarshalAs(UnmanagedType.U4)]
        public uint dwType;
    }

    /// <summary>
    /// Defines information for the raw input devices.
    /// </summary>
    /// <remarks>
    /// typedef struct tagRAWINPUTDEVICE {
    ///     USHORT usUsagePage;
    ///     USHORT usUsage;
    ///     DWORD  dwFlags;
    ///     HWND   hwndTarget;
    /// } RAWINPUTDEVICE, *PRAWINPUTDEVICE, *LPRAWINPUTDEVICE;
    /// </remarks>
    [StructLayout(LayoutKind.Sequential)]
    public struct RAWINPUTDEVICE
    {
        [MarshalAs(UnmanagedType.U2)]
        public ushort usUsagePage;
        [MarshalAs(UnmanagedType.U2)]
        public ushort usUsage;
        [MarshalAs(UnmanagedType.U4)]
        public uint dwFlags;
        public IntPtr hwndTarget;
    }

    /// <summary>
    /// Contains information about the state of the mouse.
    /// </summary>
    /// <remarks>
    /// typedef struct tagRAWMOUSE {
    ///     USHORT usFlags;
    ///     union {
    ///         ULONG  ulButtons;
    ///         struct {
    ///             USHORT usButtonFlags;
    ///             USHORT usButtonData;
    ///         };
    ///     };
    ///     ULONG  ulRawButtons;
    ///     LONG   lLastX;
    ///     LONG   lLastY;
    ///     ULONG  ulExtraInformation;
    /// } RAWMOUSE, *PRAWMOUSE, *LPRAWMOUSE;
    /// </remarks>
    [StructLayout(LayoutKind.Explicit)]
    public struct RAWMOUSE
    {
        [FieldOffset(0), MarshalAs(UnmanagedType.U2)]
        public ushort usFlags;
        [FieldOffset(4), MarshalAs(UnmanagedType.U4)]
        public uint ulButtons;
        [FieldOffset(4), MarshalAs(UnmanagedType.U2)]
        public ushort usButtonFlags;
        [FieldOffset(6), MarshalAs(UnmanagedType.U2)]
        public ushort usButtonData;
        [FieldOffset(8), MarshalAs(UnmanagedType.U4)]
        public uint ulRawButtons;
        [FieldOffset(12), MarshalAs(UnmanagedType.I4)]
        public int lLastX;
        [FieldOffset(16), MarshalAs(UnmanagedType.I4)]
        public int lLastY;
        [FieldOffset(20), MarshalAs(UnmanagedType.U4)]
        public uint ulExtraInformation;
    }

    /// <summary>
    /// Contains information about the state of the keyboard.
    /// </summary>
    /// <remarks>
    /// typedef struct tagRAWKEYBOARD {
    ///     USHORT MakeCode;
    ///     USHORT Flags;
    ///     USHORT Reserved;
    ///     USHORT VKey;
    ///     UINT   Message;
    ///     ULONG  ExtraInformation;
    /// } RAWKEYBOARD, *PRAWKEYBOARD, *LPRAWKEYBOARD;
    /// </remarks>
    [StructLayout(LayoutKind.Sequential)]
    public struct RAWKEYBOARD
    {
        [MarshalAs(UnmanagedType.U2)]
        public ushort MakeCode;
        [MarshalAs(UnmanagedType.U2)]
        public ushort Flags;
        [MarshalAs(UnmanagedType.U2)]
        public ushort Reserved;
        [MarshalAs(UnmanagedType.U2)]
        public ushort VKey;
        [MarshalAs(UnmanagedType.SysUInt)]
        public UIntPtr Message;
        [MarshalAs(UnmanagedType.U4)]
        public uint ExtraInformation;
    }

    /// <summary>
    /// Describes the format of the raw input from a Human Interface Device (HID).
    /// </summary>
    /// <remarks>
    /// typedef struct tagRAWHID {
    ///     DWORD dwSizeHid;
    ///     DWORD dwCount;
    ///     BYTE  bRawData[1];
    /// } RAWHID, *PRAWHID, *LPRAWHID;
    /// </remarks>
    [StructLayout(LayoutKind.Sequential)]
    public struct RAWHID
    {
        [MarshalAs(UnmanagedType.U4)]
        public uint dwSizeHid;
        [MarshalAs(UnmanagedType.U4)]
        public uint dwCount;
    }

    /// <summary>
    /// Contains the header information that is part of the raw input data.
    /// </summary>
    /// <remarks>
    /// typedef struct tagRAWINPUTHEADER {
    ///     DWORD  dwType;
    ///     DWORD  dwSize;
    ///     HANDLE hDevice;
    ///     WPARAM wParam;
    /// } RAWINPUTHEADER, *PRAWINPUTHEADER;
    /// </remarks>
    [StructLayout(LayoutKind.Sequential)]
    public struct RAWINPUTHEADER
    {
        [MarshalAs(UnmanagedType.U4)]
        public uint dwType;
        [MarshalAs(UnmanagedType.U4)]
        public uint dwSize;
        public IntPtr hDevice;
        [MarshalAs(UnmanagedType.SysUInt)]
        public UIntPtr wParam;
    }

    /// <summary>
    /// Contains the raw input from a device.
    /// </summary>
    /// <remarks>
    /// typedef struct tagRAWINPUT {
    ///     RAWINPUTHEADER header;
    ///     union {
    ///         RAWMOUSE    mouse;
    ///         RAWKEYBOARD keyboard;
    ///         RAWHID      hid;
    ///     } data;
    /// } RAWINPUT, *PRAWINPUT, *LPRAWINPUT;
    /// </remarks>
    [StructLayout(LayoutKind.Explicit)]
    public struct RAWINPUT
    {
        [FieldOffset(0)]
        public RAWINPUTHEADER header;
#if IA32
        [FieldOffset(16)]
        public RAWMOUSE mouse;
        [FieldOffset(16)]
        public RAWKEYBOARD keyboard;
        [FieldOffset(16)]
        public RAWHID hid;
#elif INTEL64
        [FieldOffset(24)]
        public RAWMOUSE mouse;
        [FieldOffset(24)]
        public RAWKEYBOARD keyboard;
        [FieldOffset(24)]
        public RAWHID hid;
#endif
    }

    /// <summary>
    /// Defines the raw input data coming from the specified keyboard.
    /// </summary>
    /// <remarks>
    /// typedef struct tagRID_DEVICE_INFO_KEYBOARD {
    ///     DWORD dwType;
    ///     DWORD dwSubType;
    ///     DWORD dwKeyboardMode;
    ///     DWORD dwNumberOfFunctionKeys;
    ///     DWORD dwNumberOfIndicators;
    ///     DWORD dwNumberOfKeysTotal;
    /// } RID_DEVICE_INFO_KEYBOARD, *PRID_DEVICE_INFO_KEYBOARD;
    /// </remarks>
    [StructLayout(LayoutKind.Sequential)]
    public struct RID_DEVICE_INFO_KEYBOARD
    {
        [MarshalAs(UnmanagedType.U4)]
        public uint dwType;
        [MarshalAs(UnmanagedType.U4)]
        public uint dwSubType;
        [MarshalAs(UnmanagedType.U4)]
        public uint dwKeyboardMode;
        [MarshalAs(UnmanagedType.U4)]
        public uint dwNumberOfFunctionKeys;
        [MarshalAs(UnmanagedType.U4)]
        public uint dwNumberOfIndicators;
        [MarshalAs(UnmanagedType.U4)]
        public uint dwNumberOfKeysTotal;
    }

    /// <summary>
    /// Defines the raw input data coming from the specified mouse.
    /// </summary>
    /// <remarks>
    /// typedef struct tagRID_DEVICE_INFO_MOUSE {
    ///     DWORD dwId;
    ///     DWORD dwNumberOfButtons;
    ///     DWORD dwSampleRate;
    ///     BOOL  fHasHorizontalWheel;
    /// } RID_DEVICE_INFO_MOUSE, *PRID_DEVICE_INFO_MOUSE;
    /// </remarks>
    [StructLayout(LayoutKind.Sequential)]
    public struct RID_DEVICE_INFO_MOUSE
    {
        [MarshalAs(UnmanagedType.U4)]
        public uint dwId;
        [MarshalAs(UnmanagedType.U4)]
        public uint dwNumberOfButtons;
        [MarshalAs(UnmanagedType.U4)]
        public uint dwSampleRate;
        [MarshalAs(UnmanagedType.SysInt)]
        public IntPtr fHasHorizontalWheel;
    }

    /// <summary>
    /// Defines the raw input data coming from the specified Human Interface Device (HID).
    /// </summary>
    /// <remarks>
    /// typedef struct tagRID_DEVICE_INFO_HID {
    ///     DWORD  dwVendorId;
    ///     DWORD  dwProductId;
    ///     DWORD  dwVersionNumber;
    ///     USHORT usUsagePage;
    ///     USHORT usUsage;
    /// } RID_DEVICE_INFO_HID, *PRID_DEVICE_INFO_HID;
    /// </remarks>
    [StructLayout(LayoutKind.Sequential)]
    public struct RID_DEVICE_INFO_HID
    {
        [MarshalAs(UnmanagedType.U4)]
        public uint dwVendorId;
        [MarshalAs(UnmanagedType.U4)]
        public uint dwProductId;
        [MarshalAs(UnmanagedType.U4)]
        public uint dwVersionNumber;
        [MarshalAs(UnmanagedType.U2)]
        public ushort usUsagePage;
        [MarshalAs(UnmanagedType.U2)]
        public ushort usUsage;
    }

    /// <summary>
    /// Defines the raw input data coming from any device.
    /// </summary>
    /// <remarks>
    /// typedef struct tagRID_DEVICE_INFO {
    ///     DWORD cbSize;
    ///     DWORD dwType;
    ///     union {
    ///         RID_DEVICE_INFO_MOUSE    mouse;
    ///         RID_DEVICE_INFO_KEYBOARD keyboard;
    ///         RID_DEVICE_INFO_HID      hid;
    ///     } ;
    /// } RID_DEVICE_INFO, *PRID_DEVICE_INFO, *LPRID_DEVICE_INFO;
    /// </remarks>
    [StructLayout(LayoutKind.Explicit)]
    public struct RID_DEVICE_INFO
    {
        [FieldOffset(0), MarshalAs(UnmanagedType.U4)]
        public uint cbSize;
        [FieldOffset(4), MarshalAs(UnmanagedType.U4)]
        public uint dwType;
        [FieldOffset(8)]
        public RID_DEVICE_INFO_MOUSE mouse;
        [FieldOffset(8)]
        public RID_DEVICE_INFO_KEYBOARD keyboard;
        [FieldOffset(8)]
        public RID_DEVICE_INFO_HID hid;
    }

    /// <summary>
    /// The POINT structure defines the x- and y- coordinates of a point.
    /// </summary>
    /// <remarks>
    /// typedef struct tagPOINT {
    ///     LONG x;
    ///     LONG y;
    /// } POINT, *PPOINT;
    /// </remarks>
    [StructLayout(LayoutKind.Sequential)]
    public struct POINT
    {
        [MarshalAs(UnmanagedType.U4)]
        public long x;
        [MarshalAs(UnmanagedType.U4)]
        public long y;
    } 

    /// <summary>
    /// Contains message information from a thread's message queue.
    /// </summary>
    /// <remarks>
    /// typedef struct tagMSG {
    ///     HWND   hwnd;
    ///     UINT   message;
    ///     WPARAM wParam;
    ///     LPARAM lParam;
    ///     DWORD  time;
    ///     POINT  pt;
    /// } MSG, *PMSG, *LPMSG;
    /// </remarks>
    [StructLayout(LayoutKind.Sequential)]
    public struct MSG
    {
        public IntPtr hwnd;
        [MarshalAs(UnmanagedType.SysUInt)]
        public MessageContext message;
        public IntPtr wParam;
        public IntPtr lParam;
        [MarshalAs(UnmanagedType.U4)]
        public ulong time;
        public POINT pt;
    }

    [DllImport("user32.dll")]
    public static extern bool SetForegroundWindow(IntPtr hWnd);     
    // ...
    // Import other API functions used above
    // ...
}
心不设防 2024-10-28 03:05:01

您在使用 POS for .Net 和 USB HID 设备方面走在正确的道路上。扫描仪将提供一个数据事件供您处理。您遇到的问题以及我遇到的相同问题是,在 WPF 中您无法本机从 POSExplorer 对象接收数据事件。这是因为 POSExplorer 需要 Windows 表单的句柄。事实证明,由于该技术中使用的线程模型,来自对象的 WPF 是不可接受的。

如果 Microsoft 可以为 WPF 创建一个 POSExplorer,那么您就已经准备好了,但在此之前,最简单的解决方案是使用 Windows 窗体创建一个单独的项目,以便您可以处理来自 POSExplorer 的数据事件。之后,您就可以解决将该信息传递给 WPF UI 的小问题了。

You are on the right track for using POS for .Net and a USB HID device. The Scanner will provide a Data Event for you to handle. The problem you are experiencing, and the same problem I have come accross, is that in WPF you can not natively receive Data Events from the POSExplorer object. This is because POSExplorer requires a handle to a Windows form. It turns out that a WPF from object is not acceptable because of the threading model used in that technology.

If Microsoft could create a POSExplorer for WPF then you would be set, but until then the simplest soltuion is to create a seperate project using a windows form so that you can handle the Data Event from the POSExplorer. After that is working you can then work the minor issue of communicating that information to your WPF UI.

牛↙奶布丁 2024-10-28 03:05:01

我尝试使用 WinAPI 使其工作。我可以枚举键盘、鼠标和其他人机界面设备:

int main()
{
    UINT num_devs;
    GetRawInputDeviceList(NULL, &num_devs, sizeof(RAWINPUTDEVICELIST));
    RAWINPUTDEVICELIST* dev_list = new RAWINPUTDEVICELIST[num_devs];
    UINT stored_devs = GetRawInputDeviceList(dev_list, &num_devs, sizeof(RAWINPUTDEVICELIST));

    for( int i = 0; i < stored_devs; ++i )
    {
        UINT            size;
        RID_DEVICE_INFO dev_info;
        char            dev_name[256] = {0};

        size = sizeof(dev_name);
        GetRawInputDeviceInfoA(dev_list[i].hDevice, RIDI_DEVICENAME, dev_name, &size);
        size = sizeof(RID_DEVICE_INFO);
        GetRawInputDeviceInfo(dev_list[i].hDevice, RIDI_DEVICEINFO, &dev_info, &size);

        std::cout << "Device Name: " << dev_name << "Device Type: ";
        switch( dev_info.dwType )
        {
        case RIM_TYPEHID:
            std::cout << "HID";
            break;
        case RIM_TYPEKEYBOARD:
            std::cout << "Keyboard";
            break;
        case RIM_TYPEMOUSE:
            std::cout << "Mouse";
        }
        std::cout << std::endl;
    }

    delete dev_list;
    return 0;
}

但 GetRawInputDeviceList 似乎还提供 RDP 设备和其他虚拟设备。如何识别我的键盘和扫描仪?

I tried to get this to work by using the WinAPI. I can enumerate keyboard, mouse and other human interface devices:

int main()
{
    UINT num_devs;
    GetRawInputDeviceList(NULL, &num_devs, sizeof(RAWINPUTDEVICELIST));
    RAWINPUTDEVICELIST* dev_list = new RAWINPUTDEVICELIST[num_devs];
    UINT stored_devs = GetRawInputDeviceList(dev_list, &num_devs, sizeof(RAWINPUTDEVICELIST));

    for( int i = 0; i < stored_devs; ++i )
    {
        UINT            size;
        RID_DEVICE_INFO dev_info;
        char            dev_name[256] = {0};

        size = sizeof(dev_name);
        GetRawInputDeviceInfoA(dev_list[i].hDevice, RIDI_DEVICENAME, dev_name, &size);
        size = sizeof(RID_DEVICE_INFO);
        GetRawInputDeviceInfo(dev_list[i].hDevice, RIDI_DEVICEINFO, &dev_info, &size);

        std::cout << "Device Name: " << dev_name << "Device Type: ";
        switch( dev_info.dwType )
        {
        case RIM_TYPEHID:
            std::cout << "HID";
            break;
        case RIM_TYPEKEYBOARD:
            std::cout << "Keyboard";
            break;
        case RIM_TYPEMOUSE:
            std::cout << "Mouse";
        }
        std::cout << std::endl;
    }

    delete dev_list;
    return 0;
}

But it seems that GetRawInputDeviceList also provide RDP-devices and other virtual devices. How can I identify my keyboard and my scanner?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文