It's possible to replaces chars when Shift key is pressed? - c#

Hello Stack Overflow community!
This is my function that catches every pressed key:
public static string GetBuffKeys()
{
string buffer = "";
foreach (System.Int32 i in Enum.GetValues(typeof(Keys)))
{
if (GetAsyncKeyState(i) == -32767)
buffer += Enum.GetName(typeof(Keys), i);
}
return buffer;
}
To have a little formating, I using this function that replaces me characters with new one:
public static class KeyControl
{
[DllImport("User32.dll")]
private static extern short GetAsyncKeyState(int vKey);
public static string ReplaceChars(string text)
{
text = text.Replace("Space", " ");
text = text.Replace("Delete", "<Del>");
text = text.Replace("LShiftKey", "");
text = text.Replace("ShiftKey", "");
text = text.Replace("OemQuotes", "!");
text = text.Replace("Oemcomma", "?");
text = text.Replace("D8", "á");
text = text.Replace("D2", "ě");
text = text.Replace("D3", "š");
text = text.Replace("D4", "č");
text = text.Replace("D5", "ř");
text = text.Replace("D6", "ž");
text = text.Replace("D7", "ý");
text = text.Replace("D9", "í");
text = text.Replace("D0", "é");
text = text.Replace("D1", "+");
text = text.Replace("Back", "<==");
text = text.Replace("LButton", "");
text = text.Replace("RButton", "");
text = text.Replace("NumPad", "");
text = text.Replace("OemPeriod", ".");
text = text.Replace("OemSemicolon", ",");
text = text.Replace("Oem4", "/");
text = text.Replace("LControlKey", "");
text = text.Replace("ControlKey", "");
text = text.Replace("Enter", "<ENT>");
text = text.Replace("Shift", "");
text = text.Replace("CapsLock", "");
text = text.Replace("Oem6", "(");
return text;
}
But I want replace D* (D1, for example) with number, if Shift key is pressed. It is possible? And if not, what is better method for key logging than buffer all pressed keys? Thanks a lot!

You can use Control.ModifierKeys (WinForms) or Keyboard.Modifiers (WPF) to see what modifier keys are currently pressed. For instance:
var modifiers = Control.ModifierKeys;
if (modifiers != Keys.None)
{
text = text = "[" + modifiers.ToString() + "]";
}
Note that Keyboard.Modifiers are a bitmask field. Thus the following code clears a specific modifier when they current keypress event corresponds to that modifier:
public static string GetBuffKeys()
{
var allModifierKeys = new Dictionary<Keys, Keys> { { Keys.ControlKey, Keys.Control }, {Keys.ShiftKey, Keys.Shift}, {Keys.Menu, Keys.Alt }};
var modifiers = Control.ModifierKeys;
string buffer = "";
foreach (var key in Enum.GetValues(typeof(Keys)).OfType<Keys>().Distinct()) // The enum seems to have duplicated values for Enter and Return. Uniquify them.
{
if (GetAsyncKeyState((int)key) == -32767)
{
buffer += ReplaceChars(Enum.GetName(typeof(Keys), key));
if (allModifierKeys.Keys.Contains(key))
modifiers &= ~(allModifierKeys[key]); // Remove this modifier to prevent double printing.
}
}
if (modifiers != Keys.None)
{
buffer = buffer + " [" + modifiers.ToString() + "]";
}
return buffer;
}

Related

read multiple values from file and place in the right place

I have this code, which does this
click on label object
run the MouseTracker method to get the mouse position
another method (WriteToConfig) is runned
here I check if there is any result then do some work with regex to update or write a new line with values
public partial class Settings : Form
{
public int xTemp;
public int yTemp;
const string ConfigFile = "config.ini";
public string? ConfigRead;
public Settings()
{
InitializeComponent();
}
private void MouseTracker(string name)
{
DialogResult result = MessageBox.Show($"Move your cursor to \"{name}\" slot in your tab \n and press ENTER");
if (result == DialogResult.OK)
{
xTemp = MousePosition.X;
yTemp = MousePosition.Y;
}
}
private void WriteToConfig(string labelName, int number)
{
ConfigRead = File.ReadAllText(ConfigFile);
try
{
string PATTERN = #$"{labelName} = (?<value>[0-9]+)";
Match match = Regex.Match(ConfigRead, PATTERN, RegexOptions.IgnoreCase);
if (match.Success)
{
int index = match.Groups["value"].Index;
int length = match.Groups["value"].Length;
ConfigRead = ConfigRead.Remove(index, length);
ConfigRead = ConfigRead.Insert(index, number.ToString());
File.WriteAllText(ConfigFile, ConfigRead);
}
else
{
string result = $"{labelName} = {number} \n";
ConfigRead = ConfigRead.Insert(ConfigRead.Length, result);
File.WriteAllText(ConfigFile, ConfigRead);
}
}
catch
{
MessageBox.Show($"{labelName} error");
}
}
private void ReadFromConfig()
{
ConfigRead = File.ReadAllText(ConfigFile);
string PATTERN = #"(?<labelName>[a-zA-Z]+) = (?<value>[0-9]+)";
Match match = Regex.Match(ConfigRead, PATTERN, RegexOptions.IgnoreCase);
}
private void orbTransLabel_Click(object sender, EventArgs e)
{
MouseTracker(orbTransLabel.Text.Remove(orbTransLabel.Text.Length - 1, 1));
orbTransXPos.Text = xTemp.ToString();
orbTransYPos.Text = yTemp.ToString();
WriteToConfig("orbTransXPos", int.Parse(orbTransXPos.Text));
WriteToConfig("orbTransYPos", int.Parse(orbTransYPos.Text));
}
now after I open the form, I would like the to read the file and update all the values from form
I started a ReadFromConfig method to read all the data and I'm thinking to match those results with every label and get the value from file with regex and put in the form.
I could need some help if anyone is willing to :D
the config.ini looks like this
orbTransXPos = 717
orbTransYPos = 1225
orbAltXPos = 717
orbAltYPos = 1267
orbAugXPos = 675
orbAugYPos = 1256
orbChanceXPos = 1874
orbChanceYPos = 1620
jewellersXPos = 1363
jewellersYPos = 488
orbFusingXPos = 13
orbFusingYPos = 193
chromXPos = 364
chromYPos = 1562
orbAlchXPos = 2359
orbAlchYPos = 628
chaosOrbXPos = 1125
chaosOrbYPos = 1772
regalOrbXPos = 1292
regalOrbYPos = 367
chiselXPos = 1398
chiselYPos = 1793
scouringXPos = 1074
scouringYPos = 339
wisdomXPos = 1315
wisdomYPos = 1683

Sorting lines in winforms richtextbox preserving RTF formatting

Is there any way to sort lines in winforms richtextbox preserving RTF formatting?
var lines = edit.Lines.OrderBy(s => s);
edit.Lines = lines.ToArray();
do the job fine, but, obviously, loosing any RTF formatting.
I have slightly changed the snippet of TaW:
1. Adding "unique" might break the very first line formatting
2. Besides "\par" tag there is also "\pard"
Here is a snippet (thanks again to TaW!):
private void cmdSort_Click(object sender, EventArgs e)
{
const string PARD = "\\pard";
var pard = Guid.NewGuid().ToString();
var pos1 = edit.Rtf.IndexOf(PARD, StringComparison.Ordinal) + PARD.Length;
if (pos1 < 0) return;
var header = edit.Rtf.Substring(0, pos1);
var body = edit.Rtf.Substring(pos1);
body = body.Replace("\\pard", pard);
var lines = body.Split(new[] { "\\par" }, StringSplitOptions.None);
var lastFormat = "";
var sb = new StringBuilder();
var rtfLines = new SortedList<string, string>();
foreach (var line in lines)
{
var ln = line.Replace(pard, "\\pard");
var temp = ln.Replace("\r\n", "").Trim();
if (temp.Length > 0 && temp[0] != '\\')
{
rtfLines.Add(temp.Trim(), lastFormat + " " + ln);
}
else
{
var pos2 = temp.IndexOf(' ');
if (pos2 < 0)
{
rtfLines.Add(temp.Trim(), ln);
}
else
{
rtfLines.Add(temp.Substring(pos2).Trim(), ln);
lastFormat = temp.Substring(0, pos2);
}
}
}
foreach (var key in rtfLines.Keys.Where(key => key != "}"))
{
sb.Append(rtfLines[key] + "\\par");
}
edit.Rtf = header + sb;
}
Here is a code snippet that seems to work if the file has neither images nor tables embedded..
It uses two RTF boxes. In my tests they sorted alright and kept all formatting intact.
private void button4_Click(object sender, EventArgs e)
{
string unique = Guid.NewGuid().ToString() ;
richTextBox1.SelectionStart = 0;
richTextBox1.SelectionLength = 0;
richTextBox1.SelectedText = unique;
int pos1 = richTextBox1.Rtf.IndexOf(unique);
if (pos1 >= 0)
{
string header = richTextBox1.Rtf.Substring(0, pos1);
string header1 = "";
string header2 = "";
int pos0 = header.LastIndexOf('}') + 1;
if (pos0 > 1) { header1 = header.Substring(0, pos0); header2 = header.Substring(pos0); }
// after the header comes a string of formats to start the document
string[] formats = header2.Split('\\');
string firstFormat = "";
string lastFormat = "";
// we extract a few important character formats (bold, italic, underline, font, color)
// to keep with the first line which will be sorted away
// the lastFormat variable holds the last formatting encountered
// so we can add it to all lines without formatting
// (and of course we are really talking about paragraphs)
foreach (string fmt in formats)
if (fmt[0]=='b' || ("cfiu".IndexOf(fmt[0]) >= 0 && fmt.Substring(0,2)!="uc") )
lastFormat += "\\" + fmt; else firstFormat += "\\" + fmt;
// add the rest to the header
header = header1 + firstFormat;
// now we remove our marker from the body and split it into paragraphs
string body = richTextBox1.Rtf.Substring(pos1);
string[] lines = body.Replace(unique, "").Split(new string[] { "\\par" }, StringSplitOptions.None);
StringBuilder sb = new StringBuilder();
// the soteredlist will contain the unformatted text as key and the formatted one as valaue
SortedList<string, string> rtfLines = new SortedList<string, string>();
foreach (string line in lines)
{
// cleanup
string line_ = line.Replace("\r\n", "").Trim();
if (line_[0] != '\\' ) rtfLines.Add(line_, lastFormat + " " + line);
else
{
int pos2 = line_.IndexOf(' ');
if (pos2 < 0) rtfLines.Add(line_, line);
else
{
rtfLines.Add(line_.Substring(pos2).Trim(), line);
lastFormat = line_.Substring(0, pos2);
}
}
}
foreach (string key in rtfLines.Keys) if (key != "}") sb.Append(rtfLines[key] + "\\par");
richTextBox2.Rtf = header + sb.ToString();
}
Of course this is really q&d and not ready for serious production; but it looks like a start.
EDIT 2: I changed the code to fix a bug with the first line's format and added some comments. This should work a lot better, but is still a hack that must be adapted to the real input files..
RichTextBox has a property Rtf that would keep RTF formatting.
[BrowsableAttribute(false)]
public string Rtf { get; set; }

How do i highlight a background text in a text file?

I have a dictionary collection that stores the starting position and the charecter values of a text file.
For example: a sample text file (a.txt) may contain text like "how are you? how do you do?"
I have indexed the above text as follows
Dictionary<long,string> charLocation = new Dictionary<long,string>();
charLocation[0] = "how"
charLocation[1] = "ow"
charLocation[2] = "w"
charLocation[4] = "are"
charLocation[6] = "e"
charLocation[5] = "re"
charLocation[11] = "?"
charLocation[9] = "ou?"
charLocation[10] = "u?"
charLocation[8] = "you?"
charLocation[13] = "how"
charLocation[14] = "ow"
charLocation[15] = "w"
charLocation[17] = "do"
charLocation[18] = "o"
charLocation[21] = "ou"
charLocation[22] = "u"
charLocation[20] = "you"
charLocation[26] = "?"
charLocation[24] = "do?"
charLocation[25] = "o?"
Now, I want to highlight each occurrence of "how" or "do" in the text file.
For this I want to first do a lookup in the dictionary collection and find each occurrence of the string, then open the text file and highlight the text for each occurrence.
How can i do this?
Not tested, but this should works.
public string HighLight (int startPoint, string text, string word)
{
if (startPoint > = 0)
{
int startIndex = text.indexOf (word, startPoint);
if (startIndex >= 0)
{
StringBuilder builder = new StringBuilder ();
builder.Append (text.Substring ( 0, startIndex));
builder.Append ("<strong>");
builder.Append (text.Substring (startIndex + 1, word.Length));
builder.Append ("</strong>");
builder.Append (text.Substring (startIndex + word.Length + 1));
return HighLight ((startIndex + "<strong>".Length + "</strong>".Length + word.Length, builder.ToString (), word);
}
}
//Word not found.
return text;
}
So you could do :
string myText = "how are you? how do you do?";
string hightLightedText = HighLight (0, myText, "how");
And if my code has no errors, that would returns "<strong>how</strong> are you? <strong>how</strong> do you do?";
Then you can repalce <strong> and </strong> with wathever you want to "highlight" your text.

Getting rid of *consecutive* periods in a filename

I was wondering how I'd get rid of periods in a filename if i have a filename like:
Test....1.txt to look like Test 1.txt ? I do NOT want files like : 1.0.1 Test.txt to be touched. Only files with consecutive periods should be replaced with a space. Any ideas?
This is my current code but as you can see, it replaces every period aside from periods in extension names:
public void DoublepCleanUp(List<string> doublepFiles)
{
Regex regExPattern2 = new Regex(#"\s{2,}");
Regex regExPattern4 = new Regex(#"\.+");
Regex regExPattern3 = new Regex(#"\.(?=.*\.)");
string replace = " ";
List<string> doublep = new List<string>();
var filesCount = new Dictionary<string, int>();
try
{
foreach (string invalidFiles in doublepFiles)
{
string fileOnly = System.IO.Path.GetFileName(invalidFiles);
string pathOnly = System.IO.Path.GetDirectoryName(fileOnly);
if (!System.IO.File.Exists(fileOnly))
{
string filewithDoublePName = System.IO.Path.GetFileName(invalidFiles);
string doublepPath = System.IO.Path.GetDirectoryName(invalidFiles);
string name = System.IO.Path.GetFileNameWithoutExtension(invalidFiles);
//string newName = name.Replace(".", " ");
string newName = regExPattern4.Replace(name, replace);
string newName2 = regExPattern2.Replace(newName, replace);
string filesDir = System.IO.Path.GetDirectoryName(invalidFiles);
string fileExt = System.IO.Path.GetExtension(invalidFiles);
string fileWithExt = newName2 + fileExt;
string newPath = System.IO.Path.Combine(filesDir, fileWithExt);
System.IO.File.Move(invalidFiles, newPath);
DataGridViewRow clean = new DataGridViewRow();
clean.CreateCells(dataGridView1);
clean.Cells[0].Value = doublepPath;
clean.Cells[1].Value = filewithDoublePName;
clean.Cells[2].Value = fileWithExt;
dataGridView1.Rows.Add(clean);
}
else
{
if (filesCount.ContainsKey(fileOnly))
{
filesCount[fileOnly]++;
}
else
{
filesCount.Add(fileOnly, 1);
string newFileName = String.Format("{0}{1}{2}",
System.IO.Path.GetFileNameWithoutExtension(fileOnly),
filesCount[fileOnly].ToString(),
System.IO.Path.GetExtension(fileOnly));
string newFilePath = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(fileOnly), newFileName);
System.IO.File.Move(fileOnly, newFilePath);
DataGridViewRow clean = new DataGridViewRow();
clean.CreateCells(dataGridView1);
clean.Cells[0].Value = pathOnly;
clean.Cells[1].Value = fileOnly;
clean.Cells[2].Value = newFileName;
dataGridView1.Rows.Add(clean);
}
}
}
}
catch(Exception e)
{
//throw;
StreamWriter doublepcleanup = new StreamWriter(#"G:\DoublePeriodCleanup_Errors.txt");
doublepcleanup.Write("Double Period Error: " + e + "\r\n");
doublepcleanup.Close();
}
}
string name = "Text...1.txt";
Regex r = new Regex("[.][.]+");
string result = r.Replace(name, " ");
Well, to do that with a string:
string st = "asdf..asdf...asfd...asdf.asf.asdf.s.s";
Regex r = new Regex("\\.\\.+");
st = r.Replace(st, " ");
This will replace any instance of 2 or more '.'s with a space.
I would throw this into a method:
public static string StringReplace(string original,
string regexMatch, string replacement) {
Regex r = new Regex(regexMatch);
return r.Replace(original, replacement);
}
How about this?
string newFileName = String.Join(".", fileName.Split('.').Select(p => !String.IsNullOrEmpty(p) ? p : " ").ToArray())
Why not use something like this?
string newName = name;
while (newName.IndexOf("..") != -1)
newName = newName.Replace("..", " ");
static string CleanUpPeriods(string filename)
{
StringBuilder sb = new StringBuilder();
if (filename.Length > 0) sb.Append(filename[0]);
for (int i = 1; i < filename.Length; i++)
{
char last = filename[i - 1];
char current = filename[i];
if (current != '.' || last != '.') sb.Append(current);
}
return sb.ToString();
}
You could use use regular expressions, something like this
string fileName = new Regex(#"[.][.]+").Replace(oldFileName, "");
Continuing from dark_charlie's solution, isn't
string newName = name;
while (newName.IndexOf("..") != -1)
newName = newName.Replace("..", ".");
enough?
I have tested this code on a number of cases, and it appears to exhibit the requested behavior.
private static string RemoveExcessPeriods(string text)
{
if (string.IsNullOrEmpty(text))
return string.Empty;
// If there are no consecutive periods, then just get out of here.
if (!text.Contains(".."))
return text;
// To keep things simple, let's separate the file name from its extension.
string extension = Path.GetExtension(text);
string fileName = Path.GetFileNameWithoutExtension(text);
StringBuilder result = new StringBuilder(text.Length);
bool lastCharacterWasPeriod = false;
bool thisCharacterIsPeriod = fileName.Length > 0 && fileName[0] == '.';
bool nextCharacterIsPeriod;
for (int index = 0; index < fileName.Length; index++)
{
// Includes both the extension separator and other periods.
nextCharacterIsPeriod = fileName.Length == index + 1 || fileName[index + 1] == '.';
if (!thisCharacterIsPeriod)
result.Append(fileName[index]);
else if (thisCharacterIsPeriod && !lastCharacterWasPeriod && !nextCharacterIsPeriod)
result.Append('.');
else if (thisCharacterIsPeriod && !lastCharacterWasPeriod)
result.Append(' ');
lastCharacterWasPeriod = thisCharacterIsPeriod;
thisCharacterIsPeriod = nextCharacterIsPeriod;
}
return result.ToString() + extension;
}
I just made a change to handle some edge cases. Here are some test results for this version.
"Test....1.txt" => "Test 1.txt"
"1.0.1..Test.txt" => "1.0.1 Test.txt"
"Test......jpg" => "Test .jpg"
"Test.....jpg" => "Test .jpg"
"one.pic.jpg" => "one.pic.jpg"
"one..pic.jpg" => "one pic.jpg"
"one..two..three.pic.jpg" => "one two three.pic.jpg"
"one...two..three.pic.jpg" => "one two three.pic.jpg"
"one..two..three.pic..jpg" => "one two three.pic .jpg"
"one..two..three..pic.jpg" => "one two three pic.jpg"
"one..two..three...pic...jpg" => "one two three pic .jpg"
Combining some other answers...
static string CleanUpPeriods(string filename)
{
string extension = Path.GetExtension(filename);
string name = Path.GetFileNameWithoutExtension(filename);
Regex regex = new Regex(#"\.\.+");
string s = regex.Replace(name, " ").Trim();
if (s.EndsWith(".")) s = s.Substring(0, s.Length - 1);
return s + extension;
}
Sample Output
"Test........jpg" -> "Test.jpg"
"Test....1.jpg" -> "Test 1.jpg"
"Test 1.0.1.jpg" -> "Test 1.0.1.jpg"
"Test..jpg" -> "Test.jpg"
void ReplaceConsecutive(string src, int lenght, string replace)
{
char last;
int count = 0;
StringBuilder ret = new StringBuilder();
StringBuilder add = new StringBuilder();
foreach (char now in src)
{
if (now == last)
{
add.Append(now);
if (count > lenght)
{
ret.Append(replace);
add = new StringBuilder();
}
count++;
}
else
{
ret.Append(add);
add = new StringBuilder();
count = 0;
ret.Append(now);
}
}
return ret.ToString();
}
Untested, but this should work.
src is the string you want to check for consecutives, lenght is the number of equal chars followed by each other until they get replaced with replace.
This is AFAIK also possible in Regex, but I'm not that good with Regex's that I could do this.

asp.net flip string (swap words) between character

My scenario is i have a multiline textbox with multiple values e.g. below:
firstvalue = secondvalue
anothervalue = thisvalue
i am looking for a quick and easy scenario to flip the value e.g. below:
secondvalue = firstvalue
thisvalue = anothervalue
Can you help ?
Thanks
protected void btnSubmit_Click(object sender, EventArgs e)
{
string[] content = txtContent.Text.Split('\n');
string ret = "";
foreach (string s in content)
{
string[] parts = s.Split('=');
if (parts.Count() == 2)
{
ret = ret + string.Format("{0} = {1}\n", parts[1].Trim(), parts[0].Trim());
}
}
lblContentTransformed.Text = "<pre>" + ret + "</pre>";
}
I am guessing that your multiline text box will always have text which is in the format you mentioned - "firstvalue = secondvalue" and "anothervalue = thisvalue". And considering that the text itself doesn't contain any "=". After that it is just string manipulation.
string multiline_text = textBox1.Text;
string[] split = multiline_text.Split(new char[] { '\n' });
foreach (string a in split)
{
int equal = a.IndexOf("=");
//result1 will now hold the first value of your string
string result1 = a.Substring(0, equal);
int result2_start = equal + 1;
int result2_end = a.Length - equal -1 ;
//result1 will now hold the second value of your string
string result2 = a.Substring(result2_start, result2_end);
//Concatenate both to get the reversed string
string result = result2 + " = " + result1;
}
You could also use Regex groups for this. Add two multi line textboxes to the page and a button. For the button's onclick event add:
using System.Text.RegularExpressions;
...
protected void Button1_Click(object sender, EventArgs e)
{
StringBuilder sb = new StringBuilder();
Regex regexObj = new Regex(#"(?<left>\w+)(\W+)(?<right>\w+)");
Match matchResults = regexObj.Match(this.TextBox1.Text);
while (matchResults.Success)
{
string left = matchResults.Groups["left"].Value;
string right = matchResults.Groups["right"].Value;
sb.AppendFormat("{0} = {1}{2}", right, left, Environment.NewLine);
matchResults = matchResults.NextMatch();
}
this.TextBox2.Text = sb.ToString();
}
It gives you a nice way to deal with the left and right hand sides that you are looking to swap, as an alternative to working with substrings and string lengths.

Categories