Better way to replace text in globally except using SendKeys.Send - c#

I'm trying to create an IME (Input Method Editor) or something similar to that as helping to type ANSI local language font.
it needs to replace some characters when the user types anywhere in Windows. (Word, Photoshop Coreldraw etc.)
For example when user type "r" character and "E" character, IME need to replace "rE" with "ú". I'm using a low-level key hook to capture keypress and SendKeys.Send to replace characters.
If chkStr = "rE" Then
SendKeys.Send("{BS}") 'backspace for delete "r"
SendKeys.Send("{BS}") 'backspace for delete "E"
SendKeys.Send("ú")
End If
It works. But some applications (i.e Adobe InDesign) have inbuilt key shortcuts such as shift + backspace. when user type "e" with shift key it combine with SendKeys.Send("{BS}"). the result is it calling the key shortcut. I hope experts in here can give me a solution for it.
Thanks in advance

Related

CZ characters from keyboard Unity

I am working on a word game that can take input from the keyboard. Below is the code to detect the key
foreach(KeyCode kcode in Enum.GetValues(typeof(KeyCode)))
{
if (Input.GetKey(kcode))
Debug.Log("KeyCode down: " + kcode);
}
But this code is not taking input CZ language special characters (ě š č ř ž ý á í é ). I already switched my keyboard to the CZECH version.
Your guidance will be appreciated.
Do not use Input.GetKey for keyboard input. It is meant for reading game controls which don't change when you change the input language. To read text, use Input.inputString instead.
Since this looks like this, I assume that you "type" special characters like so "AltGr + 2" to get ě
So to get this key you need to add those two keys
if(Input.GetKey(KeyCode.AltGr) && Input.GetKey(KeyCode.Alpha2))
Debug.Log("KeyCode down: AltGr & 2 equals ě");
You need to "hardcode" for each letter unique configuration to get all special characters
EDIT
To use it like that Link from a comment - as far as Unity is considered, those buttons should be mapped to numeric alpha keys.
So using Input.GetKey(KeyCode.Alpha2) is equal to ě - but you need to write your own handler for that.

SendKeys.SendWait function - send special key to application

I try to figure out how to send the character "^" (not the CTRL command) to a external text window.
This different codes I have tried:
SendKeys.SendWait("^");
SendKeys.SendWait("(^)");
Sendkeys.SendWait("{^}"); //This should be the right code, but it doesn't work either
None of those would type me the character "^" in a text field.
If I send normal text to the window it appears in the window. The "^" cannot be typed somehow.
I had a look in the MSDN and in the Online Help, but couldn't find anything close to that problem.
Any ideas?
To send the character "^" using SendKeys.SendWait(), you need to think about which keys you're actually pressing. On an en-US keyboard it's Shift & 6, which translates to this:
SendKeys.SendWait("+6");
So whichever key combination you use to generate the "^" character, enter those keys into the SendKeys.SendWait() call.

How to output windows Alt keycodes in a C# console app

How can I output Windows Alt key codes to the console in a C# console app using Console.WriteLine()?
I would like to output characters such as those used for creating boxes.
I can do so manually in a command prompt by holding alt and typing in the appropriate number such as Alt+205, Alt+187, etc.
Thanks
I suppose the easiest way would be to include them directly in your string literals within your source code:
Console.WriteLine("═╗");
EDIT: I'm sorry - my answer is incorrect. ASCII.GetChars will not work for extended ASCII characters. Thanks to Douglas for correcting me.
I think Douglas's answer is the most direct, but you could also get the character based on the value directly using something like this:
char[] characters = System.Text.Encoding.ASCII.GetChars(new byte[]
{65});
For whatever ASCII code you wanted.

Convert extended ASCII characters to it's right presentation using Console.ReadKey() method and ConsoleKeyInfo variable

Readed about 30 minutes, and didn't found some specific for this in this site.
Suppose the following, in C#, console application:
ConsoleKeyInfo cki;
cki = Console.ReadKey(true);
Console.WriteLine(cki.KeyChar.ToString()); //Or Console.WriteLine(cki.KeyChar) as well
Console.ReadKey(true);
Now, let's put ¿ in the console entry, and asign it to cki via a Console.ReadKey(true). What will be shown isn't the ¿ symbol, the ¨ symbol is the one that's shown instead. And the same happens with many other characters. Examples: ñ shows ¤, ¡ shows -, ´ shows ï.
Now, let's take the same code snipplet and add some things for a more Console.ReadLine() like behavior:
string data = string.Empty;
ConsoleKeyInfo cki;
for (int i = 0; i < 10; i++)
{
cki = Console.ReadKey(true);
data += cki.KeyChar;
}
Console.WriteLine(data);
Console.ReadKey(true);
The question, how to handle this by the right way, end printing the right characters that should be stored on data, not things like ¨, ¤, -, ï, etc?
Please note that I want a solution that works with ConsoleKeyInfo and Console.ReadKey(), not use other variable types, or read methods.
EDIT:
Because ReadKey() method, that comes from Console namespace, depends on Kernel32.dll and it definetively bad handles the extended ASCII and unicode, it's not an option anymore to just find a valid conversion for what it returns.
The only valid way to handle the bad behavior of ReadKey() is to use the cki.Key property that's written in cki = Console.ReadKey(true) execution and apply a switch to it, then, return the right values on dependence of what key was pressed.
For example, to handle the Ñ key pressing:
string data = string.Empty;
ConsoleKeyInfo cki;
cki = Console.ReadKey(true);
switch (cki.Key)
{
case ConsoleKey.Oem3:
if (cki.Modifiers.ToString().Contains("Shift")) //Could added handlers for Alt and Control, but not putted in here to keep the code small and simple
data += "Ñ";
else
data += "ñ";
break;
}
Console.WriteLine(data);
Console.ReadKey(true);
So, now the question has a wider focus... Which others functions completes it's execution with only one key pressed, and returns what's pressed (a substitute of ReadKey())? I think that there's not such substitutes, but a confirmed answer would be usefull.
The problem is not that the Console doesn't know how to deal with Unicode (it does, and correctly, check out this thread). The problem lies in your understanding of a keypress on your keyboard, the translation into keycodes, the translation of keycodes into characters and how the ReadKey() method works.
First of all: if you want to read consecutive characters, use Console.ReadLine() instead, it does all the math for you, and better.
Let's take a look at the following program:
Console.WriteLine("Press a key to start (Enter to stop).");
var key = Console.ReadKey();
var allKeys = "";
while(key.Key != ConsoleKey.Enter)
{
Console.WriteLine(key.KeyChar);
allKeys += key.KeyChar;
key = Console.ReadKey();
}
It reads a key from the input, than it appends it to string. Nothing to worry, right? Wrong! On a US International keyboard you can do this:
Type ` + a becomes à
Type Alt+123 becomes {
Type Alt+3355 becomes ←
Type ; as if on a Spanish keyboard, becomes ñ
Depending on your keyboard, you will hit a different key for a certain character. Sometimes you will hit a combination of keys. The first combination above is recorded as \0a as a string and keycode 0 (not in the enum) and then ConsoleKey.A. The total resulting string is now "\0á{←ñ".
The Alt+123/3355 is recorded as a keycode 18 (this is the Alt-key). The translation of the numeric keys to a character is done by the OS before it is send to the console.
Typing ; on a US keyboard or ñ on a Spanish keyboard will show you the ConsoleKey.Oem1 (US) and ConsoleKey.Oem3 (Spanish).
While I cannot mimic your behavior, this is probably because I don't have your screen, but it seems very much that the font you have as Console font doesn't support non-Unicode characters. On Windows 7, by default it does, I don't know for other Windows versions. It is also possible that the codepage of your console is set incorrectly.
To summarize
What constitutes a character is dependent on keyboard layout, selected keyboard in international settings, selected language, selected code page in the Console and whether or not combinations of keys are allowed (it gets worse with IME!). To go from KeyChar to normal char is often trivial, but depends on whether your system settings are in sync with each other.
When I run your examples on my system, I do not have the same behavior. But then again, I don't have your system.
Going from a key to a character is tricky business. I suggest you don't rely on your own ability to reinvent what's already in the system. It's good practice to try to see what's going on, but really, move back to ReadLine ;).
EDIT:
I just saw your latest edit. Note that you can have different encodings for input and output (Console.InputEncoding and Console.OutputEncoding). I'd also like to quote the other thread to emphasize that when you switch to Unicode, the codepage doesn't matter anymore. This is the default behavior on recent Windows versions:
If you select a Unicode font, such as Lucida Console or Consolas, then
you will be able to see and type Unicode characters on the console,
regardless of what chcp says:
ReadLine() reconfigures the codepage to use properly the extended ASCII and Unicode characters. ReadKey() leaves it in EN-US default (codepage 850).
Just use a codepage that prints the characters you want, and that's all. Refer to http://en.wikipedia.org/wiki/Code_page for some of them :)
So, for the Ñ key press, the solution is this:
Console.OutputEncoding = Encoding.GetEncoding(1252); //Also 28591 is valid for `Ñ` key, and others too
string data = string.Empty;
ConsoleKeyInfo cki;
cki = Console.ReadKey(true);
data += cki.KeyChar;
Console.WriteLine(data);
Console.ReadKey(true);
Simple :)
And a side note: in some cases it's also necessary to reconfigure the Console.InputEncoding property!
Also, note that if you select another font for the console (Lucida Console/Consolas), this trouble STILLS happen. Lotta thanks to user Abel for this, he appointed to the font changing for solution and made myself discover that this is false.

Keyboard hook in c#

I want to develop a keystroke converter which will convert any keystroke into my local language. For example, if user type "a" then it will be replaced with it's corresponding unicode letter "\u0995"
I used a code similar to: https://stackoverflow.com/global-low-level-keyboard-hook-freezing-in-c-net-3-5 There, i edited as follows:
// MessageBox.Show("Test"); // I do not want this so commented
int vkCode = Marshal.ReadInt32(lParam);
Console.WriteLine((Keys)(vkCode + 2));
SendKeys.Send("mmm"); // mmm will be my desired unicode character
Now, i open any application and type anything i get both the typed letter and "mmm".
For example, if i type: abcd then i get output as: mmmcmmmdmmmemmmf .........[output]
Now my question is,
1) How can i edit this code to send a unicode letter instead of a letter ? ( I mean, if i type "p", then i want other applications should receive unicode character similar to this unicode character: "0996"
2) How to make sure only the unicode character is sent to other application, the typed character must not be appended. I mean, i don't want the unicode character and typed english letter as in the output above[output]
1) How can i edit this code to send a
unicode letter instead of a letter ?
SendKeys.Send() can send Unicode Indic characters too e.g.
SendKeys.Send("খ");
If you want to use Unicode code to send the character, then
SendKeys.Send('\u0996'.ToString());
2) How to make sure only the unicode
character is sent to other
application?
If the code is inside a KeyDown event function, you can suppress the actual key being typed by using following just after SendKeys.Send() statement:
e.Handled == true;
AFAIK, hooking is for monitoring, so not sure if its correct approach for what you are trying to do. But in your code, perhaps you can skip calling next hook "CallNextHookEx" and that may swallow the key typed. Mind you that you should swallow conditionally otherwise you may block keys such as ALT and CTL.
I'm not quite sure, but I think you can interrupt the chain if you don't call CallNextHookEx but return a null pointer instead. But that this is something you should rather not do usually ;)
Best Regards,
Oliver Hanappi
Skip calling CallNextHookEx to prevent a particular key event from propagating.
Re: using SendKeys to enter Unicode input: "If your application is intended for international use with a variety of keyboards, the use of Send could yield unpredictable results and should be avoided." -MSDN Basically I think SendKeys doesn't explicitly support sending Unicode input.
Have you looked at Microsoft Text Services Framework instead of this approach you are trying? I think it is basically purpose built to address what you are trying to do.

Categories