Should I use DirectInput or Windows message loop?
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 log开发者_C百科ic), I call the Draw and the Update methods inside a windows message loop.Thanks
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.
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.
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.
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.
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.
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.
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.
精彩评论