.NET Interpret Enter key as Tab on textbox - c#

This simple problem reoccurs many times for me in .NET with WinForms. I have a textbox and would like to treat the Enter key as the same as the Tab key, as in whenever I press enter, I want lostfocus to be raised, the next control to be Focused, etc. I have noticed many similar questions to this, and I can solve the problem by capturing the KeyDown and when Enter is detected to move the focus, but what I am looking for is a best practice and if not for insight on where the Textbox control detects the Tab key internally and how it does it's thing so I can just add an "|| key == Keys.Enter". This would stop Keydown from being raised and instead move focus to the next control and raise other appropriate messages.
I checked this similar question before
.NET TextBox - Handling the Enter Key but it isn't what I really want to accomplish. What i really want to do is to as early as possible interpret ENTER as TAB in the Textbox control or intercept and change the Enter to a Tab and let the Textbox do it's thing.
Edit: Here's something along the lines of what I'm looking for, but I'm not sure the "safety" of modifying the Windows message like this...
class FancyTextBox : TextBox
{
public bool TreatEnterAsTab { get; set; }
const int WM_KEYDOWN = 0x100;
const int KEY_TAB= 9;
const int KEY_ENTER = 13;
public override bool PreProcessMessage(ref Message msg)
{
if (TreatEnterAsTab && msg.Msg == WM_KEYDOWN && msg.WParam.ToInt32() == KEY_ENTER)
msg.WParam = new IntPtr(KEY_TAB);
return base.PreProcessMessage(ref msg);
}
}

This is fine. Just a few details, you don't want to do it if the text box is multiline or when the Shift, Alt or Ctrl key is down. Turn it on by default, that's why you're using it:
using System;
using System.ComponentModel;
using System.Windows.Forms;
class FancyTextBox : TextBox {
public FancyTextBox() {
TreatEnterAsTab = true;
}
[DefaultValue(true)]
public bool TreatEnterAsTab { get; set; }
public override bool PreProcessMessage(ref Message msg) {
if (TreatEnterAsTab && (!this.Multiline || this.AcceptsReturn) &&
Control.ModifierKeys == Keys.None &&
msg.Msg == WM_KEYDOWN && (Keys)msg.WParam.ToInt32() == Keys.Enter) {
msg.WParam = (IntPtr)Keys.Tab;
}
return base.PreProcessMessage(ref msg);
}
private const int WM_KEYDOWN = 0x100;
}

This may be not what you are looking for, but what I have done in the past is to check for enter in the KeyPress event and use Control.SelectNextControl to use the existing tab sequencing

Related

How to paste a serial key automatically [duplicate]

I have a .net application which includes search screen which has a panel with has three text boxes, each with a varying character lengths.
What I'd like to do is capture when the paste command when invoked from the first box and paste my clipboard into the three boxes.
This functionality is similar to many modern applications accepting input for serial keys and phone numbers.
As far as I can find there is no other sensible way of doing this than to capture the WM_PASTE event.
Derive a class from TexBox and implement this method:
using System.Windows.Forms;
using System.ComponentModel;
class TextBoxWithOnPaste : TextBox
{
public delegate void PastedEventHandler();
[Category("Action")]
[Description("Fires when text from the clipboard is pasted.")]
public event PastedEventHandler OnPaste;
protected override void WndProc(ref Message m)
{
if (m.Msg == 0x302 && OnPaste != null) // process WM_PASTE only if the event has been subscribed to
{
OnPaste();
}
else
{
base.WndProc(ref m);
}
}
}
Then put three of those custom controls on your form, and assign the OnPaste event on all three textboxes to the same method, in this case I called it textPasted():
private void textPasted()
{
String input = Clipboard.GetText();
int l1 = textBoxWithOnPaste1.MaxLength;
int l2 = textBoxWithOnPaste2.MaxLength;
int l3 = textBoxWithOnPaste3.MaxLength;
try
{
textBoxWithOnPaste1.Text = input.Substring(0, l1);
textBoxWithOnPaste2.Text = input.Substring(l1, l2);
textBoxWithOnPaste3.Text = input.Substring(l2, l3);
}
catch (Exception)
{ }
}
Since you implied "like a serial", I guessed you want the pasted string to be split among the textboxes. The code above is not perfect for that (try pasting a single space into the third text box after entering data manually in all three, so it would be nice if you knew in which textbox the text was pasted, for example by altering the event's parameters and that way sending the sender with it), but it basically works and I guess you can figure out the rest (you could use the Tag property to identify the textbox).
Capture the paste event:
protected override void WndProc(ref Message m) {
// Did paste occur?
if (m.Msg == 0x302) {
//Paste occurred, add your logic here
}
base.WndProc(ref m);
}
Then, access the Clipboard object to get the desired text.
you can get the captured text
String txt = Clipboard.GetText();
and place it in the "Text" property of the other textbox
You can bind key down event, and when you get Ctrl + V or Ctrl + v, you update the value of the three textbox with value in the clipboad. You can do this on TextChanged event off first text box.
You could increase the character limit of the boxes and register for TextChanged and if the pasted (or typed) text is longer jump/cut to the next TextBox.

How to check whether the program is being used?

I need to close the application (C#) when user doesn't use it - let's say that when there is no Click event on any form of the program (there are about 100 forms). Is there any way to do that without handling Click even on each form of the app. (I have the thread running each minute, where it could be checked)?
Thanks in advance!
You can hook into the application message loop using the Application.AddMessageFilter function. Write a message filter that inspects all mouse click messages and/or keyboard messages, or anything you're interested in.
For instance:
public class DetectActivityMessageFilter : IMessageFilter
{
private const int WM_LBUTTONDOWN = 0x0201;
public bool PreFilterMessage(ref Message m)
{
if (m.Msg == WM_LBUTTONDOWN)
{
// The left mouse button was pressed
}
return false;
}
}

Windows Forms Textbox is uneditable by accident

I have an application which asks the user a few simple questions. The user is supposed to input the answer by typing it into a TextBox. When I render the Windows Form though, the TextBox is greyed out, blends in with the background, and is uneditable.
Here's my code:
public string waitForText(Point Locution)
{
TextBox WriteAnswerHere = new TextBox();
WriteAnswerHere.Location = Locution;
WriteAnswerHere.ReadOnly = false;
WriteAnswerHere.Focus();
this.Controls.Add(WriteAnswerHere);
int waiting = 1;
while (waiting == 1)
{
if (Control.ModifierKeys == Keys.Enter)
{
waiting = 0;
}
}
string HowYouAre = WriteAnswerHere.Text;
this.Controls.Remove(WriteAnswerHere);
return HowYouAre;
}
The input is supposed to be given to the application when the Enter key is pressed, hence the (Control.ModifierKeys == Keys.Enter); Any suggestions on what I am doing wrong?
You shouldn't use a while loop to detect specific key events. Your while loop is holding up the form. I suggest you check out these articles on Events and Event handlers for Windows forms.
http://msdn.microsoft.com/en-us/library/dacysss4.aspx

how to hide on EditText soft keyboard windows 8 Metro Application?

I'm having an EditText and a Button in my Frame using C#. After writing inside the edit field and clicking on the Button, I want to hide the virtual soft keyboard.
Add a dummy button and set focus to it and the keyboard will be hidden.
Thanks for your question.
i have get a better solution for this problem. like this
first we can add handler in xaml
<Grid x:Name= Tapped="Grid_Tapped_1">
......
</Grid >
then we focus current page like follow. it works well.
private void Grid_Tapped_1(object sender, TappedRoutedEventArgs e)
{
this.Focus(FocusState.Programmatic);
}
You cannot. There is more information on the behavior of the Input Hosting Manager and Soft Keyboard and you can register to know when it shows or becomes hidden. But, you cannot programmatically control whether it's up or down.
When the textbox that showed the virtual keyboard has it’s propery IsEnabled set to false, the virtual keyboard disappears. We can immediately set is to true after that and the virtual keyboard will remain hidden. Just like this:
MyTextBox.KeyDown += (s, a) => {
if (a.Key == VirtualKey.Enter) {
MyTextBox.IsEnabled = false;
MyTextBox.IsEnabled = true;
}
};
Try to set the IsReadOnly property of the Textbox`.
I'm doing something "similar"
private void textbox_input_LostFocus(object sender, RoutedEventArgs e)
{
textbox_input.IsReadOnly = false;
}
private void textbox_input_Tapped(object sender, TappedRoutedEventArgs e)
{
if(e.PointerDeviceType != Windows.Devices.Input.PointerDeviceType.Mouse)
textbox_input.IsReadOnly = true;
else
textbox_input.IsReadOnly = false;
}
With this snipped I suppress the keyboard if the user isn't using the mouse...
Also the KeyDown event is fired while the textbox is readonly so you could use the data directly to set your viewmodel and update over it your textbox ;)
There is a solution which can hide the touch-keyboard by setting the container's IsTabStop=true automaticly after clicking your Button as "submit".
But, btw, I've noticed that the next time entering that page, the EditText (supposed to be a TextBox) will be auto-focused, and have the touch-keyboard showed. Maybe you'd better Disable the EditText after submitting. (seems to finish and block the input operation)
I had the same problem, only with a little difference.
When I switched from a textbox to a datepicker the softkeyboard won't disappear.
I tried all of your suggestions, but nothing worked like it should. Every time my datepicker had a strange behaviour, after I tried one of the above solutions (Or some of other stackoverflow threads).
After some time I found something via Google, which worked like a charm. HERE
In the comment section Dusher16 wrote a very clean solution, which works also for WinRT / Win8 / Win8.1 / Metro or how you will call it.
Create a new class:
using System.Runtime.InteropServices;
using Windows.Devices.Input;
namespace Your.Namespace
{
public static class TouchKeyboardHelper
{
#region < Attributes >
private const int WmSyscommand = 0x0112; // Flag to received/send messages to the system.
private const int ScClose = 0xF060; // Param to indicate we want to close a system window.
#endregion < Attributes >
#region < Properties >
public static bool KeyboardAttached
{
get { return IsKeyboardAttached(); }
}
#endregion < Properties >
#region < Methods >
[DllImport("user32.dll")]
private static extern int FindWindow(string lpClassName, string lpWindowName); // To obtain an active system window handler.
[DllImport("user32.dll")]
private static extern int SendMessage(int hWnd, uint Msg, int wParam, int lParam); // To send a message to the system.
/// <summary>
/// To detect if a real keyboard is attached to the dispositive.
/// </summary>
/// <returns></returns>
private static bool IsKeyboardAttached()
{
KeyboardCapabilities keyboardCapabilities = new KeyboardCapabilities(); // To obtain the properties for the real keyboard attached.
return keyboardCapabilities.KeyboardPresent != 0 ? true : false;
}
/// <summary>
/// To close the soft keyboard
/// </summary>
public static void CloseOnscreenKeyboard()
{
// Retrieve the handler of the window
int iHandle = FindWindow("IPTIP_Main_Window", ""); // To find the soft keyboard window.
if (iHandle > 0)
{
SendMessage(iHandle, WmSyscommand, ScClose, 0); // Send a close message to the soft keyboard window.
}
}
#endregion < Methods >
}
}
And in for example some XAML.cs file you add the following lines:
private void DatePicker_GotFocus(object sender, RoutedEventArgs e)
{
if (TouchKeyboardHelper.KeyboardAttached)
TouchKeyboardHelper.CloseOnscreenKeyboard();
}

Preventing Focus-able Controls from stealing Keyboard Input

I'm currently working on a simple game that is drawn on a form by overriding the OnPaint method. The game requires Keyboard input and was working perfectly until I decided to enhance the GUI and add a few Buttons to the form.
The moment I added these Buttons, the form stopped receiving any Keyboard input, no matter how hard I tried the focus was always on the buttons. This behavior can be replicated by placing any Focus-able Control on the form. (ie. TextBox)
I don't need ANY Kayboard interaction with these buttons, I want the user to interact with them with the mouse only.
I've tried the following techniques to try and get around this problem - none of these worked:
1) Normal KeyDown and KeyUp events of the form. (This is the way
I was capturing Keyboard input before placing the buttons.)
2) Overriding the Form's OnKeyDown and OnKeyUp events.
3) Overriding ProcessCmdKey - Works, but cannot differentiate
between KeyUp and KeyDown events, so it is inadequate for me.
I also tried create a MessageFilter for the application, but I couldn't force it to capture only the Keyboard keys that I needed.
I've been looking into this for many hours already and can't find a suitable solution.
Help would be greatly appreciated.
Here is a sample form with a IMessageFilter for the up and down arrow keys, hope this helps:
public partial class MainForm : Form
{
private class MessageFilter : IMessageFilter
{
public MainForm Main { get; set; }
public bool PreFilterMessage(ref Message msg)
{
const int WM_KEYDOWN = 0x100;
const int WM_KEYUP = 0x101;
if (msg.Msg == WM_KEYDOWN)
{
var keyData = (Keys)msg.WParam;
if (keyData == Keys.Down || keyData == Keys.Up)
{
return true; // Process keys before return
}
}
else if (msg.Msg == WM_KEYUP)
{
var keyData = (Keys)msg.WParam;
if (keyData == Keys.Down || keyData == Keys.Up)
{
return true; // Process keys before return
}
}
return false;
}
}
public MainForm()
{
this.InitializeComponent();
Application.AddMessageFilter(new MessageFilter { Main = this });
}
}
For a list of possible Windows messages check:
List Of Windows Messages
Set the KeyPreview property of the form to True, and then set event.Handled = True when you handle KeyDown/KeyUp. This will ensure that the form gets a chance to handle events before its children. Because you set the handled property to true, the childen won't see the keyboard events.
More info here: http://msdn.microsoft.com/en-us/library/system.windows.forms.form.keypreview.aspx

Categories