我已经制作了一个带有文本框的Windows窗体应用程序,它使用条形码扫描器来获取任何输入值。我希望用户只使用条形码扫描仪来填充其中的任何值,而不想使用我的常规键盘输入任何输入。
由于我的条形码模拟键盘工作,所以禁用常规键盘也会禁用条形码扫描仪。
我搜索了很多地方来实现这一点,我发现几乎没有人建议添加一个秒表/计时器来消除50毫秒内发生的所有按键,因为条形码可以在50毫秒内扫描所有值,但没有人可以输入超过50毫秒的速度。
我也尝试过这种方法,但当我随机地用手指在键盘键上敲击时,它会读出,因为一些键在50毫秒内发射。
我也尝试了下面的代码,但即使这样也不能像我预期的那样工作
private void rtBoxInput_KeyDown(object sender, KeyEventArgs e)
{
e.SuppressKeyPress = true;
}请建议一些实现这一点的好方法?
发布于 2018-05-22 18:50:30
基本思想是检查:
如果KeyUp和KeyDown事件在指定的时间(例如17毫秒)内由相同的键触发,因为这只能使用条形码扫描器来完成。
不能在17毫秒内触发同一密钥的KeyDown和KeyUp事件。例如,某人按下并释放同一个键所需的时间会超过指定时间,但是他可以在键盘上敲击have,从而将多个键全部推到一起并触发它们的KeyDown和KeyUp事件,但所有的无键都将同步触发KeyUp和KeyDown事件。因此,通过这种方式,您可以检测是否通过常规键盘或条形码扫描仪进行输入。
请看下图:
public partial class BarcodeReader : Form
{
char cforKeyDown = '\0';
int _lastKeystroke = DateTime.Now.Millisecond;
List<char> _barcode = new List<char>(1);
bool UseKeyboard = false;
public BarcodeReader()
{
InitializeComponent();
}
private void BarcodeReader_Load(object sender, EventArgs e)
{
this.KeyDown += new KeyEventHandler(BarcodeReader_KeyDown);
this.KeyUp += new KeyEventHandler(BarcodeReader_KeyUp);
}
private void BarcodeReader_KeyUp(object sender, KeyEventArgs e)
{
// if keyboard input is allowed to read
if (UseKeyboard && e.KeyData != Keys.Enter)
{
MessageBox.Show(e.KeyData.ToString());
}
/* check if keydown and keyup is not different
* and keydown event is not fired again before the keyup event fired for the same key
* and keydown is not null
* Barcode never fired keydown event more than 1 time before the same key fired keyup event
* Barcode generally finishes all events (like keydown > keypress > keyup) of single key at a time, if two different keys are pressed then it is with keyboard
*/
if (cforKeyDown != (char)e.KeyCode || cforKeyDown == '\0')
{
cforKeyDown = '\0';
_barcode.Clear();
return;
}
// getting the time difference between 2 keys
int elapsed = (DateTime.Now.Millisecond - _lastKeystroke);
/*
* Barcode scanner usually takes less than 17 milliseconds as per my Barcode reader to read , increase this if neccessary of your barcode scanner is slower
* also assuming human can not type faster than 17 milliseconds
*/
if (elapsed > 17)
_barcode.Clear();
// Do not push in array if Enter/Return is pressed, since it is not any Character that need to be read
if (e.KeyCode != Keys.Return)
{
_barcode.Add((char)e.KeyData);
}
// Barcode scanner hits Enter/Return after reading barcode
if (e.KeyCode == Keys.Return && _barcode.Count > 0)
{
string BarCodeData = new String(_barcode.ToArray());
if (!UseKeyboard)
MessageBox.Show(String.Format("{0}", BarCodeData));
_barcode.Clear();
}
// update the last key press strock time
_lastKeystroke = DateTime.Now.Millisecond;
}
private void BarcodeReader_KeyDown(object sender, KeyEventArgs e)
{
//Debug.WriteLine("BarcodeReader_KeyDown : " + (char)e.KeyCode);
cforKeyDown = (char)e.KeyCode;
}
}在这里检查..GitHub Link
发布于 2018-05-22 18:08:06
如果您的条形码模仿键盘-您无法找到在TextBox中输入文本的是哪一个。你的条形码扫描器可以在扫描的代码中添加一些前缀吗?如果是-我认为这是一个最好的选择,结合50ms的计时器。
发布于 2018-05-22 18:45:03
您可以做的是使用KeyPress事件直接在表单上处理条形码,并禁用TextBox:
private void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
barcode = string.Empty;
try
{
barcode += e.KeyChar;
if (lastTime > new DateTime())
{
if (DateTime.Now.Subtract(lastTime).Milliseconds > 30)
{
f1 = false;
}
else
{
f1 = true;
}
}
lastTime = DateTime.Now;
/*
Test your Barcode, and if it matches your criteria then change your TextBox text
TextBox1.Text = barcode;
*/
}
catch (Exception ex)
{
MessageBox.Show("Something went wrong");
}
}别忘了设置Form1.KeyPreview = true,它应该可以做到这一点!
https://stackoverflow.com/questions/50464858
复制相似问题