I want to focus a textbox when a key is pressed.
I use this code:
private void MainForm_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
textBoxCode.Focus();
}
With KeyPreview = true on my form.
But when I do that, if I write 'az', only the 'z' char appear in my textbox. If I press only 'a', textboxCode is empty but have the focus.
How not to lose the key pressed?
SOLUTION:
private void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
if (textBox1.Focused == false)
{
textBox1.Text += e.KeyChar.ToString();
textBox1.SelectionStart = textBox1.Text.Length;
textBox1.Focus();
}
}
This is pretty hard to do, the WM_KEYDOWN message that Windows sends is already committed to the window that has the focus. You do not want to get in the business of translating key-down events into typing characters, that's a rocket science on keyboard layouts with dead keys that produces only exploding rockets.
One thing you can do is re-post the keyboard message, now with a window handle of the textbox. You can do this by overriding the form's ProcessCmdKey() method to detect the keystroke and return true to prevent it from being processed any further. Like this:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
if (!textBox1.Focused) {
PostMessage(textBox1.Handle, msg.Msg, msg.WParam, msg.LParam);
textBox1.Focus();
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern IntPtr PostMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);
Something like this:
private void MainForm_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
textBoxCode.Focus();
textBoxCode.Text = (char)e.KeyCode;
}
Related
I have to catch when the user is pressing the up arrow on the keyboard, while the button has the focus. I have written this code to handle the KeyUp event for the button:
private void btnValider_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Up)
{
//do stuff
}
}
but this function didn't handle pressing the up arrow key.
I don't know if it what i want to do is possible or if i have to handle this event from the form ?
As Hans Passant suggested,
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.Up && btnValider.Focused)
{
MessageBox.Show("hit");
return true;
}
else
return base.ProcessCmdKey(ref msg, keyData);
}
handle key down event for the button.
I have a Window with a TextBox. The cursor is inside the TextBox. If I press a key, then I receive a message in WndProc (for KeyUp and KeyDown). But if I set e.Handled = true in the KeyUp and KeyDown events, then I don't receive any key messages:
public partial class MainWindow : Window
{
public MainWindow()
{
Loaded += MainWindow_Loaded;
}
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
var textBox = new TextBox();
textBox.KeyDown += TextBox_KeyDown;
textBox.KeyUp += TextBox_KeyUp;
Content = textBox;
(PresentationSource.FromVisual(this) as HwndSource).AddHook(WndProc);
}
private void TextBox_KeyDown(object sender, KeyEventArgs e)
{
e.Handled = true;
}
private void TextBox_KeyUp(object sender, KeyEventArgs e)
{
e.Handled = true;
}
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
Debug.WriteLine(msg + " " + wParam);
return IntPtr.Zero;
}
}
Is it possible to receive a PreviewKeyDown/PreviewKeyUp event in WndProc?
There are tons of way to intercept key messages. You don't even need any library for this. Using pure Win32 API is OK but if you want simplicity, try handling the ThreadPreprocessMessage event of ComponentDispatcher:
ComponentDispatcher.ThreadPreprocessMessage += (ref MSG m, ref bool handled) => {
//check if WM_KEYDOWN, print some message to test it
if (m.message == 0x100)
{
System.Diagnostics.Debug.Print("Key down!");
}
};
The event is able to receive any key messages before it is actually sent to your window. So it's what you want in this case if you want to handle raw messages (instead of handling PreviewKeyDown, ...).
The AddHook method allows to add some hook proc for the window but it's really limited in WPF (while the equivalent WndProc protected method of Form in winforms can intercept much more messages).
Try using ManagedWinApi. You can install it with NuGet.
PM> Install-Package ManagedWinapi
For extensive examples of keyboard and other msg interception: http://mwinapi.sourceforge.net/
Another alternative is https://easyhook.github.io/
Both libraries are well documented.
I made a program in WinForms that shows a blank screen, and then if you press Enter then something happens..
well i used this code:
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
label1.Visible = false;
Colors.Start();
}
Now when I tried to add some buttons to the blank screen, the option to click on Enter just don't work anymore... no matter what I do. and please don't earse this question, I'm kind of new in programming and I know there's alot of questions like that one, but I couldn't understand them...
thanks
Is the form's AcceptButton property assigned to a button?
If so, that could be grabbing the Enter keystroke first.
An example of the suggestion by Hans Passant:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.Enter)
{
MessageBox.Show("Enter");
return true; // optionally prevent further action(s) on Enter; such as Button clicks
}
return base.ProcessCmdKey(ref msg, keyData);
}
}
Note that if you return true, then controls like the buttons will not get the Enter keystroke.
I am working on a WPF application where I need to know if my application is visible to the user or not. I tried Application.Current.Activated/Deactivated events to change a bool property and use this bool to check as per my requirements. Everything works fine except that the Deactivated event is getting called when a popup (like gtalk chat window) opens or I click in the taskbar, so my bool is changing.
What can I do to check if my app is visible to the user rather than activated/deactivated (which checks if my application is the foreground app or not)?
Application.Current.Activated += Current_Activated;
Application.Current.Deactivated += Current_Deactivated;
void Current_Deactivated(object sender, EventArgs e)
{
IsActive = false;
}
void Current_Activated(object sender, EventArgs e)
{
IsActive = true;
}
And if !IsActive I am showing the notification.
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
HwndSource source = PresentationSource.FromVisual(this) as HwndSource;
source.AddHook(WndProc);
}
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
if (msg == 0x1c)
{
OnActivateApp(wParam != IntPtr.Zero);
}
return IntPtr.Zero;
}
protected void OnActivateApp(bool activate)
{
Console.WriteLine("Activate {0}", activate);
}
Excuse me, do not write and do not understand English very well, but this article has enhanced the solution http://www.codeproject.com/Articles/704390/How-to-be-Notified-when-your-application-is-active
You can use the Application.Windows property to tell you which Windows have been instantiated and not closed (currently open) and then use the Window.IsActive property to tell if any of them are currently active:
Window activeWindow =
Application.Current.Windows.OfType<Window>().SingleOrDefault(w => w.IsActive));
if (activeWindow != null)
{
// activeWindow is the active Window
}
There's a VisibilityChanged Event where you can hook up. You'll find the current visibility state in its EventArgs.
Let me know if I need to post any code ;-)
I want to have the Esc key undo any changes to a textbox since it got focus.
I have the text, but can't seem to figure out how to capture the Esc key. Both KeyUp and KeyPressed don't seem to get it.
This should work. How are you handling the event?
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Escape)
{
MessageBox.Show("Escape Pressed");
}
}
Edit in reply to comment - Try overriding ProcessCmdKey instead:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.Escape && myTextBox.Focused)
{
MessageBox.Show("Escape Pressed");
}
return base.ProcessCmdKey(ref msg, keyData);
}
is this what you're looking for?
string origStr = String.Empty;
private void txtOrig_Enter(object sender, EventArgs e)
{
origStr = txtOrig.Text;
}
private void txtOrig_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == Convert.ToChar(Keys.Escape))
{
txtOrig.Text = origStr;
}
}
Supposedly some keys are not considered "input keys" and so are not listened to by default. You need to handle PreviewKeyDown first to enable it.
myTextBox.PreviewKeyDown += (s, e) => {
if (e.KeyCode == Keys.Escape) {
e.IsInputKey = true;
Debug.Print("ESC should get handled now.");
}
};
However, results from testing say otherwise, so it may depend on framework version. For me, whether I do that or not, KeyDown does not get called for ESC, and whether I do that or not, KeyPress DOES get called for ESC. This is while a TextBox has focus, so it may also depend on the control.