Hello all,
I was reading through some code accompanying a book recently and came upon a use of PeekMessage() that somewhat confuses me. Hopefully someone can help in clarifying this.
The code is from a small DirectX sample that accompanies Frank Luna's book on DirectX 10 ("Introduction to 3D Game Programming with DirectX 10"). The application uses a class called D3DApp to represent it, whose member is a run() function which is the focus of this question. The relevant code goes like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
|
//in D3DApp.h
class D3DApp
{
public:
int run();
void updateScene();
void drawScene();
protected:
bool mAppPaused; //signifies if App is currently paused
//...
};
//----------------------------
//in D3DApp.cpp
int D3DApp::run()
{
MSG msg = {0};
while(msg.message != WM_QUIT)
{
// If there are Window messages then process them.
if(PeekMessage( &msg, 0, 0, 0, PM_REMOVE ))
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
// Otherwise, do animation/game stuff.
else
{
if( !mAppPaused )
updateScene();
else
Sleep(50);
drawScene();
}
}
return (int)msg.wParam;
}
void D3DApp::updateScene()
{
if(GetAsyncKeyState('W') & 0x8000)
{
//move forward
}
if(GetAsyncKeyState('A') & 0x8000)
{
//move left
}
if(GetAsyncKeyState('S') & 0x8000)
{
//move back
}
if(GetAsyncKeyState('D') & 0x8000)
{
//move right
}
}
| |
(in case anyone wants to see the complete code, it can be found at:
http://www.d3dcoder.net/d3d10.htm)
So, in line 27,
if(PeekMessage())
is used, which is followed by an
else
clause in line 33. The whole code for updating the scene and redrawing it is placed in the
else
block of code. This implies that the scene updates only if there are no messages in the message queue (i.e. PeekMessage() returns
false
).
What confuses me is the use of the "if-else" (in line 27 and 33). I would expect that something like this would be used in this case (note the lack of "else" in line 12):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
int D3DApp::run()
{
MSG msg = {0};
while(msg.message != WM_QUIT)
{
if(PeekMessage( &msg, 0, 0, 0, PM_REMOVE ))
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
// <---- no "else" used
if( !mAppPaused )
updateScene();
else
Sleep(50);
drawScene();
}
return (int)msg.wParam;
}
| |
So, since I'm using the code provided in the sample, if I were to press and hold a key, say "W", I would expect that this generates WM_KEYDOWN messages that do not allow the message queue to remain empty (since I am holding the key down). So, I would suppose that the use of "if-else" in this way prevents the scene from updating.
However, upon compiling and running the sample, if I press and hold "W", the scene updates fine, and I get a continuous forward movement. (This is certainly the desired behavior for the program -- we definitely want the scene to update as we press "W", even if it is held down! The question is -- why does it update since a key is held down?)
So -- what am I missing here? Why is the scene updating even though I hold the key down continuously? This would imply that there are iterations of the loop where the message queue is actually empty, and yet I would expect it to not be so since I am holding down a key continuously.
Any feedback would be greatly appreciated! Thank you very much in advance.
Ogoyant