I want to be able to use the space key to modify the behavior of the mouse while it is held down. Without knowing better I am imagining it involves some kind of coordination between two (or three) event handler - mousemove, keydown, and keyup. But I am wondering if there is some way to handle it entirely within one event handler - mousemove.
Example code to give an idea of what I hope to be able to do...
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
if (Keyboard.KeyDown == Keys.Space)
{
/* Do modified behavour for left mouse being held down while
space is also held down */
}
else
{
// Do normal behavour for left mouse being held down
}
}
}
Is something like this possible or will I have to save the state of the space key to a class variable using keydown event handler and check it with the mouse move handler?
IT could be done using Control.ModifierKeys & Control.MouseButtons. But only works for kays like shift, ctrl and alt.
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if ((Control.ModifierKeys & Keys.Shift) != 0)
{
if ((Control.MouseButtons & MouseButtons.Left) != 0)
{ // here you go
}
}
}
You should set a variable in your KeyDown-Event and check it in your MouseEvent:
bool buttonpressed = false;
private void KeyDown_Event(object s, System.Windows.Forms.KeyEventArgs e)
{
if(e.KeyCode == KeyCode.Space)
buttonpressed = true;
else
buttonpressed = false;
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
if (buttonPressed)
{
/* Do modified behavour for left mouse being held down while
space is also held down */
}
else
{
// Do normal behavour for left mouse being held down
}
}
}
I'd have a variable that tracks when Keys.Space is in the Pressed state, then trigger it with KeyUp and KeyDown events
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
// Check if Key.Space pressed
if(SpacePressed) {
// Do something
}
}
private void KeyPressed_Event(object sender, KeyEventArgs e) {
// Check if Key.Space pressed
if(e.Key == Key.Space) {
SpacePressed = true;
}
}
private void KeyRelease_Event(object sender, KeyEventArgs e) {
// Check if Key.Space pressed
if(e.Key == Key.Space) {
SpacePressed = false;
}
}
You could use PInvoke to call GetKeyState in User32.dll.
Related
I have registed ctrl+` as a hotkey,and I want to display a window when I press the hotkey and not release the leftctrl key and toggle ` key to do something else just like alt+tab switch the application.Here is the code.
private void ListOnKeyDown(object sender, KeyEventArgs e)
{
if (e.SystemKey==Key.LeftCtrl && e.Key == Key.Oem3)
{
m_host.SelectNext();
}
}
But I found this way only fired one key.So what's the right way to fire the key event?
And here is the debug information.
debug information
Just change your keydown event to detect the modifier this way
private void ListOnKeyDown(object sender, KeyEventArgs e)
{
if (Keyboard.Modifiers == ModifierKeys.Control && e.Key == Key.Oem3)
{
m_host.SelectNext();
e.Handled = true;
}
}
Because onKeyDown event works for ONE key only, in order to use two keys at same time you need little improvise:
bool firstkeyisOn = false;
private void ListOnKeyDown(object sender, KeyEventArgs e)
{
if (e.SystemKey==Key.LeftCtrl/*Or other key by choice*/)
{
firstkeyisOn = true;
e.Handled = true;
return;
}
if(firstkeyisOn && (e.Key == Key.Oem3/*Or other key by choice*/))
{
m_host.SelectNext();
}
}
private void ListOnKeyUp(object sender, KeyEventArgs e)
{
if (e.SystemKey==Key.LeftCtrl/*Key must be same as holding one*/)
{
firstkeyisOn = false;
}
//or
//firstkeyisOn = false;
}
To cancel hotkey mode you just add firstkeyisOn = false under OnKeyUp event and you good to go.
I have a question. Examples that i find is on a "KeyPress" and they are not longer working on WPF
Can you tell me, how to allow only specified keys from keybord to be write on WPF textbox? I know about keyUp and Down functions, but how to define letters that i want to by type into it?
I think it will be easier, if i will post my code and i tell u what i want to do. What to change here?
private void textBox_KeyDown(object sender, KeyEventArgs e)
{
//something here to only allow "A" key to be pressed and displeyed into textbox
if (e.Key == Key.A)
{
stoper.Start();
}
}
private void textBox_KeyUp(object sender, KeyEventArgs e)
{
if (e.Key == Key.A)
{
//here i stop the stopwatch to count time of pressing the key
stoper.Stop();
string aS = stoper.ElapsedMilliseconds.ToString();
int aI = Convert.ToInt32(aS);
stoper.Reset();
}
}
You can use PreviewKeyDown and use e.Key to filter out what you need.
Or, in any place of your code you can use Keyboard class:
if (Keyboard.IsKeyDown(Key.E)) { /* your code */ }
UPDATE:
To forbid a key, you need to set event as handled:
if (e.Key == Key.E)
{
e.Handled = true;
MessageBox.Show($"{e.Key.ToString()} is forbidden");
}
That thing works pretty fine to me (thanks for #JohnyL):
private void textBox_KeyDown(object sender, KeyEventArgs e)
{
//something here to only allow "A" key to be pressed and displeyed into textbox
if (e.Key == Key.A)
{
stoper.Start();
}
else
e.Handled = true;
}
private void textBox_KeyUp(object sender, KeyEventArgs e)
{
if (e.Key == Key.A)
{
//here i stop the stopwatch to count time of pressing the key
stoper.Stop();
string aS = stoper.ElapsedMilliseconds.ToString();
int aI = Convert.ToInt32(aS);
stoper.Reset();
}
}
This piece of code detect most keys and puts it in a messageBox, but one of the keys it doesn't is the enter key. *Note it is a key_down method
MessageBox.Show(e.KeyData.ToString());
so far I have tried so many methods to fix and searched a lot for an answer
I have tried this
private void button1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
MessageBox.Show("this is it");
e.IsInputKey = true;
}
}
it says 0 references which I know I'm not calling the method but where do I call it?
where ever I do call it, it gives an error.
you delete this line
e.IsInputKey = true;
private void button1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
MessageBox.Show("this is it");
//e.IsInputKey = true;
}
}
or
private void button1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
MessageBox.Show("this is it");
//e.IsInputKey = true;
}
}
In your Form1 Design Properties:
AcceptButton Property set dropdown to button1 or the name of your Button
KeyUp Event of your Button
private void button1_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
MessageBox.Show("Enter key has been pressed");
}
}
or
private void button1_KeyUp(object sender, KeyEventArgs e)
{
button1_KeyDown(sender, e);
}
private void button1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
MessageBox.Show("Enter key has been pressed");
}
}
Put this line soon after: InitializeComponents(); -->
button1.PreviewKeyDown +=new PreviewKeyDownEventHandler(button1_PreviewKeyDown);
.
The event you're trying to use will only fire when you focus on that button. The focus is passed in 2 different ways ( via user interaction ) one of which is an actual mouse click on that element and another is "tabbing" on to the control, and make sure you read about "Events" and "EventsHandlers"
So I am trying to make a program that disables all keyboard input but can still detect when a key is being pressed (doesn't matter which).
I tried using the BlockInput method but it blocked ALL input (mouse and keyboard) and wouldn't allow for further detection of keyboard press.
This is my current code (function is a timer with a 1 tick interval)
private void detect_key_press_Tick(object sender, EventArgs e)
{
Process p = Process.GetCurrentProcess();
if (p != null)
{
IntPtr h = p.MainWindowHandle;
//SetForegroundWindow(h);
if (Keyboard.IsKeyDown(Key.A))
{
//SendKeys.SendWait("k");
this.BackColor = Color.Red;
}
else
{
this.BackColor = Control.DefaultBackColor;
}
}
}
How can I do this please? Thanks.
EDIT
I tried
private void Form1_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{
e.Handled = true;
e.SuppressKeyPress = true;
}
but no success. Keys still get proccessed.
I assume you use Windows Forms ?
If you set the KeyPreview on your form to true and create an event on the KeyDown for the form, you can handle the keyboard input that way.
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyData == Keys.S) // some accepted key
//Do something with it
else
{
//or cancel the key entry
e.Handled = true;
e.SuppressKeyPress = true;
}
}
I have a program where I want to move a Graphic with the keyboard keys. I originally had a function to move the graphic whenever pressed a button, but I abandoned that method to get around the keyboard repeat delay. Instead, I decided I would use a timer, which I would enable upon the KeyPess event, and disable on the KeyUp event. At first, I used 4 different timers for each different direction, and although it worked I noticed my program had begun to freeze quite often. I decided to use a single timer for all movements, and use if statements to determine the direction. Now, it seems that my Graphic doesn't move at all, even though all I did was copy and paste code.
enum Direction
{
Left, Right, Up, Down
}
private Direction _objectDirection;
int _x = 100, _y = 100;
private void Form1_Paint(object sender, PaintEventArgs e)
{
Picture.MakeTransparent(Color.Transparent);
e.Graphics.DrawImage(Picture, _x, _y);
}
void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.W)
{
if (timerAnimation.Enabled == false)
{
AnimationMaxFrame = 3;
timerAnimation.Enabled = true;
}
_objectDirection = Direction.Up;
timerMovement.Enabled = true;
}
//The rest of this code is omitted to save space, it is repeated 4 times with the only
//changes being the key pressed, and the object direction.
Invalidate();
}
void Form1_KeyUp(object sender, KeyEventArgs e)
{
timerAnimation.Enabled = false;
timerMovement.Enabled = false;
Picture = Idle;
this.Refresh();
}
private void timerMovement_Tick(object sender, EventArgs e)
{
if (_objectDirection == Direction.Up)
{
if (_y > 24)
{ _y = _y - 2; }
else
{ timerMovement.Enabled = false; }
//This if statement is to ensure that the object doesn't leave the form.
//I have tried removing them already, they're not the problem.
}
//Again, this is shortened to save space, it is repeated for each direction.
Invalidate();
}
What is preventing my graphic from moving, and is there a better way to do this? There is still a lot of functionality I want to add to this, but it's already freezing.
Not sure you are making a game with WinForms, but to the point...
You need to handle key pressed events, when a key pressed event fires set a boolean flag in your code depending on if the event was a press or release. Then in your update code check the flag and do your movement accordingly.
It would be something like this (example code):
bool moveup = false;
void KeyPressed(object sender, KeyEventArgs e)
{
// check for keys that trigger starting of movement
if (e.KeyCode == Keys.W) moveup = true;
}
void KeyReleased(object sender, EventEventArgs e)
{
// check for keys that trigger stopping of movement
if (e.KeyCode == Keys.W) moveup = false;
}
void TimerTick(obect sender, EventArgs e)
{
if (moveup)
{
// move your object
}
}