Thread: PeekMessage

  1. #1
    Registered User xds4lx's Avatar
    Join Date
    Nov 2001
    Posts
    630

    PeekMessage

    Ok, I had my program working fine, and changed to main message loop to use PeekMessage so I can have a faster loop to render my gl scene. I copied the message loop from a program on a cd and now when I exit the program its process is still active. I found this problem goes away if I change the second parameter (the windows handle) to NULL, but if its hWnd the process is still active. But the example program doesnt use NULL and it exits fine.
    "only two things are infinite, the universe and human stupidity, and im not sure about the former." - albert einstein

  2. #2
    Registered User xds4lx's Avatar
    Join Date
    Nov 2001
    Posts
    630
    Actually I was wrong, it still is happening. If needed I can upload the code.
    "only two things are infinite, the universe and human stupidity, and im not sure about the former." - albert einstein

  3. #3
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    You using PM_REMOVE?

    Checking explicitly for WM_QUIT if PeekMessage() returns TRUE?

    Know that GetMessage() does not return until it gets a message, where PeekMessage() returns after it checks, regardless of wether there was a message. PeekMessage() returns FALSE if there is no message. GetMessage() only returns FALSE if there is a WM_QUIT. If there are no messages GetMesage() will sleep your app until one arrives.
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  4. #4
    Registered User xds4lx's Avatar
    Join Date
    Nov 2001
    Posts
    630
    Yes i know this, heres the message loop:
    Code:
    BOOL bRet = FALSE;
    
    while(!bRet)
    {	::PeekMessage(&msg, hWnd, NULL, NULL,PM_REMOVE);
    	if(msg.message == WM_QUIT)
    	{	bRet = TRUE;			
    	}
    	else
    	{	glWin.Render();
    		TranslateMessage(&msg);
    		DispatchMessage(&msg);		
    	}
    }
    I can post even more if need be.
    "only two things are infinite, the universe and human stupidity, and im not sure about the former." - albert einstein

  5. #5
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    hi xds4lx,

    Just had a quick look at msdn for PeekMessage (aug2001 psdk) which has the following example:
    Code:
    HWND hwnd; 
    BOOL fDone; 
    MSG msg; 
     
    // Begin the operation and continue until it is complete 
    // or until the user clicks the mouse or presses a key. 
     
    fDone = FALSE; 
    while (!fDone) 
    { 
        fDone = DoLengthyOperation(); // application-defined function 
     
        // Remove any messages that may be in the queue. If the 
        // queue contains any mouse or keyboard 
        // messages, end the operation. 
     
        while (PeekMessage(&msg, hwnd,  0, 0, PM_REMOVE)) 
        { 
            switch(msg.message) 
            { 
                case WM_LBUTTONDOWN: 
                case WM_RBUTTONDOWN: 
                case WM_KEYDOWN: 
                    // 
                    // Perform any required cleanup. 
                    // 
                    fDone = TRUE; 
            } 
        } 
    }
    Note that 2nd param of PeekMessage is the window handle. Note also that message handling is done in place. This code will quit normally and completely (ie no residual process) when any of the conditions are met ie mouse click/keypress.

    If instead a more usual TranslateMessage-DispatchMessage mechanism is employed the window is killed but the process remains. Obviously when the 2nd param of PeekMessage is NULL no problems are encountered when quitting.

    Don't ask my why - I just noticed it myself and wondered if it may help with your own problem.
    CProgramming FAQ
    Caution: this person may be a carrier of the misinformation virus.

  6. #6
    Registered User xds4lx's Avatar
    Join Date
    Nov 2001
    Posts
    630
    Ken, thats great info but the example GL app i looked at for reference using the TranslateMessage/DispatchMessage and it exits the process fine. So I think this is feasable.
    "only two things are infinite, the universe and human stupidity, and im not sure about the former." - albert einstein

  7. #7
    Registered User xds4lx's Avatar
    Join Date
    Nov 2001
    Posts
    630
    Found a solution! If I processed the WM_DESTROY message then the application wouldnt end the process. So i just moved the code to WM_CLOSE.

    Heres the old that caused the problem:
    Code:
    case WM_CLOSE:
    {	if(::MessageBox(hWnd,"Sure you want to Quit?","Close?", MB_YESNO | MB_ICONEXCLAMATION) == IDYES)
    	{	::DestroyWindow(hWnd);
    	}
    	return(0);
    }
    case WM_DESTROY:
    {	::PostQuitMessage(0);
    	return(0);
    }
    and the working version:
    Code:
    case WM_CLOSE:
    {	if(::MessageBox(hWnd,"Sure you want to Quit?","Close?", MB_YESNO | MB_ICONEXCLAMATION) == IDYES)
                    {	::PostQuitMessage(0);
                     }
    	return(0);
    }
    Last edited by xds4lx; 08-26-2002 at 10:57 PM.
    "only two things are infinite, the universe and human stupidity, and im not sure about the former." - albert einstein

  8. #8
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    Ah! Happy, smiling code - that's what I like to see.

    Great work, xds4lx. I just tried it too and it works just great. Thanks for that.

    Now all you need to do is explain why it requires WM_CLOSE and not WM_DESTROY, although I suppose there will be an obscure 10+ year old msdn article that explains this.
    CProgramming FAQ
    Caution: this person may be a carrier of the misinformation virus.

  9. #9
    Registered User xds4lx's Avatar
    Join Date
    Nov 2001
    Posts
    630
    Im now wondering what is sent first WM_CLOSE or WM_DESTROY? and isnt WM_DESTROY sent in response to a call to DestroyWindow(...)? If so then why would calling DestroyWindow from WM_CLOSE cause this? It sure as hell didnt when I was using GetMessage
    "only two things are infinite, the universe and human stupidity, and im not sure about the former." - albert einstein

  10. #10
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    That's the interesting thing, default behaviour for WM_CLOSE is to call DestroyWindow, so WM_DESTROY comes after WM_CLOSE (presumably).

    It maybe has something to do with the GetMessage waiting for a msg while PeekMessage returns regardless as described earlier by Novacain.

    edit: I wonder if posting/sending the WM_DESTROY from WM_CLOSE would work? (probably need to send a WM_NCDESTROY if you have borders and caption).

    edit2: SendMessage(hwnd,WM_DESTROY,0,0); works fine.

    edit3: msdn for DestroyWindow says: "...flushes the thread message queue...". Perhaps because GetMessage waits for messages it's a problem that only shows itself when using PeekMessage?
    Last edited by Ken Fitlike; 08-26-2002 at 09:15 PM.
    CProgramming FAQ
    Caution: this person may be a carrier of the misinformation virus.

  11. #11
    Registered User xds4lx's Avatar
    Join Date
    Nov 2001
    Posts
    630
    Is there anything that DestroyWindow does other than post a WM_DESTROY message?
    "only two things are infinite, the universe and human stupidity, and im not sure about the former." - albert einstein

  12. #12
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    from msdn for DestroyWindow:
    The DestroyWindow function destroys the specified window. The function sends WM_DESTROY and WM_NCDESTROY messages to the window to deactivate it and remove the keyboard focus from it. The function also destroys the window's menu, flushes the thread message queue, destroys timers, removes clipboard ownership, and breaks the clipboard viewer chain (if the window is at the top of the viewer chain).

    If the specified window is a parent or owner window, DestroyWindow automatically destroys the associated child or owned windows when it destroys the parent or owner window. The function first destroys child or owned windows, and then it destroys the parent or owner window.

    DestroyWindow also destroys modeless dialog boxes created by the CreateDialog function.
    Short answer - yes.

    See my previous post edits 1,2 & 3.
    CProgramming FAQ
    Caution: this person may be a carrier of the misinformation virus.

  13. #13
    Registered User xds4lx's Avatar
    Join Date
    Nov 2001
    Posts
    630
    Hmm, well the problem also goes away if you return DefWindowProc from WM_DESTROY.
    Code:
    case WM_CLOSE:
    {	if(::MessageBox(hWnd,"Sure you want to Quit?","Close?", MB_YESNO | MB_ICONEXCLAMATION) == IDYES)
    	{	::DestroyWindow(hWnd);
    	}
    	return(0);
    }
    case WM_DESTROY:
    {	PostQuitMessage(0);
    	return(DefWindowProc(hWnd,Msg,wParam,lParam));
    }
    EDIT: This works but the process seems to hang around for a sec or two before dying. Where as the first fix I found exited right away.
    "only two things are infinite, the universe and human stupidity, and im not sure about the former." - albert einstein

  14. #14
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    The PostQuitMessage() sends the WM_QUIT. If you send a DestroyWindow() and it clears the msg que before PeekMessage() gets the WM_QUIT then your app will hang.

    Should be WM_CLOSE calls DestroyWindow() which sends a WM_DESTROY msg.
    WM_DESTROY then calls PostQuitMessage() which will send a WM_QUIT to a now empty msg que.
    PeekMessage() gets WM_QUIT and exits.

    Using 'NULL' instead of 'hWnd' as the second param of the PeekMessage() will get any msg's from children of the main window as well (hWnd will only get the main windows msg's).
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. windowproc vs. peekmessage
    By CuLtOfGoAt in forum Windows Programming
    Replies: 4
    Last Post: 06-04-2005, 02:32 PM
  2. PeekMessage Windows XP
    By wgdb198 in forum C++ Programming
    Replies: 6
    Last Post: 02-12-2005, 07:46 AM
  3. PeekMessage function
    By Micko in forum Windows Programming
    Replies: 9
    Last Post: 09-14-2004, 03:06 PM
  4. 100%cpu usage with PeekMessage
    By glUser3f in forum Windows Programming
    Replies: 6
    Last Post: 08-19-2003, 06:56 AM
  5. PeekMessage
    By Garfield in forum Windows Programming
    Replies: 9
    Last Post: 12-16-2001, 01:52 PM