I have a class that catches keyboard keys and I want to catch a specific combination:
Alt + 1
And in case this combination is detected to do my stuff.
This is what I have try:
private bool isAltPressed;
private bool isOnePressed;
private bool bothPressed;
private void HookManager_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{
if (e.KeyCode == Keys.LMenu)
isAltPressed = true;
if (e.KeyCode == Keys.D1)
isOnePressed = true;
if (isAltPressed & isOnePressed)
bothPressed = true;
}
private void HookManager_KeyUp(object sender, System.Windows.Forms.KeyEventArgs e)
{
if (bothPressed)
// Do something...
if (e.KeyCode == Keys.LMenu)
{
isAltPressed = false;
bothPressed = false;
}
if (e.KeyCode == Keys.D1)
{
isOnePressed = false;
bothPressed = false;
}
}
So where do I need to verify that both keys are pressed and released and then do my stuff?
Try this:
if ( e.KeyData == (Keys.Alt | Keys.D1) )
Keys is a struct having a flag attribute.
It means that several key codes can be combinated with the logic or operator to form the result.
[Flags]
public enum Keys ...
You should not wait for alt key to be released to perform your action. Unless you can explain why you need to make sure both the alt key and the key pressed must be released before 'doing something', the following code should suffice in either your KeyUp or KeyDown event.
if (e.Modifiers == Keys.Alt && e.KeyCode == Keys.D1)
{
// Do Something
}
Related
I have set KeyPreview property of the form to true in order to call keyboard events of the form before control events.
Both the form and the control in the form have KeyDown event like:
form:
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control && (e.KeyCode == Keys.Enter || e.KeyCode == Keys.Return)) {
MessageBox.Show("Control + Enter (Form)");
}
}
control:
private void TextBox1_KeyDown(object sender, KeyEventArgs e)
{
if (!e.Control && (e.KeyCode == Keys.Enter || e.KeyCode == Keys.Return)) {
MessageBox.Show("Control + Enter (TextBox)");
}
}
As you see the difference between these two parts of code is that in the form event code I need to call the KeyDown event when the user presses CTRL and Enter keys at the same time,
In the TextBox event code, I need to call the event when the user presses Enter key without holding CTRL-key.
The problem is that when I press Ctrl and Enter keys at the same time both of the above events will call.
How to prevent call both events?
I suggest you use the textBox1_KeyUp event. You can refer to the following code. My test was successful.
public Form1()
{
InitializeComponent();
this.KeyPreview = true;
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control && (e.KeyCode == Keys.Enter || e.KeyCode == Keys.Return))
{
MessageBox.Show("Control + Enter (Form)");
}
}
private void textBox1_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Control)
{
e.Handled = true;
}
else if (e.KeyCode == Keys.Enter)
{
MessageBox.Show("Control + Enter (TextBox)");
}
}
Use the ProcessCmdKey and like this.
protected override bool ProcessCmdKey(ref Message msg, System.Windows.Forms.Keys keyData)
{
int WM_ALRT_DOWN = 0x0104;
int WM_KEYDOWN = 0x0100;
if (msg.Msg == WM_ALRT_DOWN && (int)msg.WParam == (int)Keys.F4) //Alt + F4
{
return true; // The key is manually processed
}
if (msg.Msg == WM_KEYDOWN && (int)msg.WParam == (int)Keys.Escape) //Esc
{
return true; // The key is manually processed
}
if (msg.Msg == WM_KEYDOWN && (int)msg.WParam == (int)Keys.Space) //Space
{
return true; // The key is manually processed
}
}
I'm creating ping pong game. I managed to move both lines (picture box) at same time if keys for movement are pressed down. Problem is that if control for one player is pressed down and then other player JUST clicks (1 time) it breaks movement of other player,so that he needs to press key again. I tried to fix it with keypress and Keyboard.IsKeyDownbut no luck.
Here is my code:
public void Form1_KeyDown(object sender, KeyEventArgs e)
{
Keys up1 = (Keys)Enum.Parse(typeof(Keys), form1.p5_text_kontrole_gor1.Text , true);
Keys down1 = (Keys)Enum.Parse(typeof(Keys), form1.p5_text_kontrole_dol1.Text , true);
Keys up2 = (Keys)Enum.Parse(typeof(Keys), form1.p5_text_kontrole_gor2.Text, true);
Keys down2 = (Keys)Enum.Parse(typeof(Keys), form1.p5_text_kontrole_dol2.Text, true);
if (e.KeyCode == Keys.Escape)
Application.Exit();
if(e.KeyCode == up1)
{
goup1 = true;
}
if (e.KeyCode == down1)
{
godown1 = true;
}
if (e.KeyCode == up2)
{
goup2 = true;
}
if (e.KeyCode == down2)
{
godown2 = true;
}
igra1();
}
private void Form1_KeyUp(object sender, KeyEventArgs e)
{
Keys up1 = (Keys)Enum.Parse(typeof(Keys), form1.p5_text_kontrole_gor1.Text, true);
Keys down1 = (Keys)Enum.Parse(typeof(Keys), form1.p5_text_kontrole_dol1.Text, true);
Keys up2 = (Keys)Enum.Parse(typeof(Keys), form1.p5_text_kontrole_gor2.Text, true);
Keys down2 = (Keys)Enum.Parse(typeof(Keys), form1.p5_text_kontrole_dol2.Text, true);
if (e.KeyCode == up1)
{
goup1 = false;
}
if (e.KeyCode == down1)
{
godown1 = false;
}
if (e.KeyCode == up2)
{
goup2 = false;
}
if (e.KeyCode == down2)
{
godown2 = false;
}
igra1();
}
public void igra1()
{
if (goup1)
{
if (form1.p6_ploscek1.Top > form1.panel6_pongIgra.Top)
form1.p6_ploscek1.Top -= 15;
}
if (goup2)
{
if (form1.p6_ploscek2.Top > form1.panel6_pongIgra.Top)
form1.p6_ploscek2.Top -= 15;
}
if (godown1)
{
if (form1.p6_ploscek1.Bottom < form1.panel6_pongIgra.Bottom)
form1.p6_ploscek1.Top += 15;
}
if (godown2)
{
if (form1.p6_ploscek2.Bottom < form1.panel6_pongIgra.Bottom)
form1.p6_ploscek2.Top += 15;
}
}
I believe you're relying on the fact that keys get repeated by Windows while you hold them down to make your game pieces move. The first key being held down will stop repeating because the new key being held down is repeating instead.
To fix this move the pieces in the Tick() event of a Timer control. In the KeyDown/KeyUp events simply change the state of a variable that represents whether the associated piece should be moving (and what direction it should go). The Timer code will look at the state variables and act accordingly...
I'm designing a device app. Compact Framework 2.0
I want the user to press F1 to navigate to the next screen, but it does not work.
Can't seem to find a solution.
Is it possible?
This is how I normally use Keypress:
This works:
if (e.KeyChar == (char)Keys.M)
{
MessageBox.Show("M pressed");
e.Handled = true;
}
This dos NOT work:
if (e.KeyChar == (char)Keys.F1)
{
MessageBox.Show("F1 pressed");
e.Handled = true;
}
try this
private void Form1_Load(object sender, EventArgs e)
{
this.KeyPreview = true;
this.KeyDown += new KeyEventHandler(Form1_KeyDown);
}
void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode.ToString() == "F1")
{
MessageBox.Show("F1 pressed");
}
}
Refer This
You can override the ProcessCmdKey method of your form class and use keyData == Keys.F1 to check whether F1 is pressed. Above link has example as follows.
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.F1)
{
MessageBox.Show("You pressed the F1 key");
return true; // indicate that you handled this keystroke
}
// Call the base class
return base.ProcessCmdKey(ref msg, keyData)
}
Some keys(like f1,f2,arrow keys ,tab ....)cannot be "captured" by keychar for that you need to use keycode:
if (e.KeyCode == Keys.F1)
{
// do stuff
}
keychar property - http://msdn.microsoft.com/en-us/library/system.windows.forms.keypresseventargs.keychar.aspx
Use KeyDown instead of KeyPress:
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyData == Keys.F1)
{
// your code here
}
}
Also set KeyPreview to true
I need to have a text box on which events of Delete and Backspace works.Is it possible to have such a text box in C#,or restrict the behavior of text box in such a way. Other keys do not work.
Use TextBox.KeyPress event:
private void textBox1_KeyPress(object sender, System.Windows.Forms.KeyEventArgs e)
{
if (e.KeyCode == Keys.Delete || e.KeyCode == Keys.Back)
{
// your stuff
}
e.Handled = true;
}
For winforms you can do it like this:
protected void myTextBox_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
{
e.Handled = !IsValidCharacter(e.KeyChar);
}
private bool IsValidCharacter(Keys c)
{
bool isValid = false;
if (c == Keys.Space)
{
isValid = true;
}
return isValid;
}
If you want delete key works ..
private void textBox1_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{
Keys k = e.KeyCode
If Not (k = Keys.Back Or k = Keys.Delete)
{
e.Handled = True
}
}
If you press and hold the 5 key on the numpad it will continue to execute a statement in the KeyDown event handler. How can i ensure the statement is executed only once, even if i hold the key down?
Thanks for your attention.
private void form_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{
if (e.KeyCode == Keys.NumPad5)
{
dados.enviar("f"); //I want this to run only once!
}
}
You can set flag on key down and reset it on key up.
private bool isPressed = false;
public Form1()
{
InitializeComponent();
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if(e.KeyCode == Keys.B && !isPressed )
{
isPressed = true;
// do work
}
}
private void Form1_KeyUp(object sender, KeyEventArgs e)
{
if (isPressed )
isPressed = false;
}
bool alreadyPressed = false;
...
if (e.KeyCode == Keys.NumPad5 && ! alreadyPressed)
{
alreadyPressed = true;
...
You should use IsRepeat flag to check if it's the first time key is pressed.
if (e.KeyCode == Keys.NumPad5 && !e.IsRepeat)