Prevent KeyDown event identify SendKeys - c#

I want to make a program to simulate textentry if user press the keys "D1 - D0" and simulate some numbers if user pressed the function keys..
Here is the code I have tried.
if (e.KeyData == Keys.D1){
SendKeys.Send("simulate this text entry");
}
if (e.KeyData == Keys.F12){
SendKeys.Send("123");
}
But the problem is when I press the F12 button, the KeyDown event identify the first "1" as the "D1" key and sends both "123" and "simulate this text entry"
How can I prevent this problem ?

When you go to send the keys, you'd have to set a flag so you know to ignore the characters being sent. Additionally, you'd need to know when to turn the flag back on. This could be done by setting a variable to the length of the value being sent, and then incrementing a counter with each detected key. This isn't foolproof as the user could hit keys in rapid succession (or hold a key down) and you wouldn't know if the keypress was a result of user interaction or from your simulation.
Here's the basic idea:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private bool IgnoreKeys = false;
private int target = 0;
private int counter = 0;
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (!IgnoreKeys)
{
if (e.KeyData == Keys.D1)
{
Send("simulate this text entry");
}
if (e.KeyData == Keys.F12)
{
Send("123");
}
}
else
{
counter++;
if (counter == target)
{
IgnoreKeys = false;
}
}
}
private void Send(string entry)
{
IgnoreKeys = true;
counter = 0;
target = entry.Length;
SendKeys.Send(entry);
}
}

The problem is that using SendKeys.Send( ... ) there is no way your program can tell the difference between your sent keys and the user's keyboard input.
When you send the keys "123" it is the same as if the user pressed the 1, 2, and 3 keys.
Because you're listening for the 1 key, that event fires and catches the '1' sent by sendkeys.
If possible, try to append text to the content you're trying to "simulate textentry" into and avoid sendkeys.
Otherwise consider making your number hotkeys alt/ctrl-combinations such as this:
if (e.Control && e.KeyCode == Keys.D1)
{
SendKeys.Send("simulate this text entry");
e.Handled = true;
}
That will prevent this event from being fired when you press F12 and send "123" (because ctrl is not pushed).

Finally solved the problem.. :) Here is the code.. Have to use "SendKeys.Flush()" in this task...
private bool IgnoreKeys = false;
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if ((e.KeyData == Keys.D1) && (!IgnoreKeys))
{
SendKeys.Send("Simulate this text" + "{ENTER}");
}
if (e.KeyData == Keys.F12)
{
IgnoreKeys = true;
SendKeys.Send("123");
SendKeys.Flush();
IgnoreKeys = false;
}
This prevents the KeyDown event considering "1" in the text "123" as the key "D1"
Idea is Idle_Mind's :) Thank you..

Related

How to detect a custom key from Keyboard using C#

I have a USB Keyboard that have some Special keys like "FN",PLAY,MUTE and one that changes the keyboard light. I was trying to get what is this key "name" to perform a logic to change the color periodically.
private void textBox1_TextChanged(object sender, EventArgs e)
{
var key = sender as TextBox;
var result = key.Text;
}
But the key its not a string to be recognized. How can I do this ? Thanks!
I will suggest you to use OnKeyPress and OnKeyDown events instead to check what was pressed. MSDN Link.
Example:
// Boolean flag used to determine when a character other than a number is entered.
private bool nonNumberEntered = false;
// Handle the KeyDown event to determine the type of character entered into the control.
private void textBox1_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{
// Initialize the flag to false.
nonNumberEntered = false;
// Determine whether the keystroke is a number from the top of the keyboard.
if (e.KeyCode < Keys.D0 || e.KeyCode > Keys.D9)
{
// Determine whether the keystroke is a number from the keypad.
if (e.KeyCode < Keys.NumPad0 || e.KeyCode > Keys.NumPad9)
{
// Determine whether the keystroke is a backspace.
if(e.KeyCode != Keys.Back)
{
// A non-numerical keystroke was pressed.
// Set the flag to true and evaluate in KeyPress event.
nonNumberEntered = true;
}
}
}
//If shift key was pressed, it's not a number.
if (Control.ModifierKeys == Keys.Shift) {
nonNumberEntered = true;
}
}
// This event occurs after the KeyDown event and can be used to prevent
// characters from entering the control.
private void textBox1_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
{
// Check for the flag being set in the KeyDown event.
if (nonNumberEntered == true)
{
// Stop the character from being entered into the control since it is non-numerical.
e.Handled = true;
}
}

C# Call a function when a second key is pressed

I'm lost calling a function when a second key is pressed. I have used KeyDown event for my buttons. And that KeyDown will call a function that will check that button. My problem is after checking that button, the user must press another Enter Key or Spacebar to go on the next data.
This is for my radiobutton1 KeyDown event
private void btn1_KeyDown(object sender, KeyEventArgs e)
{
btn1.BackColor = Color.Blue;
checkAns(btn1.Text, btn1);
}
This is my checkAns function that will check the selected button
private void checkAns (string ansText, RadioButton rdo)
{
var row = dTable.Rows[currentRow];
var ans = row["ANSWER"].ToString();
if (ansText == ans)
{
rdo.BackColor = Color.Green;
correctAdd();
//MessageBox.Show("Correct");
}
else
{
rdo.BackColor = Color.Red;
wrongAdd();
//MessageBox.Show("Wrong. Answer is" + " \n " + ans);
}
nextEnter (------); //Here I'm not sure how to call the another keydown/keypress event or value of the enter key
}
This is my nextEnter function
private void nextEnter(------) //Also at this part.
{
if (------ == Keys.Enter) //And here.
currentRow++;
currentNo++;
remain--;
nextRow();
}
i solve this problem by having the form increment a variable during enter keydown event.
private void frmTest_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter || e.KeyCode == Keys.Space)
{
entCount++;
}
}
and use if statement when entCount == 2, show the next data and reset the entCount to 0.
To demonstrate what I meant in my comment:
You could pass the KeyCode property of your KeyEventArgs from btn1_KeyDown
private void btn1_KeyDown (object sender, KeyEventArgs e)
{
btn1.BackColor = Color.Blue;
checkAns (btn1.Text, btn1, e.KeyCode);
}
to checkAns
private void checkAns (string ansText, RadioButton rdo, Keys pressedKey)
{
var row = dTable.Rows [currentRow];
var ans = row ["ANSWER"].ToString ();
if (ansText == ans)
{
rdo.BackColor = Color.Green;
correctAdd ();
//MessageBox.Show("Correct");
}
else
{
rdo.BackColor = Color.Red;
wrongAdd ();
//MessageBox.Show("Wrong. Answer is" + " \n " + ans);
}
nextEnter (pressedKey); //Here I'm not sure how to call the another keydown/keypress event or value of the enter key
}
And further on to nextEnter:
private void nextEnter (Keys key) //Also at this part.
{
if (key == Keys.Enter) //And here.
currentRow++;
currentNo++;
remain--;
nextRow ();
}
Tell me if I misunderstood anything, you need further help or my solution doesn't work for you.

How to detect control + v for pasting

I am new to C#. I am using the following code to detect Ctrl+v when pressed on the keyboard:
while(true)
{
bool check = (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl));
if (check && Keyboard.IsKeyDown(Key.V))
{
if (Clipboard.ContainsText())
history.Dispatcher.Invoke(new invoke_method2(update2),
new object[] { Clipboard.GetText(), history });
}
}
The program is running in the background. The problem is, it works when the user presses Ctrl and then v. But the conditions also stand true if the user presses v and then Ctrl, which is an unwanted trigger. Is there a way to overcome it?
To capture a shortcut in a window in WPF, implement a KeyDown event, so creating a new thread isn't necessary:
public MainWindow()
{
InitializeComponent();
KeyDown += MainWindow_KeyDown;
}
void MainWindow_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyboardDevice.Modifiers == ModifierKeys.Control)
{
if (e.Key == Key.V)
{
}
}
}
Edit:
If you want to go with your solution, then you're practically searching for a point in time when V isn't pressed, but Ctrl is, so the following works:
while (true)
{
if (!Keyboard.IsKeyDown(Key.V))
{
while (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))
{
if (Keyboard.IsKeyDown(Key.V))
{
}
}
}
}

How to capture the spacebar press event using KeyeventHandler?

I have a Form with a rich text box in which i want to do the following:
When user presses the spacebar button (Currently i am doing it with keydown event but want to use key press event but it doesn't provide e.keycode), a function should be called in which this logic is to be implemented:
last written word is to be fetched and is to be looped through the text of rich text box in order to find its number of occurrences in a rich text box.
What i have done so far is:
private void textContainer_rtb_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Space)
{
String abc = this.textContainer_rtb.Text.Split(' ').Last();
chkWordRepeat(abc);
}
}
public void chkWordRepeat(String lastWordToFind)
{
int count = new Regex(lastWordToFind).Matches(this.textContainer_rtb.Text.Split(' ').ToString()).Count;
MessageBox.Show("Word: " + lastWordToFind + "has come: " + count + "times");
}
Please let me know if the above mentioned logic is correct or not And how can i attach this logic with key press event for spacebar? If not then please help me implementing!
Thanks in advance.
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == ' ')
MessageBox.Show("space pressed");
}
My opinion is :
public Dictionary<string, int> data;
private void textContainer_rtb_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Space)
{
String abc = this.textContainer_rtb.Text.Split(' ').Last();
chkWordRepeat(abc);
}
}
public void chkWordRepeat(string wrd)
{
bool present = false;
foreach (string key in data.Keys)
if (wrd == key)
{
present = true;
data[wrd]++;
}
if (!present)
data.Add(wrd, 1);
}

Unable to capture Enter Key

I have a simple form by which I take input:
12 Buttons, 1 Textbox (disabled & read-only)
this is what I do to handle input
Login_KeyDown() is common method I call for all the KeyDown of every UI component & the form itself..
private void Login_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Escape)
{
Application.Exit();
}
else if (e.KeyCode == Keys.NumPad9 || e.KeyCode == Keys.D9)
{
button3.BackgroundImage = Properties.Resources.button_hover;
button3.ForeColor = Color.White;
pin.Text = pin.Text + "9";
}
else if (e.KeyCode == Keys.Back)
{
button11.BackgroundImage = Properties.Resources.button_hover;
button11.ForeColor = Color.White;
if (pin.Text.Length > 0)
pin.Text = pin.Text.Substring(0, pin.Text.Length - 1);
}
else if (e.KeyCode == Keys.Enter)
{
MessageBox.Show(pin.Text);
}
}
This code works fine when I start the app but after I have clicked on any component, rest of the code works fine but "Enter Key Condition" doesn't work.
My guess is as "Enter Key Condition" is not working for UI components or something like that.
I have also tried using "Key Press Event" which uses KeyPressEventArgs then checking KeyChar == 13 but that is also not working.
What is the problem, and how can I solve it?
p.s.
I have not set any button click events for any button, the app is 100% KBoard based.
Check out PreviewKeyDown. Return raises that event on button controls.
private void Form1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
if (e.KeyCode == Keys.Return)
MessageBox.Show("I found return");
}
Or alternatively you can force it to raise those special keys in the KeyDown Event by using:
private void Form1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
if (e.KeyCode == Keys.Return)
e.IsInputKey = true;
}
More information: http://msdn.microsoft.com/en-us/library/system.windows.forms.control.previewkeydown.aspx
Have you tried to use
Keys.Return
Instead
Edit:
Just thought of this. Do you have the acceptbutton set for the main form?
This is because your Form has AcceptButton defined. For example, you have a "OK", "Accept" or "Confirm" button with DialogResult set to "OK". This tells its parent form that there is an AcceptButton, and the Enter event on the form would go to this button.
What you should do is to catch the Enter key at form level. Add this code to the form:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if ((this.ActiveControl == myTextBox) && (keyData == Keys.Return))
{
//do something
return true;
}
else
{
return base.ProcessCmdKey(ref msg, keyData);
}
}

Categories

Resources