问题 使用USB条形码扫描仪读取条形码,同时忽略键盘数据输入,而扫描仪产品ID和供应商ID未知


有没有办法从USB条形码阅读器读取而忽略键盘而不知道USB扫描仪的PID或VID?我知道有一种方法可以通过使用USB扫描仪的VID和/或PID来区分USB扫描仪输入和键盘输入;这是使用来自的代码完成的 http://nicholas.piasecki.name/blog/2009/02/distinguishing-barcode-scanners-from-the-keyboard-in-winforms/ 但是,如果没有将扫描仪的VID或PID放在配置文件(或源代码)中,是否存在区分键盘和USB扫描仪的另一种解决方案?不想在配置文件中放置各种VID或PID的原因是,正在开发的应用程序将部署在众多笔记本电脑上,并且附加了任意类型的扫描仪。

此外,我不想配置扫描仪的输出开始和结束序列,因为扫描仪也被同一台机器上的其他软件使用,我不想更改代码在其他软件上。出于与前面提到的相同的原因,我不想将条形码阅读器编程为串行模式。


3432
2018-03-05 14:39


起源



答案:


有一种方法可以区分键盘和USB条形码阅读器

你可以依赖这些事实:

  1. 条形码阅读器扫描的代码最少4个字符
  2. 条形码阅读器扫描的代码以RETURN“ENTER”结束
  3. 扫描孔条形码需要不到50毫秒

这是一个使用VS2005 VB的简单表格包含:

  1. TextBox1的
  2. TextBox2中
  3. textbox3
  4. Button1的
  5. Timer1“时间间隔设置为50”ms“

Public Class Form1

Dim BarcodeStr As String = ""
Dim IsBarcodeTaken As Boolean = False
Dim Str As String = ""
Dim str3 As String = ""


Private Sub Form1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown

    If Timer1.Enabled = False Then
        Str = TextBox1.Text
        str3 = TextBox3.Text
    End If

End Sub

Private Sub Form1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles Me.KeyPress
    If Timer1.Enabled = False Then
        Timer1.Enabled = True
    End If


    BarcodeStr = BarcodeStr & e.KeyChar
    If Asc(e.KeyChar) = 13 And Len(BarcodeStr) >= 4 Then
        IsBarcodeTaken = True
        TextBox2.Text = BarcodeStr


    End If

End Sub
Private Sub Form1_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyUp
    If IsBarcodeTaken = True Then
        TextBox1.Text = Str
        TextBox1.Select(Len(TextBox1.Text), 0)
        Str = ""

        TextBox3.Text = str3
        TextBox3.Select(Len(TextBox3.Text), 0)
        str3 = ""
    End If

End Sub


Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
    BarcodeStr = ""
    IsBarcodeTaken = False
    Timer1.Enabled = False
End Sub


Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    TextBox2.Text = ""

End Sub

End Class

13
2018-06-18 12:00



由于我没有足够的代表来编辑其他人的帖子,请让我为你翻译:“假设扫描仪将至少输入四个字符,以ENTER键结束,并在50ms内完成此操作。”这对我来说听起来不错,但也许你应该把时间花在100毫秒上。 - MiffTheFox
我担心,这是不正确的。您 能够 告诉,哪个设备使用生成输入 原始输入。您也不需要知道VID和PID,因为USB扫描仪已经专用 UsagePage 和 用法 分配的条目。 - IInspectable


答案:


有一种方法可以区分键盘和USB条形码阅读器

你可以依赖这些事实:

  1. 条形码阅读器扫描的代码最少4个字符
  2. 条形码阅读器扫描的代码以RETURN“ENTER”结束
  3. 扫描孔条形码需要不到50毫秒

这是一个使用VS2005 VB的简单表格包含:

  1. TextBox1的
  2. TextBox2中
  3. textbox3
  4. Button1的
  5. Timer1“时间间隔设置为50”ms“

Public Class Form1

Dim BarcodeStr As String = ""
Dim IsBarcodeTaken As Boolean = False
Dim Str As String = ""
Dim str3 As String = ""


Private Sub Form1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown

    If Timer1.Enabled = False Then
        Str = TextBox1.Text
        str3 = TextBox3.Text
    End If

End Sub

Private Sub Form1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles Me.KeyPress
    If Timer1.Enabled = False Then
        Timer1.Enabled = True
    End If


    BarcodeStr = BarcodeStr & e.KeyChar
    If Asc(e.KeyChar) = 13 And Len(BarcodeStr) >= 4 Then
        IsBarcodeTaken = True
        TextBox2.Text = BarcodeStr


    End If

End Sub
Private Sub Form1_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyUp
    If IsBarcodeTaken = True Then
        TextBox1.Text = Str
        TextBox1.Select(Len(TextBox1.Text), 0)
        Str = ""

        TextBox3.Text = str3
        TextBox3.Select(Len(TextBox3.Text), 0)
        str3 = ""
    End If

End Sub


Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
    BarcodeStr = ""
    IsBarcodeTaken = False
    Timer1.Enabled = False
End Sub


Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    TextBox2.Text = ""

End Sub

End Class

13
2018-06-18 12:00



由于我没有足够的代表来编辑其他人的帖子,请让我为你翻译:“假设扫描仪将至少输入四个字符,以ENTER键结束,并在50ms内完成此操作。”这对我来说听起来不错,但也许你应该把时间花在100毫秒上。 - MiffTheFox
我担心,这是不正确的。您 能够 告诉,哪个设备使用生成输入 原始输入。您也不需要知道VID和PID,因为USB扫描仪已经专用 UsagePage 和 用法 分配的条目。 - IInspectable


好吧,我使用的解决方案非常类似于Ehab的解决方案 - 我只是为我的应用程序清理了一些代码。我正在为我的编辑控件使用自定义类(它也在做其他一些事情) - 但这些是这个的重要部分:#

    public class ScannerTextBox : TextBox
    {
        public bool BarcodeOnly { get; set; }

        Timer timer;

        private void InitializeComponent()
        {
            this.SuspendLayout();

            this.ResumeLayout(false);
        }

        void timer_Tick(object sender, EventArgs e)
        {
            if (BarcodeOnly == true)
            {
                Text = "";
            }

            timer.Enabled = false;
        }


        protected override void OnKeyPress(KeyPressEventArgs e)
        {
            base.OnKeyPress(e);

            if (BarcodeOnly == true)
            {
                if (timer == null)
                {
                    timer = new Timer();
                    timer.Interval = 200;
                    timer.Tick += new EventHandler(timer_Tick);
                    timer.Enabled = false;
                }
                timer.Enabled = true;
            }

            if (e.KeyChar == '\r')
            {
                if (BarcodeOnly == true && timer != null)
                {
                    timer.Enabled = false;
                }
            }
        }
    }

3
2018-06-16 13:12





还有一个关于条形码的问题 这里,该链接将向您发送通过串行端口使用条形码的答案。也许那是你的解决方案?

恕我直言:最简单的解决方案是接受键盘的输入。


0
2018-03-05 14:47



此外,我不想将扫描仪配置为串行模式,因为扫描仪也被同一台机器上的其他软件使用,我不想更改其他软件上的代码。 - Amar Patel


也许这是一个过于简单的解决方案,但你能捕获按键事件并简单地阻止键盘输入吗?


0
2018-06-18 12:06



扫描仪是键盘,因此阻止按键也会阻挡扫描仪。 - Chase Florell