Arjun J Rao
Arjun J Rao

Reputation: 935

Detecting WM_KEYUP and WM_KEYDOWN events in C++

I'm writing a game and want to be able to detect when two arrow keys are pressed simultaneously.

For example :

If UP and LEFT are pressed : I want the character to move northwest
If UP alone is pressed : I want the character to move north
IF UP and LEFT were pressed, and now LEFT is released : I want the character who was moving northwest to start moving north only.

I've tried to implement this using 4 booleans, which keep track of which of the arrow keys has been pressed.

LRESULT CALLBACK WindowProc (HWND   hwnd,
                         UINT   msg,
                         WPARAM wParam,
                         LPARAM lParam)
{

      //Variables and stuff initialized

   switch (msg)
   {
    case WM_CREATE:{//Stuff to initialize windows info}break;

    case WM_COMMAND:{//Stuff that responds to menubar selections}break;


    case WM_KEYDOWN:
   {
       switch(wParam)
       {
       case VK_UP:{moveUp=true;}break;

               case VK_DOWN:{moveDown=true;}break;

       case VK_LEFT:{moveLeft=true;}break;

       case VK_RIGHT:{moveRight=true;}break;

       //More cases for handling W,Q,A,S,D and SPACE inputs

       default: //Stop moving character

       }
   }

   //Make changes to player input over here
   case WM_KEYUP:
   {
       switch(wParam)
       {
                //Cases for handling ESCAPE, P, R, W and SPACE inputs

            case VK_UP:{moveUp=false;}break;

                case VK_DOWN:{moveDown=false;}break;

                case VK_LEFT: {moveLeft=false;}break;

            case VK_RIGHT:{moveRight=false;}break;
       }//end switch

   }//end WM_KEYUP

   break;


   case WM_PAINT:{}break;

   case WM_SIZE:{}break;

   case WM_DESTROY:{}break;

   }//end switch


   return DefWindowProc (hwnd, msg, wParam, lParam);
}

And its not working... the moveUp, moveDown.. and bools are being set if I am just catching the WM_KEYDOWN events... but they are not being detected at all if I use the WM_KEYDOWN code to make them false.

Don't know why this is so. Had the same problem using a character key to enter a specific mode in my game. As long as 'Q' was pressed, I wanted the game to be in a special mode, and to come out of that mode when it was released. But even that did not work, just like this arrow-key thing is not working.

Is there something I am missing here ?

Upvotes: 1

Views: 9756

Answers (2)

Sanders
Sanders

Reputation: 109

The immediate problem I see is the missing break; statement for case WM_KEYDOWN:

This means that every time case WM_KEYDOWN: sets moveX to true case WM_KEYUP: immediately sets it back to false. You said the moveX variables are being set correctly when you're "just catching the WM_KEYDOWN events" which suggests this is indeed the issue. With case WM_KEYUP: commented out, control will instead flow into case WM_PAINT: (which you would probably not notice) before breaking.

Upvotes: 1

James
James

Reputation: 9278

Maybe the GetAsyncKeyState function would be of use to you.

Upvotes: 0

Related Questions