首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >只允许条形码扫描仪并消除键盘输入

只允许条形码扫描仪并消除键盘输入
EN

Stack Overflow用户
提问于 2018-05-22 18:00:05
回答 3查看 10.9K关注 0票数 1

我已经制作了一个带有文本框的Windows窗体应用程序,它使用条形码扫描器来获取任何输入值。我希望用户只使用条形码扫描仪来填充其中的任何值,而不想使用我的常规键盘输入任何输入。

由于我的条形码模拟键盘工作,所以禁用常规键盘也会禁用条形码扫描仪。

我搜索了很多地方来实现这一点,我发现几乎没有人建议添加一个秒表/计时器来消除50毫秒内发生的所有按键,因为条形码可以在50毫秒内扫描所有值,但没有人可以输入超过50毫秒的速度。

我也尝试过这种方法,但当我随机地用手指在键盘键上敲击时,它会读出,因为一些键在50毫秒内发射。

我也尝试了下面的代码,但即使这样也不能像我预期的那样工作

代码语言:javascript
运行
复制
private void rtBoxInput_KeyDown(object sender, KeyEventArgs e)
{
    e.SuppressKeyPress = true;
}

请建议一些实现这一点的好方法?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-05-22 18:50:30

基本思想是检查:

如果KeyUp和KeyDown事件在指定的时间(例如17毫秒)内由相同的键触发,因为这只能使用条形码扫描器来完成。

不能在17毫秒内触发同一密钥的KeyDown和KeyUp事件。例如,某人按下并释放同一个键所需的时间会超过指定时间,但是他可以在键盘上敲击have,从而将多个键全部推到一起并触发它们的KeyDown和KeyUp事件,但所有的无键都将同步触发KeyUp和KeyDown事件。因此,通过这种方式,您可以检测是否通过常规键盘或条形码扫描仪进行输入。

请看下图:

代码语言:javascript
运行
复制
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

票数 4
EN

Stack Overflow用户

发布于 2018-05-22 18:08:06

如果您的条形码模仿键盘-您无法找到在TextBox中输入文本的是哪一个。你的条形码扫描器可以在扫描的代码中添加一些前缀吗?如果是-我认为这是一个最好的选择,结合50ms的计时器。

票数 0
EN

Stack Overflow用户

发布于 2018-05-22 18:45:03

您可以做的是使用KeyPress事件直接在表单上处理条形码,并禁用TextBox:

代码语言:javascript
运行
复制
     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,它应该可以做到这一点!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50464858

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档