如何判断键盘输入是否来自条形码扫描仪?

时间:2022-08-22 12:29:39

On one computer I have both a regular keyboard and a barcode scanner which emulates a keyboard. When my app gets keyboard input, how can I determine whether that input is coming from the barcode scanner or the real keyboard?

在一台计算机上,我有一个常规键盘和一个模拟键盘的条形码扫描仪。当我的应用程序获得键盘输入时,如何确定输入是来自条形码扫描仪还是真正的键盘?

7 个解决方案

#1


6  

You'll get input from both. Not simultaneously, of course. It will all be placed into a queue, but Windows will process key events from both keyboards.

你会得到两者的意见。当然不是同时发生的。它将全部放入队列,但Windows将处理来自两个键盘的关键事件。

Don't be helpless, though. As David Heffernan suggests, you can easily figure this out yourself by plugging in both keyboards to your computer, opening up Notepad, and typing random characters to see which one generates input.

不过,不要无助。正如David Heffernan建议的那样,你可以通过将两个键盘插入计算机,打开记事本,然后输入随机字符来查看哪一个产生输入,从而轻松解决这个问题。

You reply that you want to "check that with C# code", but I have no idea what that means. How about creating a console app that reads input from the keyboard and displays it on the screen?

你回复说你想“用C#代码检查”,但我不知道这意味着什么。如何创建一个从键盘读取输入并在屏幕上显示的控制台应用程序?

using System;

class AdvancedKeyboardTester
{
   static void Main(string[] args)
   {
      for (; ;)
      {
         Console.ReadKey();
      }
   }
}

Press Ctrl+C when you tire of the fun and want to quit the program.

当你厌倦了乐趣并想要退出程序时按Ctrl + C.


Edit: It sounds like you're looking for the RegisterRawInputDevices function, which allows you to enable raw input for all of your keyboards, and then enumerate through the results to determine which device sent the message.

编辑:这听起来像你正在寻找的RegisterRawInputDevices功能,它允许您启用所有键盘的原始输入,然后通过枚举的结果,以确定哪些设备发送的消息。

Fortunately, it looks like someone has already written a C# wrapper library for this, available for download on Code Project: Using Raw Input from C# to handle multiple keyboards

幸运的是,看起来有人已经为此编写了一个C#包装器库,可以在Code Project上下载:使用C#的Raw Input来处理多个键盘


Edit 2: (it seems the information just keeps tricking in from the comments)

编辑2 :(似乎信息只是从评论中汲取)

If you're using a barcode scanner, this gets a lot easier. Because they're explicitly designed for this purpose, they're almost all programmable. Meaning that you can tell them to prefix (and/or suffix) their input with some sentinel characters that indicate the input is coming from the barcode scanner, rather than a standard keyboard. (Check your barcode scanner's user manual for more information.) Then, all you have to do is filter out the keyboard input based on the presence or absence of those sentinel characters. You can also check for how quickly the characters between the prefix and suffix were entered.

如果您使用条形码扫描仪,这将变得更加容易。因为它们是为此目的而明确设计的,所以它们几乎都是可编程的。这意味着您可以告诉他们在输入前加上(和/或后缀)一些标记字符,这些字符表示输入来自条形码扫描器,而不是标准键盘。 (有关详细信息,请查看条形码扫描仪的用户手册。)然后,您所要做的就是根据这些标记字符的存在与否来过滤掉键盘输入。您还可以检查输入前缀和后缀之间字符的速度。

#2


4  

Take a look at Microsoft's MultiPoint SDK

看看微软的MultiPoint SDK

(edit: this answer is no longer applicable now that the question has been clarified. i'm leaving it here for others to discover though)

(编辑:现在问题已经澄清,这个答案已经不再适用了。我将其留在这里供其他人发现)

#3


1  

This is OS dependent, however you will find that in most modern operating systems you will get simultaneous input from both. The best method would be to actually try it on your platform.

这取决于操作系统,但是您会发现在大多数现代操作系统中,您将同时获得两者的输入。最好的方法是在您的平台上实际尝试它。

Avoid having both people type at the same time ;)

避免让两个人同时输入;)

#4


1  

Have an event listener check the time delay between keystrokes. A barcode scanner will send keystrokes very fast, while a human's input using keyboard will be comparatively slow. I know this will work because I have done such thing using Javascript on a web application.

让事件监听器检查击键之间的时间延迟。条形码扫描仪将非常快速地发送击键,而使用键盘的人类输入将相对较慢。我知道这会有效,因为我在Web应用程序上使用Javascript做了这样的事情。

I don't know C# programming, so I have just given you the logic. Happy day!

我不知道C#编程,所以我刚刚给你了逻辑。愉快的一天!

#5


1  

Here is something modeled off of @asif's answer. It is for use in a WPF app, is in C# and has been tested. I went with Stopwatch as it is more accurate than datetime, you'll find it in the System.Diagnostics namespace.

这是以@asif的答案为模型的。它用于WPF应用程序,在C#中并且已经过测试。我使用秒表,因为它比datetime更准确,你可以在System.Diagnostics命名空间中找到它。

I wanted mine to capture text when the app (not a specific textbox) was in focus, so that is a bit different too. You'll see that in order to handle that properly, since I don't know what the actual character gets inserted, only the Key enumeration. Since primarily cared about numbers 1-10 and those enums are D1, D2, etc, I strip off the D part when needed.

当应用程序(不是特定的文本框)成为焦点时,我希望我能捕获文本,所以这也有点不同。你会看到为了正确处理它,因为我不知道插入实际字符是什么,只有Key枚举。由于主要关注数字1-10并且那些枚举是D1,D2等,我在需要时剥离D部分。

Stopwatch _inputStopwatch = new Stopwatch();
string _input = "";

private void Window_KeyUp(object sender, KeyEventArgs e)
{
    if (e.Key == Key.Enter)
    {
        _inputStopwatch.Reset();
        HandleBarcode(_input);
        _input = "";
    }
    else
    {
        if (!_inputStopwatch.IsRunning)
            _inputStopwatch.Start();
        else if (_inputStopwatch.ElapsedMilliseconds > 50)
        {
            _inputStopwatch.Restart();
            _input = "";
        }

        Console.WriteLine("DEBUG: " + e.Key + " - " + _inputStopwatch.ElapsedMilliseconds + "ms");

        var keyString = e.Key.ToString();
        if (keyString.Length == 2 && keyString.StartsWith("D"))
            keyString = keyString[1].ToString();

        //if (_inputStopwatch.ElapsedMilliseconds < 50)
            _input += keyString;
        //else
        //    _input = "";

        _inputStopwatch.Restart();
    }
}

private void HandleBarcode(string barcodeInput)
{
    //do stuff with the barcode input
}

#6


0  

Try:

Dim PreviousKeyPressTime As DateTime = Nothing

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

    If e.KeyCode = Keys.Enter Then
        PreviousKeyPressTime = Nothing
        TextBox1.Text = String.Empty
    Else
        If PreviousKeyPressTime = Nothing Then
            PreviousKeyPressTime = DateTime.Now
        End If
        Dim startTime As DateTime = Now
        Dim runLength As Global.System.TimeSpan = startTime.Subtract(CType(Me.PreviousKeyPressTime, DateTime))
        Dim millisecs As Integer = runLength.Milliseconds
        Dim secs As Integer = runLength.Seconds
        Dim TotalMiliSecs As Integer = ((secs * 1000) + millisecs)

        lblDiff.Text = TotalMiliSecs

        If TotalMiliSecs <= 50 Then
            lblMsg.Text = String.Empty
        Else
            lblMsg.Text = "keyboard Input not Allow"
        End If
        PreviousKeyPressTime = DateTime.Now
    End If
End Sub

Source : http://itlearnerinsect.blogspot.com/

资料来源:http://itlearnerinsect.blogspot.com/

#7


0  

Almost all barcode readers can be configured with a prefix and suffix to whatever it reads. Try and configure yours with, for instance, a prefix of "*" and a suffix of , and then in your C# code, force the focus to an invisible textbox whenever * comes from the input stream, and in the lostfocus event of this textbox put all code to process the entry. Be aware though that the character you chose to be the prefix is never entered in the keyboard. Also, set the tabstop property of the textbox to false, just to keep the user from reaching the object when navigating the screen. Good luck !

几乎所有条形码阅读器都可以配置前缀和后缀,无论它读取什么。例如,尝试使用前缀“*”和后缀来配置你的,然后在你的C#代码中,只要*来自输入流,并且在此文本框的lostfocus事件中,就将焦点强制转换为不可见的文本框把所有代码都放到处理条目中。请注意,您选择作为前缀的字符永远不会输入键盘。此外,将文本框的tabstop属性设置为false,只是为了防止用户在导航屏幕时到达对象。祝好运 !

#1


6  

You'll get input from both. Not simultaneously, of course. It will all be placed into a queue, but Windows will process key events from both keyboards.

你会得到两者的意见。当然不是同时发生的。它将全部放入队列,但Windows将处理来自两个键盘的关键事件。

Don't be helpless, though. As David Heffernan suggests, you can easily figure this out yourself by plugging in both keyboards to your computer, opening up Notepad, and typing random characters to see which one generates input.

不过,不要无助。正如David Heffernan建议的那样,你可以通过将两个键盘插入计算机,打开记事本,然后输入随机字符来查看哪一个产生输入,从而轻松解决这个问题。

You reply that you want to "check that with C# code", but I have no idea what that means. How about creating a console app that reads input from the keyboard and displays it on the screen?

你回复说你想“用C#代码检查”,但我不知道这意味着什么。如何创建一个从键盘读取输入并在屏幕上显示的控制台应用程序?

using System;

class AdvancedKeyboardTester
{
   static void Main(string[] args)
   {
      for (; ;)
      {
         Console.ReadKey();
      }
   }
}

Press Ctrl+C when you tire of the fun and want to quit the program.

当你厌倦了乐趣并想要退出程序时按Ctrl + C.


Edit: It sounds like you're looking for the RegisterRawInputDevices function, which allows you to enable raw input for all of your keyboards, and then enumerate through the results to determine which device sent the message.

编辑:这听起来像你正在寻找的RegisterRawInputDevices功能,它允许您启用所有键盘的原始输入,然后通过枚举的结果,以确定哪些设备发送的消息。

Fortunately, it looks like someone has already written a C# wrapper library for this, available for download on Code Project: Using Raw Input from C# to handle multiple keyboards

幸运的是,看起来有人已经为此编写了一个C#包装器库,可以在Code Project上下载:使用C#的Raw Input来处理多个键盘


Edit 2: (it seems the information just keeps tricking in from the comments)

编辑2 :(似乎信息只是从评论中汲取)

If you're using a barcode scanner, this gets a lot easier. Because they're explicitly designed for this purpose, they're almost all programmable. Meaning that you can tell them to prefix (and/or suffix) their input with some sentinel characters that indicate the input is coming from the barcode scanner, rather than a standard keyboard. (Check your barcode scanner's user manual for more information.) Then, all you have to do is filter out the keyboard input based on the presence or absence of those sentinel characters. You can also check for how quickly the characters between the prefix and suffix were entered.

如果您使用条形码扫描仪,这将变得更加容易。因为它们是为此目的而明确设计的,所以它们几乎都是可编程的。这意味着您可以告诉他们在输入前加上(和/或后缀)一些标记字符,这些字符表示输入来自条形码扫描器,而不是标准键盘。 (有关详细信息,请查看条形码扫描仪的用户手册。)然后,您所要做的就是根据这些标记字符的存在与否来过滤掉键盘输入。您还可以检查输入前缀和后缀之间字符的速度。

#2


4  

Take a look at Microsoft's MultiPoint SDK

看看微软的MultiPoint SDK

(edit: this answer is no longer applicable now that the question has been clarified. i'm leaving it here for others to discover though)

(编辑:现在问题已经澄清,这个答案已经不再适用了。我将其留在这里供其他人发现)

#3


1  

This is OS dependent, however you will find that in most modern operating systems you will get simultaneous input from both. The best method would be to actually try it on your platform.

这取决于操作系统,但是您会发现在大多数现代操作系统中,您将同时获得两者的输入。最好的方法是在您的平台上实际尝试它。

Avoid having both people type at the same time ;)

避免让两个人同时输入;)

#4


1  

Have an event listener check the time delay between keystrokes. A barcode scanner will send keystrokes very fast, while a human's input using keyboard will be comparatively slow. I know this will work because I have done such thing using Javascript on a web application.

让事件监听器检查击键之间的时间延迟。条形码扫描仪将非常快速地发送击键,而使用键盘的人类输入将相对较慢。我知道这会有效,因为我在Web应用程序上使用Javascript做了这样的事情。

I don't know C# programming, so I have just given you the logic. Happy day!

我不知道C#编程,所以我刚刚给你了逻辑。愉快的一天!

#5


1  

Here is something modeled off of @asif's answer. It is for use in a WPF app, is in C# and has been tested. I went with Stopwatch as it is more accurate than datetime, you'll find it in the System.Diagnostics namespace.

这是以@asif的答案为模型的。它用于WPF应用程序,在C#中并且已经过测试。我使用秒表,因为它比datetime更准确,你可以在System.Diagnostics命名空间中找到它。

I wanted mine to capture text when the app (not a specific textbox) was in focus, so that is a bit different too. You'll see that in order to handle that properly, since I don't know what the actual character gets inserted, only the Key enumeration. Since primarily cared about numbers 1-10 and those enums are D1, D2, etc, I strip off the D part when needed.

当应用程序(不是特定的文本框)成为焦点时,我希望我能捕获文本,所以这也有点不同。你会看到为了正确处理它,因为我不知道插入实际字符是什么,只有Key枚举。由于主要关注数字1-10并且那些枚举是D1,D2等,我在需要时剥离D部分。

Stopwatch _inputStopwatch = new Stopwatch();
string _input = "";

private void Window_KeyUp(object sender, KeyEventArgs e)
{
    if (e.Key == Key.Enter)
    {
        _inputStopwatch.Reset();
        HandleBarcode(_input);
        _input = "";
    }
    else
    {
        if (!_inputStopwatch.IsRunning)
            _inputStopwatch.Start();
        else if (_inputStopwatch.ElapsedMilliseconds > 50)
        {
            _inputStopwatch.Restart();
            _input = "";
        }

        Console.WriteLine("DEBUG: " + e.Key + " - " + _inputStopwatch.ElapsedMilliseconds + "ms");

        var keyString = e.Key.ToString();
        if (keyString.Length == 2 && keyString.StartsWith("D"))
            keyString = keyString[1].ToString();

        //if (_inputStopwatch.ElapsedMilliseconds < 50)
            _input += keyString;
        //else
        //    _input = "";

        _inputStopwatch.Restart();
    }
}

private void HandleBarcode(string barcodeInput)
{
    //do stuff with the barcode input
}

#6


0  

Try:

Dim PreviousKeyPressTime As DateTime = Nothing

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

    If e.KeyCode = Keys.Enter Then
        PreviousKeyPressTime = Nothing
        TextBox1.Text = String.Empty
    Else
        If PreviousKeyPressTime = Nothing Then
            PreviousKeyPressTime = DateTime.Now
        End If
        Dim startTime As DateTime = Now
        Dim runLength As Global.System.TimeSpan = startTime.Subtract(CType(Me.PreviousKeyPressTime, DateTime))
        Dim millisecs As Integer = runLength.Milliseconds
        Dim secs As Integer = runLength.Seconds
        Dim TotalMiliSecs As Integer = ((secs * 1000) + millisecs)

        lblDiff.Text = TotalMiliSecs

        If TotalMiliSecs <= 50 Then
            lblMsg.Text = String.Empty
        Else
            lblMsg.Text = "keyboard Input not Allow"
        End If
        PreviousKeyPressTime = DateTime.Now
    End If
End Sub

Source : http://itlearnerinsect.blogspot.com/

资料来源:http://itlearnerinsect.blogspot.com/

#7


0  

Almost all barcode readers can be configured with a prefix and suffix to whatever it reads. Try and configure yours with, for instance, a prefix of "*" and a suffix of , and then in your C# code, force the focus to an invisible textbox whenever * comes from the input stream, and in the lostfocus event of this textbox put all code to process the entry. Be aware though that the character you chose to be the prefix is never entered in the keyboard. Also, set the tabstop property of the textbox to false, just to keep the user from reaching the object when navigating the screen. Good luck !

几乎所有条形码阅读器都可以配置前缀和后缀,无论它读取什么。例如,尝试使用前缀“*”和后缀来配置你的,然后在你的C#代码中,只要*来自输入流,并且在此文本框的lostfocus事件中,就将焦点强制转换为不可见的文本框把所有代码都放到处理条目中。请注意,您选择作为前缀的字符永远不会输入键盘。此外,将文本框的tabstop属性设置为false,只是为了防止用户在导航屏幕时到达对象。祝好运 !