C# 区分键盘和扫码枪输入

该代码示例展示了如何在C#中使用RAWINPUT结构来识别输入设备,阻止键盘输入,只允许扫码枪的数据传递。通过注册RawInput设备并监听WM_INPUT消息,程序能区分不同设备,从而实现特定设备控制界面的功能。
摘要由CSDN通过智能技术生成

最近有个项目客户有个要求有个界面只准扫码枪输入,不准用键盘输入,我研究了一下,找了找网上的代码,实现了一下,主要原理是提前知道输入信息的来源,判断哪个设备的,然后如果是键盘的,不往后面传递信息好了。

具体代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace testScanCode
{

    [StructLayout(LayoutKind.Sequential)]
    internal struct RAWINPUTDEVICE

    {

        [MarshalAs(UnmanagedType.U2)]

        public ushort usUsagePage;

        [MarshalAs(UnmanagedType.U2)]

        public ushort usUsage;

        [MarshalAs(UnmanagedType.U4)]

        public int dwFlags;

        public IntPtr hwndTarget;

    }

    [StructLayout(LayoutKind.Sequential)]
    internal struct RAWINPUTHEADER

    {

        [MarshalAs(UnmanagedType.U4)]

        public int dwType;

        [MarshalAs(UnmanagedType.U4)]

        public int dwSize;

        public IntPtr hDevice;

        [MarshalAs(UnmanagedType.U4)]

        public int wParam;

    }

    [StructLayout(LayoutKind.Explicit)]
    internal struct RAWINPUT

    {

        [FieldOffset(0)]

        public RAWINPUTHEADER header;

        [FieldOffset(16)]

        public RAWMOUSE mouse;

        [FieldOffset(16)]

        public RAWKEYBOARD keyboard;

        [FieldOffset(16)]

        public RAWHID hid;

    }

    [StructLayout(LayoutKind.Sequential)]
    internal 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.U4)]

        public uint Message;

        [MarshalAs(UnmanagedType.U4)]

        public uint ExtraInformation;

    }

    [StructLayout(LayoutKind.Explicit)]
    internal struct RAWMOUSE
    {
        [MarshalAs(UnmanagedType.U2)]
        [FieldOffset(0)]
        public ushort usFlags;
        [MarshalAs(UnmanagedType.U4)]
        [FieldOffset(4)]
        public uint ulButtons;
        [FieldOffset(4)]
        public BUTTONSSTR buttonsStr;
        [MarshalAs(UnmanagedType.U4)]
        [FieldOffset(8)]
        public uint ulRawButtons;
        [FieldOffset(12)]
        public int lLastX;
        [FieldOffset(16)]
        public int lLastY;
        [MarshalAs(UnmanagedType.U4)]
        [FieldOffset(20)]
        public uint ulExtraInformation;
    }

    [StructLayout(LayoutKind.Sequential)]
    internal struct BUTTONSSTR
    {
        [MarshalAs(UnmanagedType.U2)]
        public ushort usButtonFlags;
        [MarshalAs(UnmanagedType.U2)]
        public ushort usButtonData;
    }

    [StructLayout(LayoutKind.Sequential)]
    internal struct RAWHID
    {
        [MarshalAs(UnmanagedType.U4)]
        public int dwSizHid;
        [MarshalAs(UnmanagedType.U4)]
        public int dwCount;
    }

    [StructLayout(LayoutKind.Sequential)]
    internal struct RID_DEVICE_INFO_HID
    {
        [MarshalAs(UnmanagedType.U4)]
        public int dwVendorId;
        [MarshalAs(UnmanagedType.U4)]
        public int dwProductId;
        [MarshalAs(UnmanagedType.U4)]
        public int dwVersionNumber;
        [MarshalAs(UnmanagedType.U2)]
        public ushort usUsagePage;
        [MarshalAs(UnmanagedType.U2)]
        public ushort usUsage;
    }

    [StructLayout(LayoutKind.Sequential)]
    internal struct RID_DEVICE_INFO_KEYBOARD
    {
        [MarshalAs(UnmanagedType.U4)]
        public int dwType;
        [MarshalAs(UnmanagedType.U4)]
        public int dwSubType;
        [MarshalAs(UnmanagedType.U4)]
        public int dwKeyboardMode;
        [MarshalAs(UnmanagedType.U4)]
        public int dwNumberOfFunctionKeys;
        [MarshalAs(UnmanagedType.U4)]
        public int dwNumberOfIndicators;
        [MarshalAs(UnmanagedType.U4)]
        public int dwNumberOfKeysTotal;
    }

    [StructLayout(LayoutKind.Explicit)]
    internal struct RID_DEVICE_INFO
    {
        [FieldOffset(0)]
        public int cbSize;
        [FieldOffset(4)]
        public int 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;
    }

    [StructLayout(LayoutKind.Sequential)]
    internal struct RID_DEVICE_INFO_MOUSE
    {
        [MarshalAs(UnmanagedType.U4)]
        public int dwId;
        [MarshalAs(UnmanagedType.U4)]
        public int dwNumberOfButtons;
        [MarshalAs(UnmanagedType.U4)]
        public int dwSampleRate;
        [MarshalAs(UnmanagedType.U4)]
        public int fHasHorizontalWheel;
    }


    public partial class Form1 : Form
    {
        [DllImport("User32.dll")]
        extern static uint GetRawInputData(IntPtr hRawInput, uint uiCommand, IntPtr pData, ref uint pcbSize, uint cbSizeHeader);

        [DllImport("User32.dll")]
        extern static bool RegisterRawInputDevices(RAWINPUTDEVICE[] pRawInputDevice, uint uiNumDevices, uint cbSize);

        [DllImport("User32.dll")]
        extern static uint GetRawInputDeviceInfo(IntPtr hDevice, uint uiCommand, IntPtr pData, ref uint pcbSize);

        private const int RIDEV_INPUTSINK = 0x100;
        private const int RIDEV_NoLegacy = 0x30;

        private const int WM_INPUT = 0x00FF;
        private const uint RID_INPUT = 0x10000003;
        private const uint RIDI_DEVICENAME = 0x20000007;


        bool isKeyBoard1 = true;


        string keyBoard = "VID_24AE";
        public Form1()
        {
            InitializeComponent();
            RegWM_INPUT();
        }
       
        private void RegWM_INPUT()
        {
            RAWINPUTDEVICE[] rid = new RAWINPUTDEVICE[1];
            rid[0].usUsagePage = 0x01;
            rid[0].usUsage = 0x06;
            //rid[0].dwFlags = RIDEV_INPUTSINK| RIDEV_NoLegacy;//当前设置:焦点非当前窗口时依旧接收到WM_INPUT消息,可根据此特性实现当使用条码枪时激活本窗口
            rid[0].hwndTarget = this.Handle;
            RegisterRawInputDevices(rid, (uint)rid.Length, (uint)Marshal.SizeOf(rid[0]));
        }

       
        protected override void WndProc(ref Message message)
        {
            if (message.Msg == WM_INPUT)
                processMessage(message);

            //string aa = message.Msg.ToString();
            base.WndProc(ref message);
        }

        private void processMessage(Message message)
        {
            uint dwSize = 0;

            GetRawInputData(message.LParam, RID_INPUT, IntPtr.Zero, ref dwSize, (uint)Marshal.SizeOf(typeof(RAWINPUTHEADER)));

            IntPtr buffer = Marshal.AllocHGlobal((int)dwSize);

            GetRawInputData(message.LParam, RID_INPUT, buffer, ref dwSize, (uint)Marshal.SizeOf(typeof(RAWINPUTHEADER)));

            RAWINPUT raw = (RAWINPUT)Marshal.PtrToStructure(buffer, typeof(RAWINPUT));

            uint size = (uint)Marshal.SizeOf(typeof(RID_DEVICE_INFO));

            GetRawInputDeviceInfo(raw.header.hDevice, RIDI_DEVICENAME, IntPtr.Zero, ref size);
            IntPtr pData = Marshal.AllocHGlobal((int)size);
            GetRawInputDeviceInfo(raw.header.hDevice, RIDI_DEVICENAME, pData, ref size);

            string deviceName = (string)Marshal.PtrToStringAnsi(pData);

            //MessageBox.Show(deviceName);
            //判断deviceName来自哪个设备。做对应的处理

            //doSomething..
            //

            if (deviceName.Contains(keyBoard))
            {
                isKeyBoard1 = false;
            }
            else
            {
                isKeyBoard1 = true;
            }
                

            //下面两句是释放了缓存
            Marshal.FreeHGlobal(buffer);
            Marshal.FreeHGlobal(pData);

        }

        protected override bool ProcessKeyPreview(ref Message m)//重写此函数可拦截扫码枪字符输入
        {
            if (isKeyBoard1)//如果为条码枪输入则不对窗口内的控件进行录入
            {
                return true;
            }
            return base.ProcessKeyPreview(ref m);
        }
        protected override bool ProcessDialogKey(Keys keyData)//重写此函数可拦截扫码枪回车触发按钮
        {
            if (isKeyBoard1)
            {
                return true;
            }
            return base.ProcessDialogKey(keyData);
        }

    }
}

参考文章:

C# 多输入设备识别 扫码枪键盘区分RAWINPUT原始输入简易开发笔记_c#rawinput_qq_281781648的博客-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值