在一台计算机上,我有一个常规键盘和一个模拟键盘的条形码扫描仪。当我的应用程序获得键盘输入时,如何确定该输入是来自条形码扫描仪还是真正的键盘?
答案 0 :(得分:7)
你会得到两者的意见。当然不是同时。它将全部放入队列,但Windows将处理来自两个键盘的关键事件。
但是,不要无助。正如David Heffernan建议的那样,你可以通过将两个键盘插入计算机,打开记事本,然后输入随机字符来查看哪一个产生输入,从而轻松解决这个问题。您回复说要“使用C#代码检查”,但我不知道这意味着什么。如何创建一个从键盘读取输入并在屏幕上显示的控制台应用程序?
using System;
class AdvancedKeyboardTester
{
static void Main(string[] args)
{
for (; ;)
{
Console.ReadKey();
}
}
}
当你厌倦乐趣并想要退出程序时,按 Ctrl + C 。
编辑:听起来您正在寻找RegisterRawInputDevices
function,它允许您为所有键盘启用原始输入,然后枚举结果以确定哪个设备发了短信。
幸运的是,看起来有人已经为此编写了一个C#包装器库,可以在Code Project上下载:Using Raw Input from C# to handle multiple keyboards
编辑2:(似乎信息只是从评论中汲取)
如果您使用条形码扫描仪,这将变得更加容易。因为它们是为此明确设计的,所以它们几乎都是可编程的。这意味着您可以告诉他们为输入添加前缀(和/或后缀)以及指示输入来自条形码扫描器而非标准键盘的一些标记字符。 (有关详细信息,请查看条形码扫描仪的用户手册。)然后,您所要做的就是根据这些标记字符的存在与否来过滤掉键盘输入。您还可以检查输入前缀和后缀之间字符的速度。
答案 1 :(得分:4)
看看微软的MultiPoint SDK
(编辑:现在问题已经澄清,这个答案已不再适用了。我将其留在这里供其他人发现)
答案 2 :(得分:1)
这取决于操作系统,但是您会发现在大多数现代操作系统中,您将同时获得两者的输入。最好的方法是在您的平台上实际尝试。
避免让两个人同时打字;)
答案 3 :(得分:1)
让事件监听器检查击键之间的时间延迟。条形码扫描仪将非常快速地发送击键,而使用键盘的人类输入将相对较慢。我知道这会有效,因为我在网络应用程序上使用Javascript做了这样的事情。
我不知道C#编程,所以我刚刚给你了逻辑。快乐的一天!
答案 4 :(得分:1)
几乎所有条形码阅读器都可以配置前缀和后缀,无论它读取什么。例如,尝试使用前缀“*”和后缀来配置你的,然后在你的C#代码中,只要*来自输入流,并且在此文本框的lostfocus事件中,就将焦点强制转换为不可见的文本框把所有代码都放到处理条目中。请注意,您选择作为前缀的字符永远不会输入键盘。此外,将文本框的tabstop属性设置为false,只是为了防止用户在导航屏幕时到达对象。祝你好运!
答案 5 :(得分:1)
这是以@asif的答案为蓝本的。它用于WPF应用程序,在C#中并且已经过测试。我使用秒表,因为它比datetime更准确,你会在System.Diagnostics
命名空间中找到它。
我希望我的应用程序(不是特定的文本框)成为焦点时捕获文本,所以这也有点不同。您将看到为了正确处理,因为我不知道插入实际字符的内容,只有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)
尝试:
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
答案 7 :(得分:0)
这是扩大OP困境的一种方案。
我有一个文本框。今天,用户将光标置于此框中并扫描条形码。但是,用户也可以在此框中手动键入条形码的值。他们还可以将值复制并粘贴到此文本框中。
我想尝试确定该值是来自条形码读取器还是手动读取或复制粘贴。为什么?因为如果条形码被扫描,我可以相对确定地说,在扫描时,被扫描的设备在用户位置。
RegisterRawInputDevices函数听起来很有趣。我将对此进行调查。