Keypress detection and sending in c# - c#

So what im looking to do is find if i have the space bar pressed at all and while it is i would like to have the space bar be released and then pressed again mutiple times with a delay of about 10 ms. i have tried to read and understand this link (https://msdn.microsoft.com/en-us/library/system.windows.forms.control.keypress.aspx) but it is still confusing any help? im brand new to c# but i have some experience with pascal of which i have found very similar
(using visual studio 2015 due to my computer not allowing me to update to windows 8.1)

10ms delay mean 100 times per second, no one could do it.
Key events occur in the following order:
KeyDown
KeyPress
KeyUp
Events KeyDown and KeyUp use KeyEventArgs, while KeyPress is KeyPressEventArgs,
KeyEventArgs could details how many keys are pressed at same time. KeyEventArgs.KeyCode is Keys which is a [Flags] enum, it could contains multiple keys, like CTRL+SHift+F+G
if your hotkey is Ctrl+Shift+Space, you can check with:
var hotkeyPressed = e.Control && e.Shift && e.KeyCode == Keys.Space;
if your hotkey is Ctrl+F10+Space, you can check with:
var hotkeyPressed = e.Control && e.KeyCode == (Keys.Space | Keys.F10);
but do not use:
var hotkeyPressed = e.Control && e.KeyCode.HasFlag(Keys.F10) && e.KeyCode.HasFlag(Keys.Space); // e.KeyCode probably contains other flags
KeyPressEventArgs.KeyChar is a string, take a look source code, focus on its comments
[ComVisible(true)]
public class KeyPressEventArgs : EventArgs
{
...
/// <summary>Gets or sets the character corresponding to the key pressed.</summary>
/// <returns>The ASCII character that is composed. For example, if the user presses SHIFT + K, this property returns an uppercase K.</returns>
public char KeyChar { get; set; }
...
}
to use which event, it depends on your requirement.
here is sample code in KeyDown:
private int counting = 0, limit = 10;
private void txt_KeyDown(object sender, KeyEventArgs e)
{
if (!e.KeyCode.HasFlag(Keys.Space)) //check if your expected key is pressed
{
counting = 0;
return;
}
//start counting
counting++;
if (counting > limit)
{
e.Handled = true;
//do you business work, like: Send something somewhere
}
else
{
//do something else, like: show the number 'counting' in GUI
}
}
if you want limit timespan with next space, use a Timer
private void txt_KeyDown(object sender, KeyEventArgs e)
{
timer1.Stop();
if (!e.KeyCode.HasFlag(Keys.Space))
{
counting = 0;
return;
}
//start counting
timer1.Start();
counting++;
if (counting > limit)
{
e.Handled = true;
//do you business work, like: Send something somewhere
}
else
{
//do something else, like: show the number 'counting' in GUI
}
}
//timer1.Interval = 100; //100ms timeout. user has to press space again within 100ms
private void timer1_Tick(object sender, EventArgs e)
{
counting = 0;
}

Related

How to change label text in C# form

I've an application that changes the text of the label to a serial number that is scanned using a barcode scanner. The code works up until I have buttons on my form.
I've tried (1) focusing on the label, (2) creating a groupbox and putting the label in the groupbox and focusing on that, using both tab order and this:
this.ActiveControl = groupBox2;
And neither work.
Here is code outlining the the application:
private void Form1_Load(object sender, EventArgs e)
{
this.ActiveControl = groupBox2;
this.KeyDown += new KeyEventHandler(Form1_KeyDown);
this.KeyUp += new KeyEventHandler(Form1_KeyUp);
}
private void Form1_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 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));
label1.Text = String.Format("{0}", BarCodeData);
_barcode.Clear();
}
// update the last key press strock time
_lastKeystroke = DateTime.Now.Millisecond;
}
Again, it works as soon as I take the buttons out.
Here's a pic of my the UI:
Again, the label changes, until I start adding buttons to the WinForm.
Looking at the UI, the line that says, "Please Scan Serial..." should change when the user scans the barcode.

Allow Only Barcode Scanner and Eliminate Keyboard Input

I have made a Windows Form application with a textbox which uses Barcode scanner to get any input value. I want user to use only Barcode Scanner to fill any value in it, and don't want to enter any input using my regular keyboard.
Since my Barcode works mimics as a keyboard, so disabling my regular keyboard will also disable my Barcode scanner to work.
I've searched manywhere to implement this, and found few answers were suggesting to add a Stopwatch/Timer to eliminiate all keypress which occurs within 50milliseconds, since Barcode can scan all values within 50 milliseconds, but no human can type faster than 50 miliseconds.
I also tried this way, but this fails when I randomly punches my fingers on keyboard keys, it reads out since some of keys fired within 50miliseconds.
Also tried below code but even this does not work as expected for me
private void rtBoxInput_KeyDown(object sender, KeyEventArgs e)
{
e.SuppressKeyPress = true;
}
Please suggest some good way to implement this?
The basic idea is to check:
if KeyUp and KeyDown events are fired of same keys and within specified time (say 17milliseconds), as this can be only done using Barcode scanner.
No one can trigger KeyDown and KeyUp event of same key within 17 milliseconds. For example it will take more than specified time for someone to Press and Release same key, however he can hit punch to keyboard that will push multiple keys all together and trigger their KeyDown and KeyUp events, but all no keys will have KeyUp and KeyDown events fired synchronously. So by this way you can detect whether input made by regular keyboard or barcode scanner.
Please have a look below:
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;
}
}
Check Here.. GitHub Link
If your barcode mimics a keyboard - there is no way you can find which one is inputing text in your TextBox. Can your barcode scaner add some prefix to scanned code? If yes - I think this is a best option in combination with 50ms timer.
What you can do is to handle your Barcode directly on your form using a KeyPress Event and disable your 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");
}
}
Don't forgot to set Form1.KeyPreview = true and it should do the trick !

c# Measuring interval between keyboard keydown and keyup?

I want to measure time (seconds) when a user presses the right arrow key on the keyboard and pick it up.
I have researched about this and find some page but there is not a good answer.
How can I measure this time?
my code
I define a List in top of class:
List<int> date_down = new List<int>();
when user press right arrow key : (in Form_KeyDown method)
if (Keyboard.IsKeyDown(Key.Right))
{
date_down.Add(DateTime.Now.Second);
}
when user press right arrow key and held down times Add into list
when user pick up key (in Form_keyUp method)
if (e.Key == Key.Right)
{
var second = DateTime.Now.Second - date_down[0];
}
This may be an alternative
using System.Diagnostics;
using System.Windows.Forms;
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
var watch = new Stopwatch();
KeyDown += (s, e) => watch.Start();
KeyUp += (s, e) => {
watch.Stop();
var elapsed = watch.ElapsedMilliseconds; // Duration
watch.Reset();
};
}
}
Your code is a good start, though you might need to alter it a bit to see it working.
private void form1_KeyDown(object sender, System.Windows.Forms.KeyPressEventArgs e)
{
if (e.Key == Key.Right)
{
date_down = DateTime.Now;
}
e.Handled = true;
}
private void form1_KeyUp(object sender, System.Windows.Forms.KeyPressEventArgs e)
{
if (e.Key == Key.Right)
{
var timeDelta = DateTime.Now - date_down;
}
}
You can also trigger a timer from this if you want, instead of grabbing current time and evaluating.
You could start with looking up various classes for measuring time in C#, such as this one.
You will also need a class for detecting key down and key up. Perhaps this might help.
Beyond this, the implementation should be fairly simple. Start the timer when the key is pressed down, stop the timer when the key is released, and use that time as the measurement between when the two events.

How to stop the first character in a text box from being space?

I have a textbox and want user can not enter space in first textbox.the user can enter space in any where textbox apart of Beginning textbox.my computer = allow my computer = not allow (space in begining) , space maybe one or two or more.
If you really insist on doing this using one of the Events I would suggest you do it in the Text_Changed Event I have set you a simple way to do it..
private void txtaddgroup_TextChanged(object sender, EventArgs e)
{
var textBox = (TextBox)sender;
if (textBox.Text.StartsWith(" "))
{
MessageBox.Show("Can not have spaces in the First Position");
}
}
Implement a keypress event where you get rid of any spaces, read more here.
Add this bit of code to your KeyDown event handler to stop the space key ever being registered:
//Check to see if the first character is a space
if (UsernameTextBox.SelectionStart == 0) //This is the first character
{
//Now check to see if the key pressed is a space
if (e.KeyValue == 32)
{
//Stop the key registering
e.Handled = true;
e.SuppressKeyPress = true;
}
}
32 if the Key Code for the space character.
You should call this function with parameter as 'e' on KeyPress event:
Here 32 is the ASCII value of space
void SpaceValidation(KeyPressEventArgs e)
{
if (e.KeyChar == 32 && ActiveControl.Text.Length == 0)
e.Handled = true;
}
private void textbox1_KeyPress(object sender, KeyPressEventArgs e)
{
SpaceValidation(e);
}

Keydown event capturing number keys

VS 2008 SP1
I want to capture the number keys 0 to 9. And perform some action if those number are clicked.
I am using the code below. However, it doesn't seem to be working right. However, the code doesn't go into the switch as when I use the debugger to see what key value has been captured in the e.KeyValue it comes up with "LButton | ShiftKey | Space".
However, should it not display NumPad1?
Many thanks for the advice,
private void CATDialer_KeyDown(object sender, KeyEventArgs e)
{
// Play sound when use kits number key
switch (e.KeyValue)
{
case Keys.NumPad1:
// Do something here
break;
.
.
.
}
I'm using this Code
private void tb_mds_port_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == 8) // do something if backspace is pressed
{
// ACTION
e.Handled = true;
}
}
For your code use something like this
if(e.KeyChar == (char)Keys.Return) // do something if return is pressed
{
//ACTION
e.Handled = true;
}

Categories

Resources