【问题标题】:Allow Only Barcode Scanner and Eliminate Keyboard Input仅允许条码扫描器并消除键盘输入
【发布时间】:2018-05-22 10:00:05
【问题描述】:

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

由于我的条码模拟键盘,因此禁用我的常规键盘也会使我的条码扫描仪无法工作。

我已经搜索了很多地方来实现这个,发现很少有答案建议添加一个秒表/计时器来消除在 50 毫秒内发生的所有按键,因为条形码可以在 50 毫秒内扫描所有值,但没有人能比50 毫秒。

我也尝试过这种方式,但是当我用手指随机敲击键盘键时失败了,因为某些键在 50 毫秒内触发,所以它会读出。

也尝试了下面的代码,但即使这对我来说也无法正常工作

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

请提出一些好的方法来实现这一点?

【问题讨论】:

  • 我的条码器发送键就像有人在打字一样,所以这在这个场景中不起作用..它确实取决于它是如何工作的。
  • 许多扫描仪支持两种操作模式,HID(键盘)模式和直接/串行/OPOS 兼容模式。根据您的要求,我建议将扫描仪操作模式更改为直接模式,使用 Microsoft POS for .NET Framework 并附加到扫描仪数据事件。然后你就完全独立于键盘输入了。

标签: c# .net wpf vb.net winforms


【解决方案1】:

基本思路是检查:

如果 KeyUp 和 KeyDown 事件在指定时间(例如 17 毫秒)内由相同的键触发,因为这只能使用条形码扫描仪完成。

没有人可以在 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

【讨论】:

    【解决方案2】:

    如果您的条形码模仿键盘 - 您无法找到在 TextBox 中输入文本的条形码。您的条码扫描器可以为扫描的代码添加一些前缀吗?如果是 - 我认为这是结合 50 毫秒计时器的最佳选择。

    【讨论】:

      【解决方案3】:

      您可以做的是使用 KeyPress 事件直接在表单上处理您的条形码并禁用您的 TextBox:

           private void Form1_KeyPress(object sender, KeyPressEventArgs e)
           {
              barcode = string.Empty;
      
              try
              {
                  barcode += e.KeyChar;
      
                  if (lastTime > new DateTime())
                  {
                      if (DateTime.Now.Subtract(lastTime).Milliseconds > 30)
                      {
                          f1 = false;
                      }
                      else
                      {
                          f1 = true;
                      }
                  }
      
                  lastTime = DateTime.Now;
      
                  /*
      
                  Test your Barcode, and if it matches your criteria then change your TextBox text
      
                  TextBox1.Text = barcode;
      
                  */
      
              }
              catch (Exception ex)
              {
                  MessageBox.Show("Something went wrong");
              }
           }
      

      不要忘记设置 Form1.KeyPreview = true ,它应该可以解决问题!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-21
        • 2019-01-08
        • 1970-01-01
        • 2014-02-20
        • 1970-01-01
        • 2017-06-09
        相关资源
        最近更新 更多