Jump to content


Photo

Capslock detection


  • Please log in to reply
9 replies to this topic

#1 jon sploder

jon sploder

    GMC Member

  • GMC Member
  • 858 posts

Posted 06 January 2011 - 04:58 AM

Because not all keyboards have the same ASCII combination for capslock and gamemaker doesn't have a function for keyboard_check_pressed(vk_caps), I've been trying to detect if the last key pressed is capslock.

<keyboard_pressed any>
keyboard_key_press("A");
io_handle();
if (keyboard_lastchar != "" && string_letters(keyboard_lastchar) == keyboard_lastchar)
{
    if ((string_upper(keyboard_lastchar) == keyboard_lastchar && !keyboard_check(vk_shift)) or (keyboard_check(vk_shift) && string_lower(keyboard_lastchar) == keyboard_lastchar)) 
    {Caps = 1;} else {Caps = 0;}
}
if (LastCaps != Caps) {CapsPressed = 1;} else {CapsPressed = 0;}

if (keyboard_lastkey == vk_backspace)
{
    if (ActiveTextbox == 1) {User = string_copy(User,1,string_length(User)-1);}
    if (ActiveTextbox == 2) {Password = string_copy(Password,1,string_length(Password)-1);}
}
else if (keyboard_lastchar != "#" && keyboard_lastkey != vk_shift && !CapsPressed)
{
    var Key;
    Key = keyboard_lastchar;
    if (keyboard_check(vk_shift)) {Key = string_upper(Key);}
    Key = string_lettersdigits(Key);
    
    if (ActiveTextbox == 1  && string_length(User) <= 16) {User += string_upper(Key);}
    if (ActiveTextbox == 2  && string_length(Password) <= 16) {Password += Key;}
}

LastCaps = Caps;

Is my current code. It treats all characters as caps and pressing capslock adds the last pressed key in caps...

What I'm trying to do is get the case of the key. Then if it's not capslock being pressed, add the last keyboard pressed to either User or Password. Then save the last case used. If, on next keyboard pressed the case has changed, then we pressed capslock, so lets not add anything.

I'm kinda out of it at the moment, sorry.

Edited by jon sploder, 06 January 2011 - 04:58 AM.

  • 0

#2 ragarnak

ragarnak

    GMC Member

  • Retired Staff
  • 19468 posts
  • Version:GM8

Posted 06 January 2011 - 09:31 AM

Because not all keyboards have the same ASCII combination for capslock

Capslock does not have an ASCII combination. Its a modifier to the character-keys.

and gamemaker doesn't have a function for keyboard_check_pressed(vk_caps),

Yes it has. "vk_caps" is defined as "VK_CAPITALS" in Microsofts documentation and has a value of 20 ($14).

I've been trying to detect if the last key pressed is capslock.

in the "press <any key>" (or step) event :
if keyboard_check_pressed(20)

  • 0

#3 jon sploder

jon sploder

    GMC Member

  • GMC Member
  • 858 posts

Posted 06 January 2011 - 11:09 AM


Because not all keyboards have the same ASCII combination for capslock

Capslock does not have an ASCII combination. Its a modifier to the character-keys.

and gamemaker doesn't have a function for keyboard_check_pressed(vk_caps),

Yes it has. "vk_caps" is defined as "VK_CAPITALS" in Microsofts documentation and has a value of 20 ($14).

I've been trying to detect if the last key pressed is capslock.

in the "press <any key>" (or step) event :
if keyboard_check_pressed(20)


I was doing that before but got told I was doing it wrong. O.o can anyone else confirm this?

Edited by jon sploder, 06 January 2011 - 11:09 AM.

  • 0

#4 Medusar

Medusar

    GMC Member

  • GMC Member
  • 1228 posts
  • Version:GM:Studio

Posted 06 January 2011 - 11:40 AM

The problem lies in the fact that keyboard_check() and family check whether the key is currently down, not whether caps lock is actually set. So you need to set a (global) variable. You don't know how to initialize it as you don't know whether caps lock is set when the game starts, so assume false. Then, in the step event, use
if (keyboard_check_pressed(20)) caps_on = !caps_on;
Then you can check the variable caps_on to see whether caps lock is on. It's not a pretty way, and if caps lock is turned on when the game starts, your game handles caps the wrong way round.

It can be done properly, but as far as I know that is not possible with native GM (requires a DLL). It is a strange thing that the functionality you want does exist for numlock, but not for capslock.
  • 0

#5 sabriath

sabriath

    12013

  • GMC Member
  • 3147 posts

Posted 06 January 2011 - 12:26 PM

It can be done properly, but as far as I know that is not possible with native GM (requires a DLL). It is a strange thing that the functionality you want does exist for numlock, but not for capslock.

For windows, I believe it is:

GetKeyState API in the user32 dll (long as an argument, returns an int). Using '20' for capslock as the parameter, it will return either 1 or -127 (one of them means it is being pressed (probably 1), the other means that the caps state is on).


Oh, and by the way...'vk_caps' does not exist in game maker (at least not _my_ version 8 copy). Capslock button is code 20 though.

Edited by sabriath, 06 January 2011 - 12:28 PM.

  • 1

#6 jon sploder

jon sploder

    GMC Member

  • GMC Member
  • 858 posts

Posted 06 January 2011 - 12:28 PM

Thanks. Here's the native GM code to do it: (turned out my error was forgetting to ord the char... ffs embarrassing)

Create
//Capslock
keyboard_key_press(ord("A"));
io_handle();
if ((string_upper(keyboard_lastchar) == keyboard_lastchar && !keyboard_check(vk_shift)) or (keyboard_check(vk_shift) && string_lower(keyboard_lastchar) == keyboard_lastchar)) 
{Caps = 1;} else {Caps = 0;}
^^Simulates a keyboard press to find if caps is on, on game start^^

Step
if (keyboard_check_pressed(20)) {Caps = !Caps;}

:). BTW thanks ragnorak I was wrong.

Edited by jon sploder, 06 January 2011 - 12:29 PM.

  • 0

#7 sabriath

sabriath

    12013

  • GMC Member
  • 3147 posts

Posted 06 January 2011 - 12:39 PM

jon sploder....you could also do this:

keyboard_string = "";
keyboard_key_press(65); //<-- always use numbers instead of ord() when you can
keyboard_key_release(65); //<-- don't forget to release it, don't need repeats
if(keyboard_string == "a")
  caps = false;
else
  caps = true;


ignore my previous post :P
  • 1

#8 jordan leffl

jordan leffl

    GMC Member

  • GMC Member
  • 188 posts

Posted 13 January 2011 - 02:31 AM

The more sensible way to do it instead of pressing a user's keys unnecessarily is to use a dll like LED Dll, which you can then use LED_get(1) to find if caps lock is on or off. Simulating a keystroke is a bad practice because it can also lead to unnecessary consequences on the user's end.

Edited by jordan leffl, 13 January 2011 - 02:34 AM.

  • 0

#9 slayer 64

slayer 64

    GMC Member

  • GMC Member
  • 3278 posts
  • Version:GM8.1

Posted 13 January 2011 - 05:05 AM

keyboard_key_press(65); //<-- always use numbers instead of ord() when you can


yes.
because game making is so easy, we need to make it harder by looking up ASCII character values. it's more fun that way =D

df
  • 0

#10 sabriath

sabriath

    12013

  • GMC Member
  • 3147 posts

Posted 13 January 2011 - 09:31 AM

yes.
because game making is so easy, we need to make it harder by looking up ASCII character values. it's more fun that way =D

df

ASCII codes do not have to be memorized:

http://www.asciitable.com/

And secondly, my reason for mentioning wasn't about making things more complicated, but rather that GM doesn't do any optimizations, where 'ord("A")' is obvious to us to be a recast of a constant, GM will continue to call the 'ord' function needlessly. A small game doesn't need to care about such things I suppose, but it was a suggestion anyway.
  • 0




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users