16

I'm working on a C++ DirectX 2D game and I need keyboard and mouse input.
Wikipedia says:

Microsoft recommends that new applications make use of the Windows message loop for keyboard and mouse input instead of DirectInput

So how should I use it?
I have a GameScreen class whice take care of the drawing and the updating(game logic), I call the Draw and the Update methods inside a windows message loop.

Thanks

Adir
  • 1,393
  • 3
  • 17
  • 31

7 Answers7

14

Since you pretty much have to run a message pump in order to have a window, you might as well use that pump to handle keyboard and mouse input as well. It's entirely up to your pump whether you hand keyboard events on to a child window, you can handle them in the pump if you prefer.

Your typical message pump looks like this:

while (GetMessage(&msg, NULL, 0, 0))
{
    if (WM_QUIT == msg.message)
       break;
    TranslateMessage(&msg); // post a WM_CHAR message if this is a WM_KEYDOWN
    DispatchMessage(&msg);  // this sends messages to the msg.hwnd
}

For a game, your pump might look more like this

while (true)
{
   if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE | PM_NOYIELD))
   {
      bool fHandled = false;
      if (msg.message >= WM_MOUSEFIRST && msg.message <= WM_MOUSELAST)
         fHandled = MyHandleMouseEvent(&msg);
      else if (msg.message >= WM_KEYFIRST && msg.message <= WM_KEYLAST)
         fHandled = MyHandleKeyEvent(&msg);
      else if (WM_QUIT == msg.message)
         break;

      if ( ! fHandled)
      {
         TranslateMessage(&msg);
         DispatchMessage(&msg);
      }
   }
   else
   {
       // if there are no more messages to handle right now, do some
       // game slice processing.
       //
   }
}

Of course, your actual pump will likely be even more complex than that, possibly with a MsgWaitForMultipleObjects so that you can wake periodically even if there a no messages to process, but immediatelly when there are messages.

John Knoeller
  • 31,289
  • 4
  • 56
  • 90
  • 5
    I would like to know why shouldn't I use DirectInput. Thanks – Adir Jan 30 '10 at 10:32
  • 1
    Answered by Alex in http://stackoverflow.com/questions/2165230/should-i-use-directinput-or-windows-message-loop/2168067#2168067 – bobobobo Feb 10 '10 at 04:22
7

DirectInput has been deprecated for good reasons. As fas as I know, it creates an extra thread and just queries Windows' Raw Input interface. For best performance, I'd use Raw Input directly.

If performance is not an issue for you (and I guess that's the case for a 2D game on current hardware), follow Microsoft's advice and use window messages, as described by John Knoeller.

Alexander Gessler
  • 42,787
  • 5
  • 78
  • 120
  • 1
    Can you please substantiate "just queries Windows' Raw Input interface" bit further (wiht a reference perhaps)? – bobobobo Feb 10 '10 at 05:43
3

FYI: Re John Knoeller's answer... a simplistic message pump looks like this:

while (GetMessage(&msg, NULL, 0, 0))
{
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}

The WM_QUIT test that he included can NEVER be true because GetMessage returns zero when a WM_QUIT is received. However, testing for WM_QUIT in a PeekMessage loop is required because PeekMessage returns true/false whether a message was returned or not. Since GetMessage blocks until a message is returned, so it can have a different return value.

1

If the game has a single window, than as far as I can tell the distinction is purely a matter of taste. If however, you have (or are planning to have, or cannot positively rule out the option of having in the future) multiple windows, then windows messaging can get tiresome.

Problem is that by default keyboard/mouse messages are routed only to the window currently in focus, and typically in games you want to be able to switch focus (to a hi-score view, enemies on radar view or whatever) and still maintain interactivity. The easy solution would be for every module which requires keyboard/mouse input to query for it directly, and not rely on message forwarding - hence, DirectInput.

I can't say much about your specific scenario, of course - just my 2c.

Ofek Shilon
  • 11,558
  • 3
  • 52
  • 86
  • 2
    It's not true that keyboard and mouse events go to the focus window. Keyboard events are sent to the focus window _by your message pump_ (that's what DispatchMessage does). Mouse events go to the window under the cursor. – John Knoeller Jan 30 '10 at 00:32
  • Right. Thanks! I originally commented with keyboard only and only then 'fixed' it to keyboard/mouse.. – Ofek Shilon Jan 30 '10 at 22:00
1

Yes, the MSDN post is correct. Using windows messages you can use the multilanguage support (for any kind of keyboard the user may be using)/personal settings of the user (mouse right button instead of left), etc.. that you have to discard away to use DirectInput/XInput. Only use those 2 for the gamepad/joystick support. For the rest just use the windows messages.

For the details i agree with the John Knoeller answer.

feal87
  • 837
  • 1
  • 11
  • 28
0

Use the-only use directinput under special circumstances

The nice thing about the Windows message loop used with getmessage is that it uses 0% cpu usage. If you are doing unprocessor intensive things such as waiting for a key from the user, collecting data from the user such as in a database or a tax program, or even a word processor, it makes sense just to use the Windows message with getmessage. I the all the above programs date is the process when the user presses a key.

All that the Windows message loop needs to process keys is for that program to be switched to. The mouse does not even need to be in the window.

Special circumstances-use directinput

If you need to: 1) Know when a key is pressed and released. You also may not want repeating keys detected as keypresses.
2) Process keys in the background when another program is switched to.

If either of the above is true, then use directinput.

If you're just collecting data from the user, then you will need to use the sleep command to suspend execution of the program. You want the program to have 0% cpu usage in the task manager if the program is just sitting there waiting for keys from the user.

Use the sleep function putting the program to sleep until you want to poll direct input for keys.

Therefore direct input just wastes programming time if you are doing a simple ordinary task of collecting keys from the user as you can see.

rauprog
  • 183
  • 1
  • 8
-1

XInput is definitly the way to go. Low-Latency input is crucial to gameing and XInput ( replacement of DirectInput in the new DirectXSDKs ) is designed for exactly these use-cases.

Further you have support for gamecontrollers, joysticks, etc out of the box.

DarthCoder
  • 272
  • 1
  • 2
  • 1
    DirectInput is not lower latency for keyboard and mouse events. But it does give you a more consistent input model if you later want to support joysticks, etc. – John Knoeller Jan 30 '10 at 00:28
  • You are absolutly right, but what I meant was that DirectInput ( and XInput, which is DInputs successor ) has a lower latency than Windows messages. – DarthCoder Jan 30 '10 at 01:22
  • 1
    But not for keyboard and mouse input. DirectInput is just a wrapper around the Win32 API for keyboard and mouse. – John Knoeller Jan 30 '10 at 03:10
  • That is not true. You are correct for DInput 1.0, as this was a simple wrapper around the win32 input, but since 2.0 DInput talks directly to the driver. The windows messaging system does a preprocessing ofthe input data before it passes it on to the application ( WM_CLICK, WM_DOUBLECLICK, etc ), handles all focus requirements, etc. This is were the latency difference mostly come from. – DarthCoder Jan 30 '10 at 07:53
  • Btw. You can find the citation to my claims in the DirectX SDK Documentation in "Direct X Input -> Direct Input -> Understanding DirectInput" – DarthCoder Jan 30 '10 at 08:02
  • Ain't XInput only for controllers? Asker asks about mouse and keyboard input. I've dropped a look at [MSDN doc] (http://msdn.microsoft.com/en-us/library/windows/desktop/ee417014%28v=vs.85%29.aspx) and DirectX documentation, and xbox controller is only thing mentioned. – Martin Berger Dec 18 '12 at 22:06