我制作了一个带文本框的Windows窗体应用程序,该文本框使用条形码扫描仪获取任何输入值。我希望用户仅使用条形码扫描仪来填充其中的任何值,并且不想使用常规键盘输入任何输入。

由于我的条形码可以像键盘一样工作,因此禁用常规键盘也会使条形码扫描器无法工作。

我在很多地方进行了搜索,发现几乎没有答案建议添加秒表/计时器来消除在50毫秒内发生的所有按键操作,因为Barcode可以在50毫秒内扫描所有值,但是没有人可以键入超过50毫秒的速度。

我也尝试过这种方法,但是当我随机地用手指按键盘键时,由于某些键在50毫秒之内触发,因此它无法读取。

还尝试了下面的代码,但即使这样对我也不起作用

private void rtBoxInput_KeyDown(object sender, KeyEventArgs e)
{
    e.SuppressKeyPress = true;
}


请提出一些实现此目的的好方法?

最佳答案

基本思想是检查:

如果在指定的时间内(例如17毫秒)内触发了相同的键的KeyUp和KeyDown事件,则只能使用条形码扫描仪来完成此操作。

没有人可以在17毫秒内触发同一键的KeyDown和KeyUp事件。例如,某人按下并释放相同的键将花费超过指定的时间,但是他可以按击键盘,将多个键全部推入并触发其KeyDown和KeyUp事件,但是所有键都不会具有KeyUp和KeyDown事件同步触发。因此,通过这种方式,您可以检测是通过常规键盘还是条形码扫描仪进行的输入。

请在下面看看:

public partial class BarcodeReader : Form
    {

        char cforKeyDown = '\0';
        int _lastKeystroke = DateTime.Now.Millisecond;
        List<char> _barcode = new List<char>(1);
        bool UseKeyboard = false;
        public BarcodeReader()
        {
            InitializeComponent();
        }
        private void BarcodeReader_Load(object sender, EventArgs e)
        {
            this.KeyDown += new KeyEventHandler(BarcodeReader_KeyDown);
            this.KeyUp += new KeyEventHandler(BarcodeReader_KeyUp);
        }
        private void BarcodeReader_KeyUp(object sender, KeyEventArgs e)
        {
            // if keyboard input is allowed to read
            if (UseKeyboard && e.KeyData != Keys.Enter)
            {
                MessageBox.Show(e.KeyData.ToString());
            }

            /* check if keydown and keyup is not different
             * and keydown event is not fired again before the keyup event fired for the same key
             * and keydown is not null
             * Barcode never fired keydown event more than 1 time before the same key fired keyup event
             * Barcode generally finishes all events (like keydown > keypress > keyup) of single key at a time, if two different keys are pressed then it is with keyboard
             */
            if (cforKeyDown != (char)e.KeyCode || cforKeyDown == '\0')
            {
                cforKeyDown = '\0';
                _barcode.Clear();
                return;
            }

            // getting the time difference between 2 keys
            int elapsed = (DateTime.Now.Millisecond - _lastKeystroke);

            /*
             * Barcode scanner usually takes less than 17 milliseconds as per my Barcode reader to read , increase this if neccessary of your barcode scanner is slower
             * also assuming human can not type faster than 17 milliseconds
             */
            if (elapsed > 17)
                _barcode.Clear();

            // Do not push in array if Enter/Return is pressed, since it is not any Character that need to be read
            if (e.KeyCode != Keys.Return)
            {
                _barcode.Add((char)e.KeyData);
            }

            // Barcode scanner hits Enter/Return after reading barcode
            if (e.KeyCode == Keys.Return && _barcode.Count > 0)
            {
                string BarCodeData = new String(_barcode.ToArray());
                if (!UseKeyboard)
                    MessageBox.Show(String.Format("{0}", BarCodeData));
                _barcode.Clear();
            }

            // update the last key press strock time
            _lastKeystroke = DateTime.Now.Millisecond;
        }

        private void BarcodeReader_KeyDown(object sender, KeyEventArgs e)
        {
            //Debug.WriteLine("BarcodeReader_KeyDown : " + (char)e.KeyCode);
            cforKeyDown = (char)e.KeyCode;
        }
    }


检查这里.. GitHub Link

10-05 20:45
查看更多