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);
}
}
Related
I'm checking the user ID in the text box. And it can not start with a letter or digit '0'. I can catch the wrong entry and send a message to the screen. But the wrong entry will be in the text box until I hit another key. And if this is an acceptable digit then the wrong entry stays at the beginning of the string. So I need to get rid of the wrong entry immediately after the message dialog box. Any suggestion?
private void TxtUserID_KeyPress(object sender, KeyPressEventArgs e)
{
if (!char.IsDigit(e.KeyChar) && !char.IsControl(e.KeyChar))
{
MessageBox.Show(" Your User ID can not begin with a letter !!!");
//txtUserID.Text = string.Empty;
txtUserID.Clear();
}
else if (e.KeyChar == '0')
{
MessageBox.Show("Your User ID can not begin with 0 !!!");
txtUserID.Text = string.Empty;
}
}// end of keypress
I suggest using TextChanged instead of KeyPress event: whatever changed TxtUserID.Text (e.g. Paste, or, imagine, user put "12340" and then deleted "1234" in order to obtain "0") validate the TxtUserID
private static bool IsNameValid(string name) {
if (string.IsNullOrEmpty(name))
return true;
else if (name.Any(c => c < '0' || c > '9')) {
MessageBox.Show("Your User ID must contain digits only!");
return false;
}
else if (name.StartsWith("0")) {
MessageBox.Show("Your User ID must not start from 0!");
return false;
}
return true;
}
private void TxtUserID_TextChanged(object sender, EventArgs e) {
if (!IsNameValid(TxtUserID.Text))
txtUserID.Clear(); // Taken from the question
}
Edit: As Thomas Voß pointed out, clearing the entire text can be to cruel for a user (imagine that he's printed "1001234566978563" and then decided to remove leading "100"), probably
txtUserID.Text = string.Concat(txtUserID
.Text
.Where(c => c >= '0' && c <= '9') // Digits only
.SkipWhile(c => c == '0')); // Trim all starting '0'
instead of txtUserID.Clear(); when we remove all characters but digits and trim leadibng 0 is a better choice.
I have a TextEdit.PreviewKeyDown method where I want to check if an input character is equal to a special character of my choosing.
For an instance I want to check if the user's input character is '#'. I'd use:
if(e.Key == Key.D3 && (Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift)
The problem is I don't know what the special character will be at the time and I can't possibly program all the cases, so I wanted something like:
string strSpecChar = GetSpecialCharacter();
if(strSpecChar = e.Key) {do_sth();}
Which doesn't work at all, because if I press, for example '3', the e.Key value will be equal to 'D3', so if my strSpecChar value is '3' I can't get to the do_sth()
I have browsed through the System.Windows.Input.KeyEventArgs docs and I've found nothing and I've also read some discouraging posts on other forums.
Is there any way I would be able to compare the PreviewKeyDown e and string strSpecChar?
private void Window_PreviewKeyDown(object sender, KeyEventArgs e)
{
string strNewLigneSign = String.Empty;
if (InsertTextDialogHelper != null)
strNewLigneSign = InsertTextDialogHelper.GetNewLineSign();
if (e.Key.Equals(strNewLigneSign))
{
if (!String.IsNullOrEmpty(strNewLigneSign))
{
int strCaretPosition = TextBox.CaretIndex;
e.Handled = true;
string strNewText = "\r\n";
CurrentDialogData.TextValue = CurrentDialogData.TextValue.Insert(strCaretPosition, strNewText);
TextBox.CaretIndex = strCaretPosition + strNewText.Length;
}
}
}
EDIT:
As per #mm8's suggestion I tried to implement it in the TextEdit.PreviewTextInput property as follows:
XAML
<dxe:TextEdit Name="TextBox"
PreviewTextInput="TextBox_PreviewTextInput" \">
</dxe:TextEdit>
C#
private void TextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
string strNewLigneSign = String.Empty;
if(InsertTextDialogHelper != null)
strNewLigneSign = InsertTextDialogHelper.GetNewLineSign();
if(!String.IsNullOrEmpty(strNewLigneSign))
{
if(e.Text.Contains(strNewLigneSign))
{
int strCaretPosition = TextBox.CaretIndex;
e.Handled = true;
string strNewText = Unhashify(e.Text);
CurrentDialogData.TextValue = CurrentDialogData.TextValue.Insert(strCaretPosition, strNewText);
TextBox.CaretIndex = strCaretPosition + strNewText.Length;
}
}
}
However when I run the app and set the breakpoints anywhere inside that method it seems never to go inside it.
The exact same solution worked for me back when I used it in wpf's TextBox, but as soon as I switched to devexpress, the TextBox_PreviewTextInput method is never called.
A key is a key and not a character. It's eventually mapped to a character depending on the input device.
You may want to consider handling PreviewTextInput and check the value of Text[0] of the TextCompositionEventArgs instead of handling PreviewKeyDown.
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
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;
}
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