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

时间:2011-03-10 12:24:59

标签: .net wpf barcode-scanner point-of-sale

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

在我的应用程序中,有一个特殊字段,将填充扫描仪的输入。因此,如果用户已经聚焦了另一个字段,我不想在其中插入扫描的代码,而是我的专业领域。

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

4 个答案:

答案 0 :(得分:5)

实施OPOS WEPOS WEB内容无法提供任何)的扫描程序具有包装驱动程序的COM和/或.Net组件对于设备。扫描数据时,这些组件可能会引发事件。这些标准也适用于更多,包括磁条阅读器,秤,现金抽屉,更换分配器和MICR(支票)阅读器。

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

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

答案 1 :(得分:2)

我已经放弃了用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
    // ...
}

答案 2 :(得分:1)

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

如果微软可以为WPF创建POSExplorer,那么你将被设置,但在此之前,最简单的解决方案是使用Windows窗体创建一个单独的项目,以便您可以从POSExplorer处理数据事件。在此之后,您可以处理将该信息传递到WPF UI的次要问题。

答案 3 :(得分:0)

我试图通过使用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设备和其他虚拟设备。如何识别键盘和扫描仪?