Archived

This topic is now archived and is closed to further replies.

Crawl

Weird message problem under XP

Recommended Posts

Crawl    136
I've been working on a 3d engine under Win98 for some time now and everything works fine,....but i couldn´t get it to work under WinXP, i ignored the problem for a while but today i decided to fix it. I found out the problem was my message pump,....
        
    BOOL bGotMsg;
    MSG msg;
    msg.message = WM_NULL;
    PeekMessage( &msg, NULL, 0U, 0U, PM_NOREMOVE );

    while( WM_QUIT != msg.message  )
    {
        bGotMsg = PeekMessage( &msg, NULL, 0U, 0U, PM_NOREMOVE );
        if( bGotMsg )
        {
            GetMessage( &msg, m_hWnd, 0, 0 );
            TranslateMessage( &msg );
            DispatchMessage( &msg );
        }
        else
        if ( m_bReady )
        {
             // Render frame here

        }
    }
  
I replaced it with this one ("borrowed" from one of NeHe's tutorials)
    
	MSG	msg;
	BOOL	done=FALSE;

	while(!done)
	{
		if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
		{
			if (msg.message==WM_QUIT)
			{
				done=TRUE;
			}
			else
			{
				TranslateMessage(&msg);
				DispatchMessage(&msg);
			}
		}
		else
                if ( m_bReady )
                {
                    // Render frame here

                }
	}
        
Everything works fine now,..... My question is why does the first one refuse to work under XP ????? -Crawl [edited by - Crawl on June 8, 2002 9:41:21 AM]

Share this post


Link to post
Share on other sites
Crawl    136
No errors, but it seemed that it wasn''t recieving any messages. You had to ctrl-alt-del yourself out of the application. It''s weird that it works under win98 but not under winXP....

Share this post


Link to post
Share on other sites
Dirge    300
Hehe, it''s funny, I did the same thing (minus using someone elses code). What you forgot to do my friend is tell windows that you got the message, so please remove it from the message queue.

See, you use this twice, right?

PeekMessage( &msg, NULL, 0U, 0U, PM_NOREMOVE );

The first time is correct, you say, "hey windows, you got any messages, I''m looking for quit, but I''ll take what you got".

This is just a formality in case the user quits out of the app really really quick. You don''t need it, but it is correct to have it. But here is where the problem is. You do this:

bGotMsg = PeekMessage( &msg, NULL, 0U, 0U, PM_NOREMOVE );

As Puzzler183 pointed out, yeah, you don''t need the BOOL, you could do this:

if( PeekMessage( &msg, NULL, 0U, 0U, PM_NOREMOVE )
{}

But thats pointeless, do you see it now though?
SOLUTION:
PM_NOREMOVE!?!?!? You forgot to remove it!!!! You will always keep getting the same exact message over and over! Hehe, I kicked myself in the butt the first time I did this. Just replace the second PeekMessage() argument number 5 with PM_REMOVE. And get rid of all the 0U nonsense. Just use 0! What does the U cast the zero to anyways? Good coding!


Share this post


Link to post
Share on other sites
I use PM_NOREMOVE, but I also use DispatchMessage(), which probably removes the message from the queue. I don''t know what else it does, if it it''s necessary using this function, but this is my code (works with WinXP and Win95/98):


  
while(1)
{
if( Running )
MainLoop( );
else
WaitMessage( );

if( PeekMessage( &Message, NULL, 0, 0, PM_NOREMOVE ) )
{
if( !GetMessage( &Message, NULL, 0, 0 ) )
return Message.wParam;

DispatchMessage( &Message );
}
}


~CGameProgrammer( );

Share this post


Link to post
Share on other sites
Crawl    136
quote:
Original post by Dirge
I did the same thing (minus using someone elses code).


I just grabbed the first *good* message pump/loop i could find....

quote:
Original post by Dirge
SOLUTION:
PM_NOREMOVE!?!?!? You forgot to remove it!!!! You will always keep getting the same exact message over and over! Hehe, I kicked myself in the butt the first time I did this. Just replace the second PeekMessage() argument number 5 with PM_REMOVE.

The GetMessage() call removes the message. And it worked fine under Win98....

btw: It's code that i have been using a long time in my base code.......

quote:
Original post by Dirge
Good coding!


Sarcasm ????


[edited by - Crawl on June 9, 2002 7:17:44 AM]

Share this post


Link to post
Share on other sites
Dirge    300
Good coding? It''s just what I say. Like, have a good day. :-)

Here is what I use in my generic framework:


  
MSG msg;
// Peek the first message.

PeekMessage( &msg, NULL, 0U, 0U, PM_NOREMOVE );

// While the Message is not to quit, process messages.

while ( msg.message != WM_QUIT )
{
// Peek at the new message, but remove it from the queue. If we got a

// windows message, process it...

if ( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
// otherwise spend the Idle time processing the scene.

else
{
// Move the current frame.

FrameMove();
}
}


Checkout MSDN for all the info about TranslateMessage(), DispatchMessage(), and PeekMessage(). I believe GetMessage is able to remove things from the Queue but I use PeekMessage with the flag set to PM_REMOVE. This makes it so the program doesn''t sit there waiting for a windows message. Check it out:
"Unlike GetMessage, the PeekMessage function does not wait for a message to be posted before returning."
Which means windows sits there waiting for a message! That might be why it''s not working. It waiting to resize the screen or something stupid like that instead of continuing the message loop.

I won''t copy and paste the whole description (there lots more but here:
"The TranslateMessage function translates virtual-key messages into character messages. The character messages are posted to the calling thread''s message queue, to be read the next time the thread calls the GetMessage or PeekMessage function."
*and*
"The DispatchMessage function dispatches a message to a window procedure. It is typically used to dispatch a message retrieved by the GetMessage function."

Doesn''t say much. I have NO idea why your program would work that way if you never empty a message off the queue (Win2k and XP are much more anal about certain things, win98 just goes for it. Reason why it tends to crash so much more). My only guess is that you keep pushing new messages into the queue so that it always has a new one to process and the old ones go to the back of the queue. Beats me.

I didn''t mean any disrespect btw, sorry if I came out that way, just wanna help.

Share this post


Link to post
Share on other sites
GetMessage does not literally wait for any messages to come, that''s what WaitMessage does. PeekMessage returns true if a message is received, and if one was, then the first parameter is filled with the message info. That''s why you say "if( PeekMessage() )" because you only handle a message if PeekMessage finds that there is one.

I think the MSDN help is saying that GetMessage waits for confirmation that an application received and handled a message, before returning. Keep in mind I use GetMessage() and WinXP and my code works.

~CGameProgrammer( );

Share this post


Link to post
Share on other sites
cgoat    132
It could be the fact that you''re passing NULL as the hWnd for PeekMessage, then passing m_hWnd as the hWnd for GetMessage.

I bet if you changed the GetMessage to match the PeekMessage it would work fine.

Share this post


Link to post
Share on other sites