C# Key hooks key down event - c#

Creating a key hook so that when the combination is pressed, the application will open again.
I have looked into various ways of doing it, however I do not know what the input combination will be unlike this example:
if (e.KeyCode == Keys.C && e.Modifiers == Keys.Control && e.Modifiers == Keys.Shift)
{
//Do work
}
else if (e.KeyCode == Keys.V && e.Modifiers == Keys.Control)
{
//Paste
}
Our input combination is from the user, where they select which combination they want to input from a combo box.
public void KeyboardHooks_OnKeyPress(object sender, KeyPressArgs e)
{
//The first input
if (LastKey != Keys.None)
{
Keys combinationOne = (Keys)cmbCombinationOne.SelectedValue;
Keys combinationTwo = (Keys)cmbCombinationTwo.SelectedValue;
}
LastKey = e.Key;
MessageBox.Show("KeyPressed");
}
Not sure on how to go about setting our values to the combo box's

From your code snippets it looks like you're going the route of WinForms key events. If the user does a key combination in your application and you do this 'open' of something else, you're on the right path. You'll just need to make it dynamic to see if the user-defined items are pressed.
So when you save the user settings, convert it to a keycode so you can do the generic
if(e.KeyCode == Settings.FirstModKey && e.KeyCode == Settings.SecondModKey && e.KeyCode == Settings.FirstKey)
You'll need to consider the multiple scenarios, the modifiers Shift, Alt and Control could be none, one, two, or all three. In my above, you could have FirstModKey and SecondModKey the same value if the user chose Ctrl only, or they could be handling if they did Ctrl and Shift both. Then FirstKey is the non-mod key, like 'A'.
the application will open again
However, from the quote it sounds like you want a global hook, that wherever the user is in any application, with yours not running, you want to listen and do work if its your keycode. You need to look into a service and low level hooks. This can come close to keylogging and you need to be careful who your audience is, security risks and concerns that you might be breaking compliance.

{
//The first input
if (LastKey != Keys.None)
{
int combination1 = (int)Enum.Parse(typeof(Keys), cmbCombinationOne.SelectedValue.ToString());
int combination2 = (int)Enum.Parse(typeof(Keys), cmbCombinationTwo.SelectedValue.ToString());
int LastKeyPress = (int)Enum.Parse(typeof(Keys), LastKey.ToString());
ThisKey = e.Key;
if (combination1 == LastKeyPress && combination2 == Convert.ToInt32(ThisKey))
{
MessageBox.Show("Key pressed");
}
}
LastKey = e.Key;
}
This worked with my original existing code

Related

Allow only 1 symbol in TextBox

I am currently working on a custom control that allow users to enter either a decimal or in time format (hh:mm). So I would like that if the TextBox contain a period(.), the user will no longer add/enter a colon(:) and vice versa.
I have this code below so that user can only enter numeric, a period and a colon.
private void txtTime_KeyPress(object sender, KeyPressEventArgs e)
{
if ((!char.IsControl(e.KeyChar) & !char.IsDigit(e.KeyChar) & !(Convert.ToString(e.KeyChar) == ".") & !(Convert.ToString(e.KeyChar) == ":")))
{
e.Handled = true;
}
else
{
//only allow one '.' & ':'
if (e.KeyChar == '.' && (sender as TextBox).Text.IndexOf('.') > -1)
{
e.Handled = true;
}
else if (e.KeyChar == ':' && (sender as TextBox).Text.IndexOf(':') > -1)
{
e.Handled = true;
}
}
}
So my question is, how will I do it?
Can somebody help me? Thanks in advance.
For operators it is a nuisance if they have typed something, and they want to correct it, but they can't because there is an incorrect dot or a semicolon in it.
Suppose the operator tried to type 14:38:21, but instead types:
14.38
"Oh no, this is wrong, I wanted 14.38:21! So let's first continue typing :21 and then go back to change the dot into a colon!"
Imagine the operator's frustration when he can't type :21, and doesn't understand why
In windows forms, only validate entered input when the operator expresses he finished editing the input.
Therefore, use TextBox.OnValidating. When this one is called, you can either accept or decline the input and tell the operator what is wrong.
protected override void OnValidating (CancelEventArgs e)
{
e.Cancel = this.IsInputErrorDetected;
if (e.Cancel)
{
this.DisplayInputProblem();
}
}
Bonus point: also works with copy-paste.
I am not sure, if I understand your question good.
Maybe you are looking for maskedTextBox where you can specify mask of user input.
This one has mask for short time HH:MM

Unity - handle 2 input for keybinding in my game

In my game you can control unit, each unit have spell, and we would like to give to the user the possibility to change the keybinding of his different spell.
The goal is for exemple having the possibility to have a combinaison of input for a spell (exemple : "ctrl + H" send the spell)
I find on the unity Store a plugin named "Rewired" that seem to do that, but it's cost 40€and handle too many feature that I don't want.
So I try to create myself my own script to solve my issue, but I don't know how to create the combination of 2 keycode pressed.
This is my script bellow, do you have any idea on how can I create this ?
KeyCode key;
KeyCode curModifiersKey;(alt, ctrl)
KeyCode nonModifierKey;
KeyCode firstModifierKeyInfo;
KeyCode finalKey;
public void DetectedSeveralInput(KeyCode key)
{
if (key != KeyCode.AltGr)
{
if (key == KeyCode.LeftAlt || key == KeyCode.RightAlt || key == KeyCode.LeftControl || key == KeyCode.RightControl)
{
if (modifierPressedCount == 0)
{
firstModifierKeyInfo = key;
modifierPressedCount += 1;
}
curModifiersKey = key;
}
nonModifierKey = key;
//finalKey = curModifiersKey + nonModifierKey
LogVariables();
}
else
{
Debug.Log("AltGR pressed");
return;
}
}
What I do to detect multiple key press is like this
void Update()
{
bool shiftPressed = Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift);
bool keyPressed = Input.GetKeyUp( /* other key code here */ );
if(shiftPressed && keyPressed)
{
//Do logic here
}
}
I check shift key being held with Input.GetKey, but makes sure that the logic only happens once by making the other check an Input.GetKeyUp so it will only be true on key release.
Thanks Tricko for the answer.
But the issue is that i can't do this sytem when you got like 10 units, who have 4 spells.
My reference on it is Starcraft 2 where you have a full panel for your own keybinding when you can add mouse button or ctrl/shift/alt also.
That why i want to so something that save the 2 input into one (if it's possible) and relate it to the speel n°X for my unit Y

C# - Window.Current.CoreWindow.GetKeyState not working as expected

I am developing a simple Universal Windows App using C#. I have a RichEditBox and I found a weird behavior when using Control+I key combination, which for some reason inserts a Tab (is that expected?). Because I wanted the combination of keys to toggle Italic font style, I thought the best way was through the KeyDown event.
So, this is my code:
private void richbox_KeyDown(object sender, KeyRoutedEventArgs e)
{
System.Diagnostics.Debug.Write("\nKeyDown : " + e.Key.ToString());
if (e.Key == VirtualKey.Tab)
{
richbox.Document.Selection.TypeText("\t");
e.Handled = true;
}
else if (Window.Current.CoreWindow.GetKeyState(VirtualKey.Control) == Windows.UI.Core.CoreVirtualKeyStates.Down)
{
//If Control is pressed down, check if current key is B,I,U...
System.Diagnostics.Debug.Write(" => Control is down!");
switch (e.OriginalKey)
{
case VirtualKey.B:
toogleBold();
e.Handled = true;
break;
case VirtualKey.I:
e.Handled = true;
toogleItalic();
break;
case VirtualKey.U:
toogleUnderline();
e.Handled = true;
break;
}
}
}
My problem is, the condition on the Else If is not always true when I press the Control key. I would like to understand why and what could I do to fix it.
If I run the code and I press the control key a few times, this is the output:
KeyDown : Control => Control is down!
KeyDown : Control
KeyDown : Control => Control is down!
KeyDown : Control
...
Thanks in advance :)
I tried your code and used debugger output to see what the actual state of Ctrl is in those situations:
var state = Window.Current.CoreWindow.GetKeyState(VirtualKey.Control);
Debug.WriteLine(state);
What I found out is that the second time you press the key, its state is not Down, but Down|Locked, more specifically Windows.UI.Core.CoreVirtualKeyStates.Down | Windows.UI.Core.CoreVirtualKeyStates.Locked. It turns out CoreVirtualKeyStates is a flag enum and it can have multiple values at the same time. In this case you are comparing with == which means you don't get a match. You can first use the HasFlag method or bitwise AND (&) to get the right value out and then compare and you will be good to go!
That means either this:
else if ( Window.Current.CoreWindow.GetKeyState(VirtualKey.Control).
HasFlag( CoreVirtualKeyStates.Down ) )
{
//rest of the code
}
Or this:
else if (
( Window.Current.CoreWindow.GetKeyState(VirtualKey.Control) &
Windows.UI.Core.CoreVirtualKeyStates.Down )
== CoreVirtualKeyStates.Down )
{
//rest of the code
}

Calculator keypress handle

I'm currently working on a calculator project and I have run into two problems.
The first problem is how to handle the keypress event so that numbers plus (+-/*.) all work however every other key is blocked. Heres the code im using at the moment:
if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar))
{
e.Handled = true;
}
I know I could add each symbol separately by using && (e.KeyChar != '+') && (e.KeyChar != '-') but is there an easier more efficient way of handle all of these keys?
Edit: Sorry forgot to mention that my calculator uses a text box so that is why I need to block the use of letters and some symbols
My second question is how can I stop the user being able to write two or more decimal points in one number for example 9.5.6 or 0.3.2.9?
Thanks
Declare char array on class level:
private char[] allowed = new char[]
{
'/','*','+','-'
};
On keypress event:
if (!char.IsDigit(e.KeyChar) && !allowed.Contains(e.KeyChar) )
{
e.Handled = true;
}

Send Button in Serial

I want to make RC and remote it using serial communication. I want to:
if i press 'W' in keyboard, send '1000'
if i press 'S' in keyboard, send '0100'
if i press 'A' in keyboard, send '0010'
if i press 'D' in keyboard, send '0001'
if i press 'W' and 'A', send '1010'
if i press 'W' and 'D', send '1001'
etc, just like we play a game
I make a code, but it didn't work when I press A and W together. The code didn't send '1010', but only send '1000'
private void SEND_KeyPress(object sender, KeyPressEventArgs e)
{
string tx;
if (e.KeyChar == (char)Keys.W & e.KeyChar == (char)Keys.A)
{
tx = "1010";
serialPort1.Write(tx);
}
if (e.KeyChar == (char)Keys.W & e.KeyChar == (char)Keys.D)
{
tx = "1001";
serialPort1.Write(tx);
}
if (e.KeyChar == (char)Keys.S & e.KeyChar == (char)Keys.A)
{
tx = "0110";
serialPort1.Write(tx);
}
if (e.KeyChar == (char)Keys.W & e.KeyChar == (char)Keys.A)
{
tx = "0101";
serialPort1.Write(tx);
}
if (e.KeyChar == (char)Keys.W)
{
tx = "1000";
serialPort1.Write(tx);
}
if (e.KeyChar == (char)Keys.S)
{
tx = "0100";
serialPort1.Write(tx);
}
if (e.KeyChar == (char)Keys.A)
{
tx = "0010";
serialPort1.Write(tx);
}
if (e.KeyChar == (char)Keys.D)
{
tx = "0001";
serialPort1.Write(tx);
}
}
A and W can never be truly pressed at the same time, no matter how much you try they will be off. One always happens before the other. Keypress fires for each key press.
You need to subscribe to keydown and keyup. When keydown happens record the key that was pressed in a hashlist. When keyup happens check if the hashlist contains A and W, then send 1010.
Always check your highest key combination first, before processing shorter key combinations, and then single keys. It's important to do it in Keyup because the user needs a chance to press all the keys down that go together and hold them. If you tried to do it in keydown you'd have the same problem (always 1 at a time).
//DetectCombination like this:
public DateTime PrevPress { get; set; }
public DateTime CurrentPress { get; set; }
public string PrevKey { get; set; }
private void SEND_KeyPress(object sender, KeyPressEventArgs e)
{
string keycomb = DetectCombination(e.KeyChar.toString);
}
public string DetectCombination(string currentKey)
{
CurrentPress = DateTime.Now;
if(CurrentPress.CompareTo(PrevPress) < //100ms)
{
PrevKey+=currentKey;
}
else
{
PrevKey = currentKey;
PrevPress = CurrentPress;
}
return PrevKey;
}
//One more function will be required to apply your logic, but seems like you'd take care of it.
From the MSDN documentation:
Occurs when a character. space or backspace key is pressed while the
control has focus.
This event handler is fired once per key. This means that this line
if (e.KeyChar == (char)Keys.W & e.KeyChar == (char)Keys.A)
Will always evaluate to false. Not to mention the fact that a variable cannot be multiple values at once.
Therefore if you want to detect multiple keys, you will have to do it another way. One way could be, every time you press a key, store the value in a buffer, first checking if the buffer already has a value, and if so, modify the sending value accordingly. Then have a timer running, so every time the timer elapses it will send whatever data is in the buffer, then clear it.
A and W can never be truly pressed at the same time,first check W and then check A,finally pass value 1010
if (e.KeyChar == (char)Keys.W)
{
if(e.KeyChar == (char)Keys.A)
{
tx = "1010";
serialPort1.Write(tx);
}
}

Categories

Resources