如何在不使用文本框的情况下从 vb.net 中的条形码扫描仪读取输入?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14134126/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to read input from a barcode scanner in vb.net without using a textbox?
提问by curzedpirate
My program is already working fine, I use a TextBox to capture the barcode scanner input. The purpose of my program is for time and attendance monitoring, the problem is I want to prevent users from using the keyboard to type in their ID's as it would render the barcode scanner and their ID's with barcodes useless.
我的程序已经运行良好,我使用 TextBox 来捕获条码扫描仪输入。我的程序的目的是用于时间和出勤监控,问题是我想阻止用户使用键盘输入他们的 ID,因为它会使条码扫描仪和他们的 ID 与条码无用。
*I already tried removing the keyboard from the computer and it did work, but the keyboard must not be removed as a requirement...
*我已经尝试从计算机上卸下键盘,它确实有效,但不能作为要求卸下键盘...
回答by
Option 1:
选项1:
Get a barcode-scanner that is connected to a serial-port (raw serial device read by a COM port). As most barcode-scanners emulate keyboard strokes there is no way to directly distinguish a barcode scanner input from a keyboard input (see next option) without going low-level (see last update).
获取连接到串行端口(由 COM 端口读取的原始串行设备)的条形码扫描仪。由于大多数条码扫描器模拟键盘敲击,因此无法直接区分条码扫描器输入和键盘输入(请参阅下一个选项),而无需进入低级(请参阅上次更新)。
One connected to a serial port (or emulated one via USB as serial-ports are not so common anymore) gives you full control on where the input comes from.
一个连接到串行端口(或通过 USB 模拟一个,因为串行端口不再那么常见)可以让您完全控制输入的来源。
Option 2:
选项 2:
Count number of chars typed by time. Barcode-scanners inject a sequence (line) pretty fast compared to typing. Measuring the time used in the textbox by counting key-presses (use CR+LF as a measure point as these are sent by the scanner as well) can give you one method to distinguish if a human is typing (unless there is one typing fast as f) or the content was injected. If timed-out just reject/clear the input.
计算按时间键入的字符数。与打字相比,条形码扫描仪注入序列(行)的速度相当快。通过计算按键次数来测量文本框中使用的时间(使用 CR+LF 作为测量点,因为这些也是由扫描仪发送的)可以为您提供一种方法来区分是否有人在打字(除非有一个打字速度快)作为 f) 或内容被注入。如果超时,只需拒绝/清除输入。
In addition the checksum of the barcode (if you use one that contains that) can be used to do an extra validation in addition to time measurement.
此外,除了时间测量之外,条形码的校验和(如果您使用包含它的校验和)还可用于进行额外的验证。
(you can detect pasting by overriding the ctrl + v as in the next option).
(您可以通过覆盖 ctrl + v 来检测粘贴,如下一个选项中所示)。
Option 3:
选项 3:
Combine option 2 but instead of measure in the textbox tap into the ProcessCmdKey() function (by overriding it) and measure there if textbox has focus. This way you can first buffer input, measure time and if within a set time-out value, inject the line into the textbox.
组合选项 2,而不是在文本框中测量,点击 ProcessCmdKey() 函数(通过覆盖它)并在那里测量文本框是否具有焦点。通过这种方式,您可以首先缓冲输入,测量时间,如果在设置的超时值内,则将该行注入文本框。
Update:
更新:
Option 4:a non-technical approach -
选项 4:非技术方法 -
Usability improvements: make it visually very clear that bar-codes must be entered with a scanner and not typed. I am including as an option as it is simple and if made correct also effective (there's no right answer of what is correct unfortunately).
可用性改进:使条形码必须使用扫描仪输入而不是键入在视觉上非常清楚。我将其作为一个选项包括在内,因为它很简单,如果正确也有效(不幸的是,没有正确的答案)。
Approached could include f.ex. a watermark in the textbox ("Don't type, scan!" or something in that order). Give it a different color, border, size etc. to distinguish it from normal textboxes, and have a help text associated and available at all time that improves clarity.
接近可能包括 f.ex。文本框中的水印(“不要输入,扫描!”或其他顺序)。给它一个不同的颜色、边框、大小等,以将它与普通文本框区分开来,并有一个相关的帮助文本并始终可用,以提高清晰度。
回答by Hernan
I had the same issue and I did the following:
我遇到了同样的问题,我做了以下事情:
I set an int variable digitsPrevTyped = 0
In the "TextChanged" event of my textbox I added this (the textbox has a maxsize of 17 chars):
Private Sub tbxScannedText_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles tbxScannedText.TextChanged
If tbxScannedText.Text.Length >= 17 Then SearchFunction(False) Else digitsPrevTyped = tbxScannedText.Text.Length End If
End Sub
Then in my "SearchFunction" I check the following:
Dim inputMethod As Char If tbxScannedText.TextLength = 17 And digitsPrevTyped = 0 Then inputMethod = TEXT_SCANNED Else inputMethod = TEXT_MANUALLY_ENTERED End If
我设置了一个 int 变量digitsPrevTyped = 0
在我的文本框的“TextChanged”事件中,我添加了这个(文本框的最大大小为 17 个字符):
Private Sub tbxScannedText_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) 处理 tbxScannedText.TextChanged
If tbxScannedText.Text.Length >= 17 Then SearchFunction(False) Else digitsPrevTyped = tbxScannedText.Text.Length End If
结束子
然后在我的“SearchFunction”中,我检查以下内容:
Dim inputMethod As Char If tbxScannedText.TextLength = 17 And digitsPrevTyped = 0 Then inputMethod = TEXT_SCANNED Else inputMethod = TEXT_MANUALLY_ENTERED End If
If the textbox initially had a length of 0 chars and now has a length of 17 chars it means that the text was scanned. If the length of the previously typed text is less than 17 chars, then the text was typed. It is very basic but it works for me.
如果文本框最初的长度为 0 个字符,现在长度为 17 个字符,则表示文本已被扫描。如果先前键入的文本长度小于 17 个字符,则该文本已被键入。这是非常基本的,但对我有用。
回答by Munawar
The other possible workaround is to handle keypress event to restrict user input. Do not allow direct input from keyboard and leave the readonly false.
另一种可能的解决方法是处理按键事件以限制用户输入。不允许从键盘直接输入并保留 readonly 假。
Set following in KeyPress event handler
在 KeyPress 事件处理程序中设置以下内容
Private Sub Textbox1_KeyPress(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles Textbox1.KeyPress
e.Handled = True
End Sub
回答by zorogates
Just disable the keyboard anyway.. when using barcode you can disable the keyboard without using readonly on the textbox..
无论如何都要禁用键盘..使用条形码时,您可以禁用键盘而无需在文本框上使用只读..
on keypress event put some code i.e
在按键事件上放一些代码,即
if e.keychar <> chrw(0) then e.keychar = chrw(0) end if
if e.keychar <> chrw(0) then e.keychar = chrw(0) end if
that condition will automatically be trigged when user type anything.. you will forcibly disable any input from user but not from barcode
当用户输入任何内容时,该条件将自动触发。
回答by EasyE
This is an old post, but it took me some time to figure out a relatively clean way to use a barcode scanner and combobox so this is for future users.
这是一篇旧帖子,但我花了一些时间才找到一种相对干净的方法来使用条形码扫描仪和组合框,因此这是为未来用户准备的。
Barcode scanners can often be configured to append carriage return and line feed to the end of the scan. I have a form that can take user input or barcode scanner input into a bound combobox using the _PreviewKeyDown property and trapping on the value "Keys.Enter".
条码扫描器通常可以配置为在扫描结束后附加回车和换行。我有一个表单,可以使用 _PreviewKeyDown 属性将用户输入或条形码扫描仪输入到绑定的组合框中,并捕获值“Keys.Enter”。
Example:
例子:
If ((e.KeyCode = Keys.Enter) Then
'do stuff
Else
'do other stuff
End if
Verifying the data exists in the datasource is a bit trickier because the SelectedValue property of the combobox doesn't update so that event doesn't fire. I used a custom method to verify that the value scanned exists in the datasource. This method uses the .Text property of the combo box. It uses:
验证数据源中存在的数据有点棘手,因为组合框的 SelectedValue 属性不会更新,因此不会触发事件。我使用自定义方法来验证扫描的值是否存在于数据源中。此方法使用组合框的 .Text 属性。它用:
Me.combobox.findexactstring(Me.combobox.Text)
回答by Rei Salazar
If e.KeyCode = Keys.Enter And txt.Text.Length > 0 Then
'To Do
Else
'To Do
End if
回答by topshot
All of my scanner input goes into a "hidden" textbox, which then fills the visible ones as needed depending on the input. This, of course, means you need to keep track of where the focus is. Any type of control that can get focus will then make a call in those events to return focus to whatever the "active" textbox is at that time, which is normally the hidden one. For example...
我的所有扫描仪输入都进入“隐藏”文本框,然后根据输入根据需要填充可见文本框。当然,这意味着您需要跟踪焦点所在。任何可以获得焦点的控件都会在这些事件中进行调用,以将焦点返回到当时“活动”文本框所在的位置,这通常是隐藏的文本框。例如...
Private Sub buttons_gotFocus(sender As System.Object, e As System.EventArgs) Handles btnPrint.GotFocus, btnInMVPageDown.GotFocus, btnAdv.GotFocus, btnManual.GotFocus, btnResend.GotFocus, dgvInbound.GotFocus, dgvOutbound.GotFocus, TCRole.GotFocus
Try
activeTextbox.Focus()
Catch ex As Exception
'ignore any errors
End Try
End Sub
Most other textboxes are disabled by default, and only enabled under certain conditions. Once that entry is done they are disabled and the hidden one will get focus again. Works like a charm.
大多数其他文本框默认是禁用的,并且仅在特定条件下启用。完成该条目后,它们将被禁用,隐藏的将再次获得焦点。奇迹般有效。
回答by Nicolás Riolfo
There's no need to record previous typed characters.
无需记录以前键入的字符。
Here's my solution:
这是我的解决方案:
Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged
If TextBox1.Text.Length >= 17 Then '17 or the number of characters your scanner gets.
MsgBox("scanned")
TextBox1.Clear()
Else
If TextBox1.Text.Length <> 0 Then TextBox1.Clear()
End If
End Sub
回答by Mark Ismail
This answer will handle any fast typing.
这个答案将处理任何快速打字。
Dim scanner_input As Boolean = False
Dim start_typing As DateTime
Private Sub TextBox_part_number_TextChanged(sender As Object, e As EventArgs) Handles
TextBox_part_number.TextChanged
If (TextBox_part_number.Text.Length = 1) Then
start_typing = DateTime.Now
scanner_input = False
'' MsgBox(start_typing.ToString)
ElseIf (TextBox_part_number.Text.Length > 7) Then
If (calc_typing_time(start_typing) < 500) Then
scanner_input = True
Else
scanner_input = False
End If
End If
End Sub
Function calc_typing_time(time_started As DateTime)
Dim time_finished As DateTime
time_finished = DateTime.Now
Dim duration As TimeSpan = time_finished - time_started
Dim time_diff As String = duration.TotalMilliseconds
Return time_diff
End Function
回答by Tyler
why not use an "alias" in the bar code like "123@#$!" (but make it stupid long) is "JSMITH" and set the font color to the same as the background color in the textbox. The user can't see what they're typing or what the bar code value is when it's scanned.
为什么不在条形码中使用“别名”,例如“123@#$!” (但让它变得愚蠢)是“JSMITH”并将字体颜色设置为与文本框中的背景颜色相同。用户在扫描时看不到他们正在键入的内容或条形码值。
Super simplistic approach that doesn't really require anything added aside from another field in the the user table.
超级简单的方法,除了用户表中的另一个字段之外,实际上不需要添加任何内容。