C# 或 .NET 刷新键盘缓冲区

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/978091/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 04:43:53  来源:igfitidea点击:

C# or .NET Flushing Keyboard Buffer

c#keyboardbufferflush

提问by Amar Patel

How do I flush the keyboard buffer in C# using Windows Forms?

如何使用 Windows 窗体在 C# 中刷新键盘缓冲区?

I have a barcode scanner which acts like a keyboard. If a really long barcode is scanned and the cancel button is hit on the form, I need the keyboard buffer to be cleared. So I need to flush and ignore all pending input. I need the buffer cleared because if the barcode contains spaces, the spaces are processed as button clicks which is unecessary.

我有一个像键盘一样的条形码扫描仪。如果扫描了一个非常长的条形码并点击了表单上的取消按钮,我需要清除键盘缓冲区。所以我需要刷新并忽略所有挂起的输入。我需要清除缓冲区,因为如果条形码包含空格,则空格将作为不必要的按钮点击进行处理。

采纳答案by rein

I'm not sure you can do this. The keystrokes go into the event queue for the main event loop. Any action you take to cancel these keystrokes will be placed in the queue after the keystrokes.

我不确定你能做到这一点。击键进入主事件循环的事件队列。您为取消这些击键而采取的任何操作都将在击键后放入队列中。

The event loop will only get to your cancel action after the keystrokes have been processed. You can only cancel the keystrokes based on some event that happens in the middle of the keystroke sequence.

事件循环只会在处理完击键后才能执行您的取消操作。您只能根据在击键序列中间发生的某些事件来取消击键。

回答by SLaks

Set KeyPreviewon the Form to true, then catch the KeyPressevent and set e.Handledto trueif cancel was clicked.

KeyPreview在 Form 上设置为true,然后捕获KeyPress事件并设置e.Handledtrue如果单击取消。

EDIT: Catch the Form'sKeyPress event

编辑:捕获表单的KeyPress 事件

回答by VVS

You coulddo BIOS level flushing (http://support.microsoft.com/?scid=kb%3Ben-us%3B43993&x=22&y=10) but I would advise against this low level approach since Windows also does keyboard buffering on a higher level.

可以执行 BIOS 级别刷新(http://support.microsoft.com/?scid=kb%3Ben-us%3B43993&x=22&y=10)但我建议不要使用这种低级别方法,因为 Windows 也会在更高级别上进行键盘缓冲等级。

The best way seems to be to eat any arriving char while a specific flag is set. As SLaks suggests I would set KeyPreviewto true and set e.Handledto true either in KeyPressor in KeyDown.. should make no difference.

最好的方法似乎是在设置特定标志时吃掉任何到达的字符。正如 SLaks 建议的那样,我将设置KeyPreview为 true 并设置e.Handled为 trueKeyPress或 in KeyDown.. 应该没有区别。

回答by Chris

while (Console.KeyAvailable) { Console.ReadKey(true); }

while (Console.KeyAvailable) { Console.ReadKey(true); }

回答by jp2code

@Chris:

@克里斯:

Console.KeyAvailablethrew an exception on me because the Console did not have focus.

Console.KeyAvailable向我抛出异常,因为控制台没有焦点。

The exception message was helpful, though. It suggested using Console.In.Peek()to read in that instance.

不过,异常消息很有帮助。它建议Console.In.Peek()在那种情况下使用阅读。

I thought it would be worth noting here as an alternate solution and for posterity.

我认为作为替代解决方案和后代,这里值得一提。

 if (-1 < Console.In.Peek()) {
     Console.In.ReadToEnd();
 }

回答by midspace

Disable the form, and force all processing to occur with DoEvents whilst it's disabled. The Controls should reject any keystokes because they are disabled. Then re-enable the form.

禁用表单,并在禁用时强制所有处理与 DoEvents 一起发生。控件应拒绝任何按键操作,因为它们已被禁用。然后重新启用表单。

this.Enabled = false;
Application.DoEvents();
this.Enabled = true;

回答by BlinkSun

It's a old question but I got the same issue and I found a good way to do it...
When Application.DoEvent()is called, the keystoke buffer call the KeyPress event but _keypress is set to false, so it'll skip all them, after that _keypress return to true to be ready for another keypress event !

这是一个老问题,但我遇到了同样的问题,我找到了一个很好的方法来做到这一点......
Application.DoEvent()被调用时,keystoke 缓冲区调用 KeyPress 事件但 _keypress 设置为 false,所以它会跳过所有这些,在那之后 _keypress 返回 true 为另一个按键事件做好准备!

Public _keypress As Boolean
Private Sub Form1_KeyPress(sender As Object, e As KeyPressEventArgs) Handles Form1.KeyPress
    If Not _keypress Then
        _keypress = True
        //instructions
    End If
    Application.DoEvents()
    _keypress = False
End Sub