Go Back   Forums > Community Chatterbox > Tech Corner > Programming
Memberlist Forum Rules Search Today's Posts Mark Forums Read
Search Forums:
Click here to use Advanced Search

Reply
 
Thread Tools Display Modes
Old 25-03-2011, 04:36 PM   #1
The Fifth Horseman
FUTURE SCIENCE BASTARD
 
The Fifth Horseman's Avatar


 
Join Date: Oct 2004
Location: Opole, Poland
Posts: 14,276
Default Distunguishing regular and keypad Enter keys in C# forms?

I'm working on a C# application that allows a user to configure a control profile for an emulator. Part of that involves binding keyboard keys to controller buttons, and is done through a clickable "on-screen keyboard" dialog. Today, I decided to add keyboard recognition to the dialog window, so that the user can simply press a key on his keyboard to map it.

It's working, apart from the fact that I don't seem to have any way of telling apart the numpad enter key with the regular enter. This is something I need to fix, but can't find any info on how this could be done.

The current code kludge handling the keyboard input in this part of my application is below:
Code:
        [DllImport("user32.dll")]
        static extern short GetAsyncKeyState(System.Windows.Forms.Keys vKey);

        private bool IsKeyPressed(Keys key)
        {
            if (Convert.ToInt32(GetAsyncKeyState(key).ToString()) == -32767)
                return true;
            else
                return false;
        }
        protected override bool ProcessDialogKey(Keys keyData)
        {
            if (IsKeyPressed(Keys.LShiftKey)) button55.PerformClick();
            else if (IsKeyPressed(Keys.RShiftKey)) button28.PerformClick();
            else if (IsKeyPressed(Keys.LMenu)) button69.PerformClick();
            else if (IsKeyPressed(Keys.LControlKey))
            {
                if (IsKeyPressed(Keys.RMenu)) button70.PerformClick();
                else button67.PerformClick();
            }
            else if (IsKeyPressed(Keys.RControlKey)) button68.PerformClick();
            else if (IsKeyPressed(Keys.RMenu)) button70.PerformClick();
            else switch (keyData)
                {
                    case Keys.Escape: button1.PerformClick(); break;
                    // there's 90-something lines of the same thing repeated, differentiated only between different Keys enums and buttons.
                    case Keys.Right: button81.PerformClick(); break;

                    default:
                        break;
                }
            
            return true;
            
        }
__________________

"God. Can't you people see I'm trying to commit a crime against science and nature here?"
-- Reed Richards
The Fifth Horseman is offline                         Send a private message to The Fifth Horseman
Reply With Quote
Old 25-03-2011, 11:38 PM   #2
Japo
Autonomous human
 
Japo's Avatar


 
Join Date: Mar 2006
Location: ,
Posts: 4,613
Default

I see you have immediately resorted to importing a native Windows API function, probably that's familiar territory for you. :P I suppose by "C# forms" you mean Windows Forms (System.Windows.Forms namespace). I haven't had more luck than you using the .NET types in that namespace, both keys can't be told apart with them AFAIK, any more than with your Windows API call--probably the Windows version of the .NET Framework calls that same WinAPI function you're importing yourself, or a similar one.

I don't really know the answer, but I think that if you want that kind of low-level information about keyboard input, you may have to use a Stream (or derived) object (System.IO namespace) and inspect the bytes yourself or something. That's the good news, the bad news is that I have no experience in keyboard IO (if it were about files I have a little bit) and I have no clue how to create an instance of Stream that's connected to the keyboard. But if you dedicate a little time to research it you'll probably find the answer.

Also you could use a different library for IO, like SDL (the one DOSBox uses, but its documentation is not stellar), you already know how to invoke native DLLs from .NET in C#.
__________________
Life starts every day anew. Prospects not so good...
Japo is offline                         Send a private message to Japo
Reply With Quote
Old 26-03-2011, 10:35 AM   #3
arete
If All Else Fails, Play Dead
 
arete's Avatar


 
Join Date: May 2008
Location: Waterside, South Africa
Posts: 3,138
Default

Distinguishing, my love. (Feel free to hard-delete this annoying message. ^^)
__________________

"You have heard that it was said, 'You shall love your neighbor and hate your enemy.' But I say to you, love your enemies, bless those who curse you, do good to those who hate you, and pray for those who spitefully use you and persecute you..."
arete is offline                         Send a private message to arete
Reply With Quote
Old 26-03-2011, 11:53 AM   #4
The Fifth Horseman
FUTURE SCIENCE BASTARD
 
The Fifth Horseman's Avatar


 
Join Date: Oct 2004
Location: Opole, Poland
Posts: 14,276
Default

Typo.
__________________

"God. Can't you people see I'm trying to commit a crime against science and nature here?"
-- Reed Richards
The Fifth Horseman is offline                         Send a private message to The Fifth Horseman
Reply With Quote
Old 26-03-2011, 12:01 PM   #5
arete
If All Else Fails, Play Dead
 
arete's Avatar


 
Join Date: May 2008
Location: Waterside, South Africa
Posts: 3,138
Default

I knoe
__________________

"You have heard that it was said, 'You shall love your neighbor and hate your enemy.' But I say to you, love your enemies, bless those who curse you, do good to those who hate you, and pray for those who spitefully use you and persecute you..."
arete is offline                         Send a private message to arete
Reply With Quote
Old 27-03-2011, 11:29 AM   #6
Kanalia
Newbie

 
Join Date: Mar 2011
Location: ,
Posts: 13
Default

Well, I think that going into SDL or any other external library just for this keyboard mapping functionality would be a kind of overkill.

IMHO it isn't possible to distinguish the RETURN (main keyboard) and ENTER (numpad) keys with GetAsyncKeyState(), precisely because both are mapped to the VK_RETURN virtual key. Same thing with other "duplicated" keys (such as +,-,*, etc.) IIRC.

I suggest that you handle the WM_KEYDOWN event message through WinAPI. With this approach you'll get both the virtual key code (stored in wParam), which is the same as what you're getting already through calling GetAsyncKeyState(), and the so called "keydata" (stored in lParam).
The 24th bit of the keydata parameter enables you to distinguish between the two ENTER keys (value 0 for RETURN, 1 for numpad ENTER).

More info: http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx

If you intend to use this approach I think you'd be better of with axing the GetAsyncKeyState() calls and just listen for the WM_KEYDOWN events.

I trust that you already know how to handle Windows messages inside a .NET application

Last edited by Kanalia; 27-03-2011 at 11:33 AM.
Kanalia is offline                         Send a private message to Kanalia
Reply With Quote
Old 28-03-2011, 08:48 PM   #7
The Fifth Horseman
FUTURE SCIENCE BASTARD
 
The Fifth Horseman's Avatar


 
Join Date: Oct 2004
Location: Opole, Poland
Posts: 14,276
Default

Thank you, that helped.
It seems I'm going to have to keep GetAsyncKeyState for one special case, namely the right ALT button. It returns the Left CTRL scancode when pressed, and I can only determine it's that button by checking GetAsyncKeyState.
__________________

"God. Can't you people see I'm trying to commit a crime against science and nature here?"
-- Reed Richards
The Fifth Horseman is offline                         Send a private message to The Fifth Horseman
Reply With Quote
Old 30-03-2011, 07:21 PM   #8
Japo
Autonomous human
 
Japo's Avatar


 
Join Date: Mar 2006
Location: ,
Posts: 4,613
Default

Just for the record, today I remembered this thread and I thought that XNA (MS's .NET library for games programming) would have better types for input than Windows Forms. (Too bad Windows Forms and both WinAPI functions decide not to tell some equivalent keys apart, otherwise they could do the job.) I haven't tried XNA yet but here are some links on the topic, in case you want to explore:

http://msdn.microsoft.com/en-us/library/bb203899.aspx

http://msdn.microsoft.com/en-us/library/bb203902.aspx

http://msdn.microsoft.com/en-us/libr...ork.input.aspx

Also it occurred to me that keyboard input may not be so simple as I was thinking initially, in a multi-tasking OS like Windows. Applications don't get input directly, it's the OS that decides to send it in a message to the one application that has focus. Also searching the MSDN forums I found a lot of threads about installing global hooks with the WinAPI to monitor input, but I wonder when such a crude bypass is recommended or actually used.
__________________
Life starts every day anew. Prospects not so good...

Last edited by Japo; 30-03-2011 at 07:26 PM.
Japo is offline                         Send a private message to Japo
Reply With Quote
Old 01-04-2011, 06:13 PM   #9
Kanalia
Newbie

 
Join Date: Mar 2011
Location: ,
Posts: 13
Default

Quote:
Originally Posted by The Fifth Horseman View Post
Thank you, that helped.
It seems I'm going to have to keep GetAsyncKeyState for one special case, namely the right ALT button. It returns the Left CTRL scancode when pressed, and I can only determine it's that button by checking GetAsyncKeyState.
You're welcome.

As to the "special case", you don't need to keep GetAsyncKeyState just for that. The left and right ALT keys have their own keycodes defined, known respectively as VK_LMENU and VK_RMENU. Have you tried those?

Also, IIRC, the RALT = LCTRL problem occurs usually when a non-US (or maybe non-English?) keyboard layout is set in the OS. Just for kicks, try out how your program works with US keyboard layout set (instead of Polish, which I presume is the case with you ).

Also, if the above doesn't work, using the same way you already listen for WM_KEYDOWN messages, you could just add the special case for the WM_SYSKEYUP message. Details are available here: http://msdn.microsoft.com/en-us/libr...8VS.85%29.aspx
It's easy to understand so I won't explain.

Japo:
Ah yes, it's not that easy. WinAPI is a pretty complicated API and there's usually more ways than one (or even two) to accomplish something, even if it seems to be something trivial

Quote:
Originally Posted by Japo
and both WinAPI functions decide not to tell some equivalent keys apart, otherwise they could do the job.)
Well if that were really the case then we wouldn't have any good solution, right?

Utilizing XNA for a purely desktop windowed app makes about the same sense as using SDL in this case.

Last edited by Kanalia; 01-04-2011 at 06:21 PM.
Kanalia is offline                         Send a private message to Kanalia
Reply With Quote
Old 02-04-2011, 12:11 PM   #10
The Fifth Horseman
FUTURE SCIENCE BASTARD
 
The Fifth Horseman's Avatar


 
Join Date: Oct 2004
Location: Opole, Poland
Posts: 14,276
Default

Yes, the issue with the right Alt was a result of the non-US layout. But then, I do have to take all the possibilities into account including that the user will be running a layout like that. :/
__________________

"God. Can't you people see I'm trying to commit a crime against science and nature here?"
-- Reed Richards
The Fifth Horseman is offline                         Send a private message to The Fifth Horseman
Reply With Quote
Reply


Similar Threads
Thread Thread Starter Forum Replies Last Post
regular sgtboat Blah, blah, blah... 4 26-11-2008 03:30 AM
When will regular updates start? Doink Blah, blah, blah... 6 13-12-2007 10:00 AM
How To Make Html/php Forms Read New Lines? Danny252 Programming 2 05-01-2007 08:20 PM
Enter Thevoid's Gallery TheVoid Music, Art, Movies 672 26-06-2006 03:10 PM
Regular Expressions Kon-Tiki Programming 23 26-01-2006 09:58 PM

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump
 


The current time is 10:31 PM (GMT)

 
Powered by vBulletin® Version 3.7.1
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.