I am using the below code to capture the ctrl + alt + Q hot keys, which works perfectly.
But, i want to use this in a background application. Since my application does not have any forms, i want to use the same code inside a class file.
i am confuse, because i cannot write a event handler [keypressed] in class file.
Instead i want to use the keypress in thread.
Please help.
public DialogResult Result;
KeyboardHook hook = new KeyboardHook();
public Form1()
{
InitializeComponent();
// register the event that is fired after the key press.
hook.KeyPressed += new EventHandler<KeyPressedEventArgs>(hook_KeyPressed);
// register the control + alt + F12 combination as hot key.
hook.RegisterHotKey((ModifierKeys)2 | (ModifierKeys)1, Keys.Q);
}
void hook_KeyPressed(object sender, KeyPressedEventArgs e)
{
Result = MessageBox.Show("Are you sure, you want to log off?","Log off"
,MessageBoxButtons.YesNo
,MessageBoxIcon.Warning);
if (Result == DialogResult.Yes)
{
}
else
{
}
}
If you want to capture a global hotkey without a form, I'm afraid you cannot.
The reason is that global hotkeys are sent to a window handle (and processed in wndProc, aka. the message pump)
So basically the way Windows works, you cannot use global hotkeys without a form to received them.
I'm not entirely certain this is what you want to do however. But on the other there won't be any local hotkeys without a form either, so I cannot see what else it might be.
You may want to further clarify your question a bit (no offense)
Related
For example, say I wanted to switch Ctrl+C and Ctrl+V so that Ctrl+C will paste and Ctrl+V will copy. I will need to first override Ctrl+Ccopying and then make Ctrl+C paste. I will have to do the same with Ctrl + V as well, except I will need to override the paste and make it copy.
How should I go about doing this? Is this possible in a UWP app using C#? Whenever I look up something along the lines of "remapping keyboard shortcuts in c#", it shows me results for remapping keyboard shortcuts in Visual Studio, not for in my app.
>How do I remap keyboard shortcuts in UWP C# app?
It is a little complicated but you could do it in your app. You need to handle the keyboard input event - CoreWindow.KeyDown Event first. In the input event, check both if the control key is pressed and if the C key is pressed. When both of them are pressed, then you could do your own logic in the event handler.
Here is a sample code about how to handle the keydown event.
Window.Current.CoreWindow.KeyDown += CoreWindow_KeyDown;
private void CoreWindow_KeyDown(Windows.UI.Core.CoreWindow sender, Windows.UI.Core.KeyEventArgs args)
{
var ctrl = Window.Current.CoreWindow.GetKeyState(VirtualKey.Control);
if (ctrl.HasFlag(CoreVirtualKeyStates.Down) && args.VirtualKey == VirtualKey.V)
{
//clean the data in the clipboard.
Windows.ApplicationModel.DataTransfer.Clipboard.Clear();
// do your stuff
Debug.WriteLine("Ctr+V");
return;
} else if(ctrl.HasFlag(CoreVirtualKeyStates.Down) && args.VirtualKey == VirtualKey.C)
{
//clean the data in the clipboard.
Windows.ApplicationModel.DataTransfer.Clipboard.Clear();
// do your stuff
Debug.WriteLine("Ctr+C");
return;
}
}
Let's say my application consists of Rich Text Box and a button. I want the button to be enabled when users press a key in RTB, but it can't be any of modifiers.
I can handle this in some KeyEvent like PreviewKeyDown, but it doesn't work when I press modifier + other char, for instance SHIFT + S, which is valid, cause the result is letter S. Is there a way to separate my demand or should I make use of some different approach? I could use TextChanged, but there are many more actions that I've already written and I would prefer to do it that way.
Simple explanation:
private void richTextBox_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
if (!e.Alt && !e.Control && !e.Shift)
{
this.button1.Enabled = true;
else
this.button1.Enabled = false;
}
}
Since the KeyPress event Occurs when a character, space or backspace key is pressed while the control has focus and modifier keys has no impact on this event, it seems using KeyPress may help you.
But you better consider handling TextChangedevent and checking TextLength, since the user can paste something in the RichtextBox, and this way none of key events will fire.
I am using this Global Keyboard Hook as found here: Using global keyboard hook (WH_KEYBOARD_LL) in WPF / C#
It works great, and I use a little piece of code to handle the keydown event.
private void Klistener_KeyDown(object sender, RawKeyEventArgs e)
{
if (e.Key == Key.Snapshot)
{
MessageBox.Show("Key Pressed!");
}
}
However, any other handlers tied to Key.Snapshot will still work. For instance Windows default for the key will print screen and save it into the clipboard, what if I didn't want any other actions happening after my handler?
I'm not entirely fluent in the Keyboard Hook I am using, but I'm sure there must be a way to implement a e.Handled property or something similar as can be found in KeyEventArgs.
Any ideas how I would go about doing this? Thanks.
The MSDN says :
If the hook procedure processed the message, it may return a nonzero value to prevent the system from passing the message to the rest of the hook chain or the target window procedure.
So you would need to just return 1 in LowLevelKeyboardProc if the desired key was pressed. Otherwise you return the call to CallNextHookEx
I am creating a simple game for school in C#, where I am controlling a character using the WASD keys. The character is taken from a sprite sheet and put into an imagelist. The imagelist is in a picturebox.
Everything works fine when it's just the picturebox in the form, but when I add a button or something else, it's like it lose focus. It doesn't respond.
I have searched endless pages for a solution to set focus on the picturebox when the form opens, but I haven't found anything that works.
I would really appreciate some help.
Edit: It's WinForms.
The PictureBox cannot take the focus. It is intended as a way to show an image but not intended to allow user input such as via the keyboard.
A crude approach would be to intercept the OnKeyDown event on the Form itself and then test for the keys of interest. This will work as long as the control that has the focus, such as your Button, does not want to process those keys itself.
A better approach would be to override ProcessCmdKey() method of the Form. This method is called on the target control, such as your Button, to decide if the key is special. If the Button does not recognize it as special then it calls the parent control. In this way your Form level method will be called for each key press that is not a special key for the actual target. This allows the Button to still process a ENTER key which is used to press the Button but other keys will be processed by your Form.
Lastly, to intercept all keys before they are handled by any of the controls on the Form you would need to implement the IMessageFilter interface. Something like this...
public partial class MyWindow : Form, IMessageFilter
{
public MyWindow()
{
InitializeComponent();
Application.AddMessageFilter(this);
}
public bool PreFilterMessage(ref Message m)
{
// WM_KEYDOWN
if (m.Msg == 0x0100)
{
// Extract the keys being pressed
Keys keys = ((Keys)((int)m.WParam.ToInt64()));
// Test for the A key....
if (keys == Keys.A)
{
return true; // Prevent message reaching destination
}
}
}
return false;
}
I found event MouseHover with pictureBox1_Hover calling pictureBox1.Focus() worked. When the mouse was hovered over the PictureBox in question, it would gain focus. Other than that, it didn't seem that calling pictureBox1.Focus() during form load had any effect on the focus.
this.pictureBox1.MouseHover += new System.EventHandler(this.pictureBox1_Hover);
private void pictureBox1_Hover(object sender, EventArgs e)
{
pictureBox1.Focus();
}
It worked for me!
The only keyboard hook supported for .NET managed code is a low-level keyboard hook (WH_KEYBOARD_LL).
See Using global keyboard hook (WH_KEYBOARD_LL) in WPF / C#
I have the above code working in my application at the moment so that when you swipe your card you will get a list of all the keystrokes. The problem is for typing delimiter characters such as "%" and ";" it will send me Alt+Numpad+? WPF Key objects corresponding to these symbols.
My question: Is there some way to make this behave more high-level, that is, to capture a string generated from all keyboard commands?
Cheers!
Not sure what's going on, but getting a character like % out of a keyboard hook is very untrivial. The hook only notifies you of virtual keys. But % is a typing key, produced by pressing Shift + 5 on my keyboard (a US layout). Windows normally produces these characters by processing the WM_KEYDOWN/UP messages, generating a WM_CHAR message for the typing key. That's not happening in your case. The low-level Windows function that does this is ToUnicodeEx().
I would guess if you are swiping the card, there's an input somewhere on the wpf form, like a textbox for example? Then I would be inclined to add an event, perhaps a KeyUp Event handler, (The keyboard wedge card scanner does send an end-of-processing signal such as ENTER to indicate the swipe was successful yes?), In the KeyUp Event Handler, build up a string using StringBuilder, and when the end-of-processing signal such as ENTER is caught, you can then remove the "%" and ";" from the StringBuilder instance and do whatever you have to do with it.
It might be easier to use a state system, when the KeyUp event handler receives a "%", then enter another state where the end expected state would be a ";"
static bool StartState = false;
StringBuilder sbInput = new StringBuilder();
private void textBox1_KeyUp(object sender, KeyEventArgs e)
{
if (!StartState){
if (e.KeyCode == Keys.D5) StartState = true;
sbInput.Append((char)e.KeyValue);
}else{
if (e.KeyCode == Keys.OemSemicolon){
StartState = false;
// sbInput will contain the data from the scanner,
// copy it somewhere else and reset sbInput
// sbInput.Remove(0, sbInput.Length);
}
sbInput.Append((char)e.KeyValue);
}
e.Handled = true;
}
Hope this helps,
Best regards,
Tom.