Jump to content
  • Advertisement
Sign in to follow this  
cow_in_the_well

WM_INPUT for keyboard - worth it?

This topic is 3631 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, So DirectInput has been mostly deprecated (for keyboard and mouse) and everyone is saying to use WM_INPUT instead. So this is what I've done, for both keyboard and mouse. However, I'm wondering if is there actually any real advantage to using WM_INPUT for keyboard, rather than just listening for WM_KEYDOWN/KEYUP? I've been poking around and can't find much information on this. Mouse gets the benefit of high-res input, but does keyboard get any? I can't imagine the overhead of windows processing the device data into WM_KEYDOWN/KEYUP etc causes any significant extra overhead. As an aside, I've only implemented unbuffered input (i.e. using GetRawInputData). According to MSDN buffered input should be used for devices that create large amounts of data. Unbuffered has worked fine for me so far, so I'm just wondering if anyone has had any problems with it for mouse (the only HID that I'm supporting that would create any sizable amount of data). Cheers, Thomas

Share this post


Link to post
Share on other sites
Advertisement
You should be fine with unbuffered for keyboard/mouse. I'm guessing buffered mode is mostly useful for non-human-generated input (e.g. GPS devices, telephony devices, etc)

As for the advantages of using it for the keyboard, I guess the main one is that you're using the same infrastructure for both keyboard and mouse (and whatever else).

But still, if you're wanting to accept textual input from the users as well (e.g. let them write messages to each other, etc, not just controlling character movement and stuff) you'll probably want to at least use the normal input events for that so that international characters and stuff get properly handled (especially things like dead keys). If you're looking at a real international market, then you'd also need to look into supporting IMEs and stuff (but that's probably getting a bit advanced, and I wouldn't bother until it actually becomes a requested feature [smile])

Share this post


Link to post
Share on other sites
Ah yes. I am actually needing to use WM_CHAR for text input (one of the main reasons for dropping DInput -_^). So I might as well use WM_KEY* for all keyboard stuff. There's no real issue with doing mouse/keyboard in different ways.

Thanks.

-Thomas

Share this post


Link to post
Share on other sites
You should be fine with WM_KEYDOWN, WM_KEYUP. It's certainly not any slower than using WM_INPUT.

Share this post


Link to post
Share on other sites
Okay - found a reason to use WM_INPUT for keyboard. I want to get events for individual left shift/right shift. Unfortunately WM_KEYDOWN/KEYUP is only sent once for VK_SHIFT even if you press both keys. WM_INPUT gets the keydown event for both (I still need to use GetAsyncKeyState to determine left or right because it doesn't set the RI_KEY_E0 in the flags).

Also, since I need to remap the Virtual Key's to DIK (for compatability purposes), I was at first excited because it appeared that RAWKEYBOARD::MakeCode seemed to be mapping to the DIK scan codes. Unfortunately, it doesnt seem the case for some keys - for example the down arrow was being reported as Numpad 2 (yes I know, numpad 2 is down arrow, but I would have thought the two keys would be distinct at this low level). Am I missing something here? There doesn't seem to be much documentation on the MakeCode field. It'd be nice to not have to have a giant LUT to convert from the VK to the DIK :).

Thanks.

-Thomas

Share this post


Link to post
Share on other sites
Quote:
Original post by cow_in_the_well
Okay - found a reason to use WM_INPUT for keyboard. I want to get events for individual left shift/right shift. Unfortunately WM_KEYDOWN/KEYUP is only sent once for VK_SHIFT even if you press both keys. WM_INPUT gets the keydown event for both (I still need to use GetAsyncKeyState to determine left or right because it doesn't set the RI_KEY_E0 in the flags).
What does WM_KEYDOWN give you? Does it only detect one shift key or something?

Quote:
Original post by cow_in_the_well
Also, since I need to remap the Virtual Key's to DIK (for compatability purposes), I was at first excited because it appeared that RAWKEYBOARD::MakeCode seemed to be mapping to the DIK scan codes. Unfortunately, it doesnt seem the case for some keys - for example the down arrow was being reported as Numpad 2 (yes I know, numpad 2 is down arrow, but I would have thought the two keys would be distinct at this low level). Am I missing something here? There doesn't seem to be much documentation on the MakeCode field. It'd be nice to not have to have a giant LUT to convert from the VK to the DIK :).
ISTR there's a way to convert from one to another, it was mentioned in a thread somewhere here ages ago by using a couple of Win32 functions. I'll try to look it up and edit this post if I find it.

EDIT: MapVirtualKeyEx sounds like it'll do the job, with an example usage Here - although that's going from scan codes to virtual keys, you'll want to go the other way obviously.

EDIT #2: This also looks promising.

Share this post


Link to post
Share on other sites
Cool - I am now mapping scancode to VK using MapVirtualKey thanks steve. I can distinguish between all left/rights now. My problem now is I need to associate the WM_CHAR with the WM_KEYDOWN that generated it, so I can no longer rely on just using WM_CHAR. :(

I'm using ToUnicodeEx to determine character based on keyboard layout, which works fine however I'm having a bit of a hard time with the dead keys. In the CEGUI link you posted they're manually mapping the ASCII key to a unicode diacritic (the switch statement). This seems really horrible, but I can't find any win32 functions in the keyboard layout stuff for doing this for me (the full list of possible diacritics is rather large). Anyone have any suggestions on how to do a proper diacritic key->unicode codepoint conversion without setting up a huge LUT myself (the actual conversion would surely be keyboard layout specific anyway...)?

Steve: re: VK_SHIFT - if you press left shift and then right shift (while still holding left shift) you only get the VK_SHIFT event for the first shift. You only get a WM_KEYUP for VK_SHIFT once you have released both shifts.

Cheers.

Share this post


Link to post
Share on other sites
What exactly is the problem? ToUnicode should theoretically handle dead keys. It returns -1 if there's not (yet) enough state built up to return an actual character but the next keypress should work.

So you press the dead key for the acute accent (say) and ToUnicode will return -1. Just ignore it for now. Then you press "E" (say) and ToUnicode should return 1 and the buffer will contain an "é".

At least, that's my understanding, what are you seeing?

By the way, you should still be able to use WM_CHAR with WM_INPUT. As long as you don't specify the RIDEV_NOLEGACY flag when you register for raw input.

Share this post


Link to post
Share on other sites
I do receive WM_CHAR, it's just that I need to store which key event generated the char event (so I can decide later on whether I want to allow the char to go through to the scripts).

Anyway, looking at the documentation that's how I thought it'd behave. However here's some output I'm getting from ToUnicodeEx (the four numbers is the resulting buffer, the first number is the only pertinent one):

when I just press "e":

ToUnicodeEx: result is 1 (101 0 0 0)

when I press "'" and then "e" (with Spanish keyboard layout):

ToUnicodeEx: result is -1 (39 0 28858 122)
ToUnicodeEx: result is 1 (101 0 28860 122)

(the last two values in the buffer seems to be garbage as it changes every time, in any case the return value is 1 indicating the first element should be considered).

The code:


HKL kblayout = GetKeyboardLayout(0);
uchar kbstate[256];
if ( GetKeyboardState(kbstate) )
{
wchar_t buff[4] = {0,0,0,0};
int res = ToUnicodeEx( vkey, rkb->MakeCode, kbstate, buff, ARRAY_SIZE(buff), 0, kblayout );

INFO_MSG("ToUnicodeEx: result is %d (%d %d %d %d)\n",
res, buff[0], buff[1], buff[2], buff[3]);
...



Any ideas? Thanks :).

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!