Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 13 of 13
  1. #1
    Regular Coder
    Join Date
    May 2004
    Location
    New Hampshire, America
    Posts
    246
    Thanks
    0
    Thanked 2 Times in 2 Posts

    C++/win32: GetAsyncKeyState with timer

    Hello, I am writing a win32 game in which the player enters their name at the keyboard. I am using a timer at 1 millisecond intervals which constantly checks through a bunch of:
    Code:
    if ( GetAsyncKeyState( 0x41 ) )
                          return 'a';
    and so on...
    The problem is that if the user enters, say the letter 'a', it get's copied into the buffer (with sprintf) about 10 times because the timer is so fast. Is there a way to 'lock' the key after it is pressed by the user so that my game does not detect it about 10 times? I can't slow the timer down without risking that I miss a keypress which would annoy the player, and I can't use a check to see if the same key is entered twice in a row because the player may have done this purposefully. (I hope you understand what I mean, if not I will clarify it as best I can).
    Another solution might just be a different way to detect the keypresses. I would use DirectX which simplifies everything, but the program has mostly been written already and I don't want to switch it over.
    Thanks in advance,
    dunna.

  • #2
    New Coder
    Join Date
    Nov 2004
    Location
    Netherlands
    Posts
    87
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Can't you just catch the WM_KEYDOWN or WM_CHAR messages?

  • #3
    Senior Coder Mhtml's Avatar
    Join Date
    Jun 2002
    Location
    Sydney, Australia
    Posts
    3,531
    Thanks
    0
    Thanked 1 Time in 1 Post
    I agree. You are going about this the wrong way entirely. Catching the WM_KEYDOWN or WM_CHAR messages will be more efficient.

    In my engine, because I have taken an Object Oriented approach, I have a key state object which records the last 256 key states into a buffer. I find this is a good way to go about it. It's fast, the info is always there and you aren't continually polling, it's more event driven. Perhaps you should think about taking the same approach.
    Last edited by Mhtml; 02-13-2005 at 01:47 PM.
    Omnis mico antequam dominus Spookster!

  • #4
    Regular Coder
    Join Date
    May 2004
    Location
    New Hampshire, America
    Posts
    246
    Thanks
    0
    Thanked 2 Times in 2 Posts
    Yes, but for the WM_KEYDOWN and the WM_CHAR events don't you need a window? Sometimes I don't have a window running at all while something is loading, and other times I switch between windows but I want all the data in the same buffer. (I haven't tried the WM_CHAR, but I assume it will fail because the WM_KEYDOWN never gets read. I have been doing the message check in the WinMain function because I have multiple WinProc's.)

    It looks something like this (only relevant information shown):

    Code:
    // this is in winmain
    while( GetMessage(Msg.message, 0, 0, NULL) > 0 )
    {
              TranslateMessage(&Msg);
              if (Msg.message = WM_TIMER)
              {
                     CheckKeys();
                     // Other stuff for the timer here, but not relevant
              }
    }
    //Code orginally by Dr. Evil
    For some reason WM_KEYDOWN fails to be detected. I suppose this is because this code is not contained within a WinProc function.

  • #5
    Senior Coder Mhtml's Avatar
    Join Date
    Jun 2002
    Location
    Sydney, Australia
    Posts
    3,531
    Thanks
    0
    Thanked 1 Time in 1 Post
    Do you realise you are doing an assignment in that Msg.message if condition, instead of a comparison?

    You could create a window hook to catch keys.

    [edit:]
    Ok a few ideas.

    1) If there isn't a window, there shouldn't be a need to catch keys anyway right?

    2) If there isn't a window, create a transparent one and set focus to it.
    Last edited by Mhtml; 02-14-2005 at 01:09 AM.
    Omnis mico antequam dominus Spookster!

  • #6
    Regular Coder
    Join Date
    May 2004
    Location
    New Hampshire, America
    Posts
    246
    Thanks
    0
    Thanked 2 Times in 2 Posts
    OK, the code above may have some error in it because it was from memory. As for the transparent window / setting focus to it, I'll give it a try. There IS a window, just not one. Keys are constantly being read by different ones, so I just one one handler function to read them in and store them (CheckKeys()).

  • #7
    Senior Coder Mhtml's Avatar
    Join Date
    Jun 2002
    Location
    Sydney, Australia
    Posts
    3,531
    Thanks
    0
    Thanked 1 Time in 1 Post
    Ok, well right now I'm thinking perhaps you should try going OO. It might be a bit more work, but it's definitely better in the long run.
    Omnis mico antequam dominus Spookster!

  • #8
    Regular Coder
    Join Date
    May 2004
    Location
    New Hampshire, America
    Posts
    246
    Thanks
    0
    Thanked 2 Times in 2 Posts
    OO? What is that?

  • #9
    Senior Coder Mhtml's Avatar
    Join Date
    Jun 2002
    Location
    Sydney, Australia
    Posts
    3,531
    Thanks
    0
    Thanked 1 Time in 1 Post
    Object Oriented, ie; C++ classes.
    Omnis mico antequam dominus Spookster!

  • #10
    Regular Coder
    Join Date
    May 2004
    Location
    New Hampshire, America
    Posts
    246
    Thanks
    0
    Thanked 2 Times in 2 Posts
    So how is that going to solve my problem? (sorry if I'm a lttle slow...)

  • #11
    Senior Coder Mhtml's Avatar
    Join Date
    Jun 2002
    Location
    Sydney, Australia
    Posts
    3,531
    Thanks
    0
    Thanked 1 Time in 1 Post
    Well it's a different way of managing all of your data, it's sort of hard for me to explain... But if you know OOP (object oriented programming) then you'd see what I'm getting at.

    You'd have your engine object, and your input object, your engine would manage all of your windows and direct all input to the input object instance. It's more modular, easier to manage.

    There are lots of tutorials on classes out there. It isn't completely necessary, but I find working with classes to be much easier for something like this.
    Omnis mico antequam dominus Spookster!

  • #12
    New Coder
    Join Date
    Nov 2004
    Location
    Netherlands
    Posts
    87
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by Dunna
    Yes, but for the WM_KEYDOWN and the WM_CHAR events don't you need a window? Sometimes I don't have a window running at all while something is loading, and other times I switch between windows but I want all the data in the same buffer. (I haven't tried the WM_CHAR, but I assume it will fail because the WM_KEYDOWN never gets read. I have been doing the message check in the WinMain function because I have multiple WinProc's.)

    It looks something like this (only relevant information shown):

    Code:
    // this is in winmain
    while( GetMessage(Msg.message, 0, 0, NULL) > 0 )
    {
              TranslateMessage(&Msg);
              if (Msg.message = WM_TIMER)
              {
                     CheckKeys();
                     // Other stuff for the timer here, but not relevant
              }
    }
    //Code orginally by Dr. Evil
    For some reason WM_KEYDOWN fails to be detected. I suppose this is because this code is not contained within a WinProc function.
    If you have a window you shouldn't check the message in the message loop, just put DispatchMessage(&Msg), and it will give it to the windows, that may be why they didn't recieve the WM_CHAR message in the first place. If you want to keep the timer, just catch the WM_TIMER message.

  • #13
    Senior Coder Mhtml's Avatar
    Join Date
    Jun 2002
    Location
    Sydney, Australia
    Posts
    3,531
    Thanks
    0
    Thanked 1 Time in 1 Post
    I didn't even realise you weren't dispatching the message. But regardless, the WM_TIMER idea is not a good one.
    Omnis mico antequam dominus Spookster!


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •