Click here to Skip to main content
15,888,610 members
Home / Discussions / C#
   

C#

 
GeneralRe: Testing for current PictureBox.Image Pin
kanchoette9-Jul-09 4:27
kanchoette9-Jul-09 4:27 
GeneralRe: Testing for current PictureBox.Image Pin
Luc Pattyn9-Jul-09 9:31
sitebuilderLuc Pattyn9-Jul-09 9:31 
AnswerRe: Testing for current PictureBox.Image Pin
0x3c09-Jul-09 5:40
0x3c09-Jul-09 5:40 
QuestionC# Rijndael Encrypt and Pel Crypt::CBC Pin
DanielLC9-Jul-09 3:13
DanielLC9-Jul-09 3:13 
QuestionGraphics.DrawImageUnscaled blurry Pin
Huisheng Chen9-Jul-09 3:02
Huisheng Chen9-Jul-09 3:02 
AnswerRe: Graphics.DrawImageUnscaled blurry Pin
Christian Graus9-Jul-09 3:17
protectorChristian Graus9-Jul-09 3:17 
GeneralRe: Graphics.DrawImageUnscaled blurry Pin
Huisheng Chen9-Jul-09 3:53
Huisheng Chen9-Jul-09 3:53 
QuestionToUnicodeEx and dead keys inside system wide hooks Pin
RevengerPT9-Jul-09 2:52
RevengerPT9-Jul-09 2:52 
Hello there. I'm trying to detect which character is produced whenever the user presses a key. For this, I'm using the ToUnicodeEx function, which translates the specified virtual-key code and keyboard state to the corresponding Unicode character, inside a keyboard system wide hook. However, every time the user presses dead keys, such as the ones producing '¨', '~' or '´', strange things happen. Here is sample code of the first version:

private static int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
{
	//indicates if any of underlaing events set e.Handled flag
	bool handled = false;

	if (nCode >= 0)
	{
		//read structure KeyboardHookStruct at lParam
		KeyboardHookStruct MyKeyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));

		// raise KeyPress
		if (s_KeyPress != null && wParam == WM_KEYDOWN)
		{
			bool isDownShift = ((GetKeyState(VK_SHIFT) & 0x80) == 0x80 ? true : false);
			bool isDownCapslock = (GetKeyState(VK_CAPITAL) != 0 ? true : false);

			byte[] keyState = new byte[256];
			GetKeyboardState(keyState);
			System.Text.StringBuilder sbString = new System.Text.StringBuilder();
			IntPtr HKL = GetKeyboardLayout(0);

			switch (ToUnicodeEx((uint)MyKeyboardHookStruct.VirtualKeyCode,
				(uint)MyKeyboardHookStruct.ScanCode,
				keyState,
				sbString,
				5,
				(uint)MyKeyboardHookStruct.Flags,
				HKL))
			{
				case 1:
					char key = sbString.ToString()[0];
					if ((isDownCapslock ^ isDownShift) && Char.IsLetter(key)) key = Char.ToUpper(key);
					KeyPressEventArgs e = new KeyPressEventArgs(key);
					s_KeyPress.Invoke(null, e);
					handled = handled || e.Handled;
					break;
			}
		}

	}

	//if event handled in application do not handoff to other listeners
	if (handled)
		return -1;

	//forward to other application
	return CallNextHookEx(s_KeyboardHookHandle, nCode, wParam, lParam);
}


With this code I faced the following problem: Whenever I tried to type "á" in notepad, which requires '´' to be pressed before 'a', the result would be "´´a". Although the captured character by ToUnicodeEx was 'á', I can't admit that my application prevents the user from using characters such as 'á'.

So, I worked around this problem by avoiding ToUnicodeEx to be called whenever a dead key is pressed. This way, I can avoid the ToUnicodeEx function from messing with the keyboard state. Here is the current version code:

private static int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
{
	//indicates if any of underlaing events set e.Handled flag
	bool handled = false;

	if (nCode >= 0)
	{
		//read structure KeyboardHookStruct at lParam
		KeyboardHookStruct MyKeyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));

		// raise KeyPress
		if (s_KeyPress != null && wParam == WM_KEYDOWN)
		{
			bool isDownShift = ((GetKeyState(VK_SHIFT) & 0x80) == 0x80 ? true : false);
			bool isDownCapslock = (GetKeyState(VK_CAPITAL) != 0 ? true : false);

			byte[] keyState = new byte[256];
			GetKeyboardState(keyState);
			System.Text.StringBuilder sbString = new System.Text.StringBuilder();
			IntPtr HKL = GetKeyboardLayout(0);

			if (!IsDeadKey((uint)MyKeyboardHookStruct.VirtualKeyCode))
			{
				switch (ToUnicodeEx((uint)MyKeyboardHookStruct.VirtualKeyCode,
					(uint)MyKeyboardHookStruct.ScanCode,
					keyState,
					sbString,
					5,
					(uint)MyKeyboardHookStruct.Flags,
					HKL))
				{
					case 1:
						char key = sbString.ToString()[0];
						if ((isDownCapslock ^ isDownShift) && Char.IsLetter(key)) key = Char.ToUpper(key);
						KeyPressEventArgs e = new KeyPressEventArgs(key);
						s_KeyPress.Invoke(null, e);
						handled = handled || e.Handled;
						break;
				}
			}
		}
	}

	//if event handled in application do not handoff to other listeners
	if (handled)
		return -1;

	//forward to other application
	return CallNextHookEx(s_KeyboardHookHandle, nCode, wParam, lParam);
}

static bool IsDeadKey(uint key)
{
	if ((MapVirtualKey(key, 2) & 2147483648) == 2147483648)
	{
		return true;
	}
	else
	{
		return false;
	}
}


I though this solution would solve my problem, but I was wrong. The result has improved, but it's not quite what I wanted. Now, typing 'á' in notepad results in 'a'. Notice that the accent '´' is missing.

Does anyone know how to work around this issue? My current method already captures the correct character, but prevents the user from producing characters with accents or diacritics. I think the KeyboardHookProc method just need a few changes, but I can't figure them out.

Thanks in advance.

PS: I tried the solution described in the following link: http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/7c038b72-3ae3-4b9e-9e21-33c7ccea735c. However, the result is quite the same as in my current version. That code only erases the keyboard buffer, which deletes the accents, therefore not allowing the user to use them.
Questioncash register. Pin
solomonope9-Jul-09 2:03
solomonope9-Jul-09 2:03 
AnswerRe: cash register. Pin
Christian Graus9-Jul-09 2:13
protectorChristian Graus9-Jul-09 2:13 
GeneralRe: cash register. Pin
solomonope9-Jul-09 3:43
solomonope9-Jul-09 3:43 
AnswerRe: cash register. Pin
Rajesh R Subramanian9-Jul-09 3:17
professionalRajesh R Subramanian9-Jul-09 3:17 
GeneralRe: cash register. Pin
Manas Bhardwaj9-Jul-09 3:28
professionalManas Bhardwaj9-Jul-09 3:28 
GeneralRe: cash register. Pin
solomonope9-Jul-09 3:37
solomonope9-Jul-09 3:37 
GeneralRe: cash register. Pin
OriginalGriff9-Jul-09 4:02
mveOriginalGriff9-Jul-09 4:02 
GeneralRe: cash register. Pin
Rajesh R Subramanian9-Jul-09 4:13
professionalRajesh R Subramanian9-Jul-09 4:13 
QuestionProblem in viewing image in multi user environment Pin
Khawar Abbas19-Jul-09 2:01
Khawar Abbas19-Jul-09 2:01 
AnswerRe: Problem in viewing image in multi user environment Pin
Christian Graus9-Jul-09 2:14
protectorChristian Graus9-Jul-09 2:14 
GeneralRe: Problem in viewing image in multi user environment Pin
Khawar Abbas19-Jul-09 2:19
Khawar Abbas19-Jul-09 2:19 
GeneralRe: Problem in viewing image in multi user environment Pin
Christian Graus9-Jul-09 2:36
protectorChristian Graus9-Jul-09 2:36 
GeneralRe: Problem in viewing image in multi user environment Pin
Khawar Abbas19-Jul-09 2:41
Khawar Abbas19-Jul-09 2:41 
Question[Message Deleted] Pin
guchu9-Jul-09 1:53
guchu9-Jul-09 1:53 
AnswerRe: reading from the datagrid Pin
Christian Graus9-Jul-09 2:17
protectorChristian Graus9-Jul-09 2:17 
AnswerRe: [Message Deleted] Pin
Christian Graus9-Jul-09 2:36
protectorChristian Graus9-Jul-09 2:36 
QuestionPropertyChanged Notofication Pin
schiebel-t9-Jul-09 1:24
schiebel-t9-Jul-09 1:24 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.