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?
-
21. Open Notepad. 2. Type on the keyboards to see which one produces input. – David Heffernan Apr 11 '11 at 11:45
-
thanks but i want to check that with c# code!! – mahboub_mo Apr 11 '11 at 11:50
-
@raha Why do you want to do that? – David Heffernan Apr 11 '11 at 11:52
-
because i have a device that consider as a usb keyboard ,but i dont want to send that's data to open program. – mahboub_mo Apr 11 '11 at 11:55
-
My guess: you want to know if a barcode scanner or keyboard is being used. – Kieren Johnstone Apr 11 '11 at 11:55
-
yes thats right.i have a barcode sccaner and a keyboard. – mahboub_mo Apr 11 '11 at 12:09
-
2That's not what your question says. It says very explicitly that you have **two keyboards**. One of them is USB and the other is PS/2. It doesn't say anything about a barcode scanner. This is not how you ask questions the smart way. – Cody Gray - on strike Apr 11 '11 at 12:15
-
oh.yes.that's right.but i think that the barcode scanner consider as a usb keyboard! – mahboub_mo Apr 11 '11 at 12:22
-
@cody - fixed it for him – Robert Levy Apr 11 '11 at 13:45
8 Answers
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.
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.
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?
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.
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.
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
Edit 2: (it seems the information just keeps tricking in from the comments)
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.

- 948
- 16
- 33

- 239,200
- 50
- 490
- 574
-
ok.you realy help me.but i can't undrestand this: all you have to do is filter out the keyboard input based on the presence or absence of those sentinel characters. – mahboub_mo Apr 11 '11 at 12:32
-
@raha: Right, basically you can configure the scanner to send some characters that basically tell the computer "hi, it's me". When you see those characters in your input stream, you know the information is coming from the barcode scanner, not from something the user typed on the keyboard. Did you check the manual that came with your barcode scanner? It should have more information about this. – Cody Gray - on strike Apr 11 '11 at 12:37
-
i read the manual but there is no information about barcode scanner programing!!should i write some code in my program to do this configuration that or ...? – mahboub_mo Apr 12 '11 at 05:19
Take a look at Microsoft's 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)

- 28,747
- 6
- 62
- 94
-
ok.thanks.but could you explain a little about Microsoft's MultiPoint SDK? – mahboub_mo Apr 11 '11 at 12:02
-
See http://en.wikipedia.org/wiki/Windows_MultiPoint_Mouse_SDK: "Multiple stations can be added to a WMS 2010 host computer by connecting a single monitor, USB 2.0 hub, keyboard and mouse for each station." – Robert Levy Apr 11 '11 at 13:41
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 <TAB>, 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.

- 9,564
- 146
- 81
- 122

- 55
- 5
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.
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.
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
}

- 15,039
- 7
- 88
- 96
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 ;)

- 721
- 1
- 5
- 9
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.
I don't know C# programming, so I have just given you the logic. Happy day!

- 9,391
- 11
- 57
- 81
Here is a scenario to expand on the OP's dilemma.
I have a textbox. Today users put their cursor into this box and scan a barcode. But, users could also manually type the value of the barcode into this box. They could also copy and paste a value into this textbox.
I want to try to determine if the value was from a barcode reader vs manual or copy & paste. Why? Because if the barcode was scanned I can say with relative certainty that at the time of scanning, the device being scanned was at the users location.
The RegisterRawInputDevices function sounds interesting. I'm going to investigate that.

- 155
- 1
- 2
- 16
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/
-
1It'd be even better if you explained the code you posted. Also, the blog link is dead as of time of writing. – Oct 28 '12 at 00:41
-
This code times how fast the keys are coming in and if they are too slow it determines that a person is typing. Can't tell if it actually works but that is the intent of the code. – Hucker Aug 13 '14 at 23:04