mIRC Home    About    Download    Register    News    Help

Print Thread
processing shift keys in an @window #270106 02/04/22 07:10 AM
Joined: Dec 2002
Posts: 234
T
Talon Offline OP
Fjord artisan
OP Offline
Fjord artisan
T
Joined: Dec 2002
Posts: 234
I'm working on a Picwin game in mSL, my own version of a classic game, Pinball!

I wanted to utilize key presses to determine which flipper to operate, and mold this off of other PC pinball games I've played in the past. Games that I remember, like old MS-DOS Epic Pinball, you used the left and right shift keys to control your flippers, and space-bar to launch the ball. Also to keep a similar feel to a real pinball machine, which always had toggles on the side of the unit for your left and right hand to smack to make the flippers move.

Here's a screenshot:
[Linked Image from i.ibb.co]

The problem lies with both ON *:CHAR: and ON *:KEYDOWN, even $mouse.key. How do I tell which shift key is pressed?

ON *:CHAR: does nothing, there's no output for a shift key.
on *:KEYDOWN: tells me the same $keyval for both shift keys (16)
"if ($mouse.key & 4)" or "$and($mouse.key,4)" also just tells me "A" shift key is held, not "which" shift key is held...

Is there something I might be missing here? is it possible to assign an event to ANY key on the keyboard regardless of if they achieve the same function? I'm not familliar with many other keyboards but I think the only repetitive key (besides keypad numbers and number row) is shift....

Re: processing shift keys in an @window [Re: Talon] #270109 02/04/22 06:21 PM
Joined: Jul 2006
Posts: 3,880
W
Wims Offline
Hoopy frood
Offline
Hoopy frood
W
Joined: Jul 2006
Posts: 3,880
mIRC is reporting the correct keypress, there's another extra check that need to be performed to get the left/right bit


Originally Posted by https://stackoverflow.com/questions/15966642/how-do-you-tell-lshift-apart-from-rshift-in-wm-keydown-events
To distinguish between the left and right versions of the Shift, Ctrl, or Alt keys, you have to use the MapVirtualKey() function or the 'extended key' bit in the lParam passed with the virtual key's message. The following function will perform that translation for you - just pass in the virtual keycode and the lParam from the message, and you'll get back the left/right specific virtual keycodes as appropriate:

WPARAM MapLeftRightKeys( WPARAM vk, LPARAM lParam)
{
WPARAM new_vk = vk;
UINT scancode = (lParam & 0x00ff0000) >> 16;
int extended = (lParam & 0x01000000) != 0;

switch (vk) {
case VK_SHIFT:
new_vk = MapVirtualKey(scancode, MAPVK_VSC_TO_VK_EX);
break;
case VK_CONTROL:
new_vk = extended ? VK_RCONTROL : VK_LCONTROL;
break;
case VK_MENU:
new_vk = extended ? VK_RMENU : VK_LMENU;
break;
default:
// not a key we map from generic to left/right specialized
// just return it.
new_vk = vk;
break;
}

return new_vk;
}
If the virtual keycode passed in isn't one that maps to a left/right version, the original keycode is passed back unchanged. So you can just run the WM_KEYDOWN/WM_KEYUP/WM_SYSKEYDOWN/WM_SYSKEYUP message parameters through the function whenever you need to distinguish between the left and right variants.

By using MapVirtualKey() you don't need to know the lore about the left-shift and right-shift scancodes being 0x2a and 0x36 - the API takes care of that detail. And if they ever do happen to be different (not that that will ever really happen), Windows will be responsible for dealing with it, not you.

So in your WM_KEYDOWN/WM_KEYUP/WM_SYSKEYDOWN/WM_SYSKEYUP handlers you just have to add a line of code that looks like:

wparam = MapLeftRightKeys(wparam, lparam);
and the rest of your code can act on the left/right-specific VK codes as if the system message just gave them to you in the first place.
If this is implemented, which I'm all for, it would need to be a new identifier or maybe two properties for $keyval, $keyval.left would be $true if left shift/control/alt is pressed, same for $keyval.right