How to disable certain combination keys (eg. Shift + "certain number key") - c#

I'm created a telephone keypad which consists of 0-9 plus hash key (#) and star key (*). I was able to disable other keys except those number keys so that when user type in the textbox provided, it will only allow number keys. Since # is the combination of Shift+3 and * is the combination of Shift+8, my problem is I can't disable other combination key except those two. So, is there any way to handle this problem in order to just allow Shift+3 and Shift+8 only?
private void NumDisplayBox_PreviewKeyDown(object sender, KeyEventArgs e)
{
//Determine whether the keystroke is a number from the top of the keyboard
if (e.Key < Key.D0 || e.Key > Key.D9)
//Determine whether the keystroke is a number from the keypad
if (e.Key < Key.NumPad0 || e.Key > Key.NumPad9)
e.Handled = true;
if (e.Key == Key.Space) //Disable the space key
e.Handled = true;
//Enable the following keys
if (e.Key == Key.Back || e.Key == Key.Delete || e.Key == Key.Left || e.Key == Key.Right)
e.Handled = false;
//Determine whether the keystroke is # or *
if ((Keyboard.Modifiers == ModifierKeys.Control) && (e.Key == Key.D3))
e.Handled = false;
}

Related

Get long combination key (password) entered in WPF Window

I'm having a bit of confusion regarding my post here. How to get combination key about 5-10 keys? I'm intended to capture "!qaz$esz" key without double quotes.
My application is a full screen application that prevent access to desktop before entering a right key to enable desktop access. I have kill explorer.exe and disable the Task Manager when the program start and enable it back after combination password is correct:-
private void Window_Loaded(object sender, RoutedEventArgs e)
{
/**
* 1. KILL EXPLORER
* 2. DISABLE KEY TO TERMINATE
* = Alt + F4
* = Win + Tab
* = Win + D
* = etc
* 3. ACCEPT SPECIFIC KEY ONLY TO UNLOCK TO MINIMIZE AND SET TOP = FALSE
*
*
* **/
RegistryKey regkey = SetKey(TaskManager.Disabled);
regkey.Close();
}
public static RegistryKey SetKey(TaskManager command)
{
RegistryKey mKey;
string subKey = "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System";
mKey = Registry.CurrentUser.CreateSubKey(subKey);
switch (command)
{
case TaskManager.Enabled:
mKey.SetValue("DisableTaskMgr", 0);
break;
case TaskManager.Disabled:
mKey.SetValue("DisableTaskMgr", 1);
break;
}
return mKey;
}
But something must be lack on my code where I cannot detect the combination code that more to password.
Below code are what I'm testing to see if my entered key is captured.
public MainWindow()
{
InitializeComponent();
AddHandler(Keyboard.KeyDownEvent, (KeyEventHandler)HandleKeyDownEvent);
}
private void HandleKeyDownEvent(object sender, KeyEventArgs e)
{
if (e.Key == Key.Tab && (Keyboard.Modifiers & (ModifierKeys.Control | ModifierKeys.Shift)) == (ModifierKeys.Control | ModifierKeys.Shift))
{
MessageBox.Show("CTRL + SHIFT + TAB trapped"); // Working
}
if (e.Key == Key.Tab && (Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control)
{
MessageBox.Show("CTRL + TAB trapped"); // Working
}
if (e.Key == Key.F4 && Keyboard.Modifiers.HasFlag(ModifierKeys.Alt))
{
MessageBox.Show("ALT + F4 trapped"); // Not working
}
if (e.Key == Key.D && Keyboard.Modifiers.HasFlag(ModifierKeys.Windows))
{
MessageBox.Show("WIN + D trapped"); // Not working
}
if ((Keyboard.IsKeyDown(Key.LeftShift) && e.Key == Key.D1) && e.Key ==Key.Q && e.Key == Key.A && e.Key == Key.Z && e.Key == Key.D4 && e.Key == Key.E && e.Key == Key.S && e.Key == Key.Z)
{
MessageBox.Show("COMBOKEY"); // Not working
// RUN EXPLORER
// ENABLE TASK MANAGER
}
}
What is not settle is WINLOGO + D, ALT + TAB, ALT + F4 and LONG COMBINATION KEY.
I have try some of the code from here:-
https://stackoverflow.com/a/5750757/3436326
https://stackoverflow.com/a/17088823/3436326
I have see some discussion/posting/article on writing to LowLevelAPI. I'm not familiar accessing low level API and apply it on WPF application:-
http://www.tamas.io/c-disable-ctrl-alt-del-alt-tab-alt-f4-start-menu-and-so-on/
https://www.codeproject.com/articles/14485/low-level-windows-api-hooks-from-c-to-stop-unwante
e.Key == Key.Q && e.Key == Key.A
If e.Key is equal to Key.Q, it cannot be equal to Key.A at the same time. That’s why it’s not working. What you want to detect is the sequence of those keys, and since you only have a key listener, you have to take care of managing the state yourself:
private int passwordState = 0;
private void HandleKeyDownEvent(object sender, KeyEventArgs e)
{
// other checks
else if (Keyboard.IsKeyDown(Key.LeftShift) && e.Key == Key.D1)
passwordState = 1; // first key of the password
else if (passwordState == 1 && e.Key == Key.Q)
passwordState = 2;
else if (passwordState == 2 && e.Key == Key.A)
passwordState = 3;
else if (passwordState == 3 && e.Key == Key.Z)
passwordState = 4;
else if (passwordState == 4 && e.Key == Key.D4)
passwordState = 5;
else if (passwordState == 5 && e.Key == Key.E)
passwordState = 6;
else if (passwordState == 6 && e.Key == Key.S)
passwordState = 7;
else if (passwordState == 7 && e.Key == Key.Z)
{
passwordState = 0;
// correct password
MessageBox.Show("COMBOKEY");
}
else
passwordState = 0; // some other/unexpected key: reset password state
}
But that is really annoying to maintain, so why don’t you have a special key combination instead that simply shows a modal prompt for the user to enter the password? Yes, you would show the user a clear password prompt then that they could accidentally discover, but what’s the problem with that?

How to accept just certain characters into a textbox?

How do I limit textbox from accepting letter A,B,C,D only? I've tried this code, but it still accepts letters aside from letters A,B,C,D.
e.Handled = !char.IsDigit(e.KeyChar) && !char.IsControl(e.KeyChar);
I agree with the comment that if all you want is a single character that actually using a combo box may be more appropriate, but if you're planning on allowing the user to enter a series of the limited characters then it may be worth having a look at an article that I wrote a few years ago about how to restrict the characters that are allowed in the text box, which is available at "Restrict characters entered into textbox".
Further to DanDan78's comment below the important code is;
Private Sub TextBox1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TextBox1.KeyPress
Dim allowedChars As String = "0123456789"
If allowedChars.IndexOf(e.KeyChar) = -1 Then
' Invalid Character
e.Handled = True
End If
End Sub
On the KeyPress event of your TextBox, you can just use this simple code to achieve your aim:
if (e.KeyChar < 'A' || e.KeyChar > 'D')
e.Handled = true;
If you wish to accept lower and upper case A-D:
if ((e.KeyChar < 'A' || e.KeyChar > 'D') && (e.KeyChar <'a' || e.KeyChar > 'd'))
e.Handled = true;
If you also wish to allow 'special' characters like backspace, delete, etc., you need to also allow characters below ASCII code 32:
if ((e.KeyChar < 'A' || e.KeyChar > 'D') && (e.KeyChar <'a' || e.KeyChar > 'd') && e.KeyChar > 32)
e.Handled = true;
Following a further user comment, in order to allow A-D, a-d and backspace only, the following should suffice:
if ((e.KeyChar < 'A' || e.KeyChar > 'D') && (e.KeyChar <'a' || e.KeyChar > 'd') && e.KeyChar != 8)
e.Handled = true;
Attach a KeyPressEventHandler to the text box:
textBox.KeyPress += new KeyPressEventHandler(keyPressed);
Then create an event to handle these letters:
private void keyPressed(Object sender, KeyPressEventArgs e)
{
if (e.KeyChar == 'A' || e.KeyChar == 'B' || e.KeyChar == 'C' || e.KeyChar == 'D')
{
e.Handled = true;
}
}
This will stop the text box accepting these letters

WPF Key is digit or number

I have previewKeyDown method in my window, and I'd like to know that pressed key is only A-Z letter or 1-0 number (without anyF1..12, enter, ctrl, alt etc - just letter or number).
I've tried Char.IsLetter, but i need to give the char, so e.key.ToString()[0] doesn't work, because it is almost everytime a letter.
Something like this will do:
if ((e.Key >= Key.A && e.Key <= Key.Z) || (e.Key >= Key.D0 && e.Key <= Key.D9) || (e.Key >= Key.NumPad0 && e.Key <= Key.NumPad9))
Of course you will also have to check that no modifier keys like CTRL are pressed according to your requirements.
e.Key is giving you a member of the enum System.Windows.Input.Key
You should be able to do the following to determine whether it is a letter or a number:
var isNumber = e.Key >= Key.D0 && e.Key <= Key.D9;
var isLetter = e.Key >= Key.A && e.Key <= Key.Z;
In your specific case the answer provided by Jon and Jeffery is probably best, however if you need to test your string for some other letter/number logic then you can use the KeyConverter class to convert a System.Windows.Input.Key to a string
var strKey = new KeyConverter().ConvertToString(e.Key);
You'll still need to check to see if any modifier keys are being held down (Shift, Ctrl, and Alt), and it should also be noted that this only works for Letters and Numbers. Special characters (such as commas, quotes, etc) will get displayed the same as e.Key.ToString()
try this, it works.
private void txbNumber_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key >= Key.D0 && e.Key <= Key.D9) ; // it`s number
else if (e.Key >= Key.NumPad0 && e.Key <= Key.NumPad9) ; // it`s number
else if (e.Key == Key.Escape || e.Key == Key.Tab || e.Key == Key.CapsLock || e.Key == Key.LeftShift || e.Key == Key.LeftCtrl ||
e.Key == Key.LWin || e.Key == Key.LeftAlt || e.Key == Key.RightAlt || e.Key == Key.RightCtrl || e.Key == Key.RightShift ||
e.Key == Key.Left || e.Key == Key.Up || e.Key == Key.Down || e.Key == Key.Right || e.Key == Key.Return || e.Key == Key.Delete ||
e.Key == Key.System) ; // it`s a system key (add other key here if you want to allow)
else
e.Handled = true; // the key will sappressed
}
Add a reference to Microsoft.VisualBasic and use the VB IsNumeric function, combined with char.IsLetter().
bit of a cludge but it works :)
private void TextBox_KeyDown(object sender, KeyEventArgs e)
{
Regex R = new Regex("^([A-Z]|[0-9]){1}$");
var strKey = new KeyConverter().ConvertToString(e.Key);
if(strKey.Length > 1 )
{
strKey = strKey.Replace("NumPad", "").Replace("D", "");
}
if (strKey.Length == 1)
{
if (!R.IsMatch(strKey))
{
e.Handled = true;
}
}
else
{
e.Handled = true;
}
}
Can you put some code to show what you intend? Shouldn't this work for you
if(e.key.ToString().Length==1)
`Char.IsLetter(e.key.ToString()[0])`
else
//

Setting an attribute to only allow doubles in a textbox

I remember using some attribute on the getter/setter that would limit the input to a certain datatype, length etc. IE [Attribute something something].
Any ideas?
Thanks
Did you mean the ValidateInput attribute available in System.Web.Mvc?
Also, you could probably use a MaskedTextBox if you're doing WinForms.
One way to do it (if you want to keep using a standard text box) would be to make an event for the text changed event of the text box, and in that, read the text to make sure that it contains only numbers (and an optional period in the case of a double)
Winforms? Have you considered using masked Textbox control?
http://msdn.microsoft.com/en-us/library/system.windows.forms.maskedtextbox.aspx
Winforms? Why not use a NumericUpDown?
http://msdn.microsoft.com/en-us/library/57dy4d56.aspx
http://msdn.microsoft.com/en-us/library/system.windows.forms.numericupdown.aspx
If you need scientific notation you can do :
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
TextBox tBox = (TextBox)sender;
if (!((e.KeyCode >= Keys.D0 && e.KeyCode <= Keys.D9)
|| (e.KeyCode >= Keys.NumPad0 && e.KeyCode <= Keys.NumPad9)
|| (e.KeyCode == Keys.Decimal && !(tBox.Text.Contains('.'))
&& !(tBox.Text.Length == 0)
&& !((tBox.Text.Length == 1)
&& (tBox.Text.Contains('-') || tBox.Text.Contains('+'))))
|| (e.KeyCode == Keys.OemPeriod && !(tBox.Text.Contains('.'))
&& !(tBox.Text.Length == 0)
&& !((tBox.Text.Length == 1)
&& (tBox.Text.Contains('-') || tBox.Text.Contains('+'))))
|| (e.KeyCode == Keys.Subtract && ((tBox.Text.Length == 0) ||
tBox.Text.EndsWith("e") || tBox.Text.EndsWith("E")))
|| (e.KeyCode == Keys.OemMinus && ((tBox.Text.Length == 0) ||
tBox.Text.EndsWith("e") || tBox.Text.EndsWith("E")))
|| (e.KeyCode == Keys.Add && ((tBox.Text.Length == 0) ||
tBox.Text.EndsWith("e") || tBox.Text.EndsWith("E")))
|| (e.KeyCode == Keys.Oemplus && ((tBox.Text.Length == 0) ||
tBox.Text.EndsWith("e") || tBox.Text.EndsWith("E")))
|| e.KeyCode == Keys.Delete
|| e.KeyCode == Keys.Back
|| e.KeyCode == Keys.Left
|| e.KeyCode == Keys.Right
|| (e.KeyCode == Keys.E) && !(tBox.Text.Contains('e')) &&
(tBox.Text.Contains('.') && !tBox.Text.EndsWith("."))))
{
e.SuppressKeyPress = true;
}
}
This will deny input of any pattern which is not consistent with a numeric value. Minus signs are only allowed at the beginning of the string (to indicate a negative number) and after an e or E to indicate a negative exponent. Plus signs follow the same rule as minus. Only one decimal point is allowed and it must follow at least one number. Only one e or E is allowed and it must follow a decimal point and at least one number after the decimal point.
You could also allow things like the Help, Tab, etc, keys if it would interfere with other aspects of your program function.
Note that this does not prevent incomplete numbers (ie: 1.37E- or -13. from being entered so you would probably want to check the string in any case. This at least denies any immediately invalid entries.
You might do something like (in the same handler, before the other logic):
if (e.KeyCode == Keys.Enter)
{
textBox1_Validating(sender, new CancelEventArgs());
return;
}
The above only gives the enter key the normal 'feel' for input (force validation). Leaving the textbox (going out of focus) will also trigger validation where you might do something like :
private void textBox1_Validating(object sender, CancelEventArgs e)
{
TextBox tBox = (TextBox)sender;
double tstDbl;
if (!double.TryParse(tBox.Text, out tstDbl))
{
//handle bad input
}
else
{
//double value OK
doSomething(tstDbl);
}
}

detect Ctrl + Enter

(using WPF)
i try to detect when Ctrl + Enter gets hit.
so i tried this code:
if (e.Key == Key.Return && (e.Key == Key.LeftCtrl || e.Key == Key.RightCtrl))
{
//Do Something
}
Obviously this is not correct, as it does not work.
Could anyone help me out, explaining what the right way should be ?
thanx
Obviously e.Key can't be equal to more than one different value in the same event.
You need to handle one of the events that uses KeyEventArgs, there you'll find properties such as Control and Modifiers that will help you detect combinations.
The KeyPress event, which uses KeyPressEventArgs, just doesn't have sufficient information.
Drat, you said WPF didn't you. It looks like you need e.KeyboardDevice.Modifiers.
I think you need a SpecialKey Handler.
I googled a bit a found a solution here.
Following code from the referred link may solve your problem:
void SpecialKeyHandler(object sender, KeyEventArgs e)
{
// Ctrl + N
if ((Keyboard.Modifiers == ModifierKeys.Control) && (e.Key == Key.N))
{
MessageBox.Show("New");
}
// Ctrl + O
if ((Keyboard.Modifiers == ModifierKeys.Control) && (e.Key == Key.O))
{
MessageBox.Show("Open");
}
// Ctrl + S
if ((Keyboard.Modifiers == ModifierKeys.Control) && (e.Key == Key.S))
{
MessageBox.Show("Save");
}
// Ctrl + Alt + I
if ((Keyboard.Modifiers == (ModifierKeys.Alt | ModifierKeys.Control)) && (e.Key == Key.I))
{
MessageBox.Show("Ctrl + Alt + I");
}
}
if (e.Modifiers == Keys.Control && e.KeyCode == Keys.Enter)
if (e.KeyChar == 10)
{
///Code
}
Or
if ((Char)e.KeyChar == '\n')
{
///Code
}

Categories

Resources