Keyboard hook in c# - 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.

Related

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

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

Determine if a string only contains characters from the seven bit alphabet(c#)

I'm developing an sms application in c#. The service that I use to send a message only allows characters form the 7 bit alphabet. I'm looking for a way to check if a message only contains characters from this alphabet.
My first idea was to split the message into a character array and then loop these characters and compare them to the alphabet. But I bet there is a much better.
7 big alphabet:
http://www.dreamfabric.com/sms/default_alphabet.html
You can find a utility GSM Encoding class (it simply derives from the abstract System.Text.Encoding) defined here: The GSM character set in .NET. I think this is the most elegant and reusable way.
I think you need to determine the encoding of input text look at the Encoding class

Optimistic RegEx Matching for User Text Entry

I'm working on a text entry application that uses regular expressions to validate user input. The goal is to allow keypresses that fit a certain RegEx while rejecting invalid characters. One issue I've run into is that when a user starts inputting information they may create a string that doesn't yet match the given regex, but could cause a match in the future. These strings get erroneously rejected. Here's an example - given the following regex for inputting date information:
(0?[1-9]|10|11|12)/(0?[1-9]|[12]\\d|30|31)/\\d{2}\\d{2}
A user may begin entering "1/" which could be a valid date, but RegEx.IsMatch() will return false and my code ends up rejecting the string. Is there a way to "optimistically" test strings against a regular expression so that possible or partial matches are allowed?
Bonus: For this RegEx in particular there are some sequences which cause required characters. For example, if the user types "2/15" the only possible valid character they could enter next is "/". Is it possible to detect those scenarios so that the required characters could be automatically entered for the user to ease input?
What you can do is anchor your RegExp (i.e. adding ^ and $, as in start/end of line) and make some component optionnal for validation, but strictly defined if present.
Something looking like this:
^(0?[1-9]|10|11|12)(/((0?[1-9]|[12]\\d|30|31)(/(\\d{2}(\\d{2})?)?)?)?)?$
I do realize it looks horrible but as far as I know there is no way to tell the regexp engine to validate as long as the string satisfies the beginning of the regexp pattern.
In my opinion, the best way to achieve what you want to do is to create separate inputs for day/month/date and check their value when leaving the text field.
It also provides a better visibility and user-experience, as I believe no one likes to be prevented from typing certain characters into a text field with or without noticing them disappear as they type or having slashes inserted automatically and without notice.
Have you ever used and app or form that worked that way, simply refusing to accept any keypress it didn't like? If the answer is Yes, did it blow an electronic raspberry each time you pressed a wrong key?
If you really need to validate the input before the form is submitted, use a passive feedback mechanism like a red border around the textfield that disappears the regex matches the input. Also, make sure there's a Help button or a tooltip nearby to provide constructive feedback.
Of course, the best option would be to use a dedicated control like a date-entry widget. But whatever you do, don't do it in such a a way that it feels like you're playing guessing games with the user.

Character / Language

I just developed a simple asp.net mvc application project for English only. I want to block user's any input for a language other than English. Is it possible to know whether user inputs other languages when they write something on textbox or editor in order to give a popup message?
You could limit the input box to latin characters, but there's no automatic way to see if the user entered something in say English, Finnish or Norwegian. They all mostly use a-z. Any character outside of a-z could give you an indication, but certain accents needs to be allowed in English as well, so it's not 100%.
Google Translate exposes a javascript API to detect the language of text.
Use the following code:
<p>Note that this community uses the English language exclusively, so please be
considerate and write your posts in English. Thank you!</p>
there are two tests you can do. one is to find out what the cultureinfo is set on the users machine:
http://msdn.microsoft.com/en-us/library/system.threading.thread.currentuiculture.aspx
this will give you their current culture setting, which is a start. of course, you can have your setting as 'english' but still typing in russian, and most of the letters will be the same..
so the next step is to discover the language using this: http://www.google.com/uds/samples/language/detect.html
it's not the greatest, according to online discussions, but its a place to start. I'm sure there are better natural language identifiers out there, though.
Checking for Latin 26
If you wanted to ensure that any non-English letters were submitted, you could simply validate that they fall outside the A-Z, a-z, 0-9 and normal punctuation ranges. It sounds like you want the regular non-Latin characters to be detected and rejected.
Detecting the user's OS settings, keyboard settings isn't the best way, as the user could have multiple keyboards attached, and have use of copy/paste.
UI Validation
At the user interface level, you could create a jQuery method that would check the value of a textbox for a value other than your acceptable range. Perhaps that's A-Z, a-z and numeric. You could do this on event onBlur. Remember that you might want to allow ', .
$('#customerName').blur(function() {
var isAlphaNumeric;
//implementation of checking a-z, A-Z, 0-9, etc.
alert(isAlphaNumeric);
});
Controller Validation
If you wanted to ALSO implement this at the controller level, you could run a regex on the incoming values.
public ActionMethod CreateCustomer(string custName)
{
if (IsAcceptableRange(custName))
{
//continue
}
}
public bool IsAcceptableRange(string input)
{
//whitelist all the valid inputs here. be sure to include
//space, period, apostrophe, hypen, etc
Regex alphaNumericPattern=new Regex("[^a-zA-Z0-9]");
return !alphaNumericPattern.IsMatch(input);
}
Google Translate was quoted in two answers, but I want to add that Microsoft Word API may also be used to detect language, just like Word does for check spelling.
It is for sure not the best solution, since language detection by Microsoft Office doesn't work very well (IMHO), but may be an alternative if doing web requests to Google or other remote service on every posted message is not a solution.
Also, check spelling through Microsoft Word API can be useful too. If a message has a huge number of misspelled words when checking in English, it's probably because the message is written in another language (or the author of the message writes too badly, too).
Finally, I completely agree with Matti Virkkunen. The best, and maybe the only way to ensure that messages will be written in English is to ask the users to write in English. Otherwise, it's just as bad as implementing obscenity filters.

How do I find out if my string contains the "micro" Unicode character?

I have a Excel Spreadsheet with lab data which looks like this:
µg/L (ppb)
I want to test for the presence of the Greek letter "µ" and if found I need to do something special.
Normally, I would write something like this:
if ( cell.StartsWith(matchSequence) ) {
//.. <-- universal symbol for "magic" :)
}
I know there is an Encoding API in the Framework, but should I use it for just this one edge-case or just copy the Greek micro symbol from the character map?
How would I test for the presence of a this unicode character? The character map seems like a "cheap" fix that will bite me later (I work for a company which is multinational).
I want to do something that is maintainable and not just some crazy math-voodoo conversion that only works for this edge case.
I guess I'm asking for best practice advice here.
Thanks!
You need to work out the unicode character you're interested in, then you can represent it with in code with an escape sequence.
For example, µ is U+00B5, so you just need:
if (text.Contains("\u00b5"))
You can find out the Unicode value from charmap or from the Unicode code charts.
The Unicode code point for micro µ is U+00B5 and is different from the "Greek letter mu" µ, which is at U+03BC. So you can use "\u00b5" to find it, and possibly also look for "\u03bc" as well - they look the same, so whoever created the spreadsheet could have used the wrong one!
You can create a Char from the numeric equivelent shown to you in the Character Map (displays as U+0050 for 'P'). To do this simply check the contains:
string value;
if (value.Contains(Char.ConvertFromUtf32(0x0050)))
;
C# code files are usually encoded in utf8, since the language is using this encoding. All strings and strign literals in c# (and other .NET languages) are encoded in utf16. So you can safely copy the micro character from the character map.
You can also use its integer value as unicode literal like 0x1234.

Categories