mguyott@eriador.prime.com (02/22/91)
I would like to use PeekMessage() in a yield loop so that other applications will be able to run while my application is doing some serious number crunching. However, I have one concern and that has to do with the WM_QUIT message. Will PeekMessage() remove a WM_QUIT message from the windows message queue? If it does can I requeue the message? Perhaps via PostMessage()? Thanks in advance for any help. Marc ---- Two of the worst things we teach our children are that a knowledge of science is nice but not necessary, and a knowledge of sex is necessary but not nice. Marc Guyott Constellation Software, Inc. (508) 620-2800 Framingham, Mass. 01701 USA Ext. 3135 mguyott@primerd.prime.com ...!{uunet, decwrl}!primerd.prime.com!mguyott
epperson@adobe.COM (Mark Epperson) (02/22/91)
In article <149000004@eriador> mguyott@eriador.prime.com writes: > >I would like to use PeekMessage() in a yield loop so that other applications >will be able to run while my application is doing some serious number >crunching. However, I have one concern and that has to do with the >WM_QUIT message. Will PeekMessage() remove a WM_QUIT message from the >windows message queue? If it does can I requeue the message? Perhaps >via PostMessage()? Thanks in advance for any help. Marc >---- >Two of the worst things we teach our children are that a knowledge of science >is nice but not necessary, and a knowledge of sex is necessary but not nice. > >Marc Guyott Constellation Software, Inc. (508) 620-2800 > Framingham, Mass. 01701 USA Ext. 3135 >mguyott@primerd.prime.com ...!{uunet, decwrl}!primerd.prime.com!mguyott Here is a tried and true way to make sure that you yield properly: -------- C U T H E R E ------------------------------------------ /* This is based on information which is not generally available. Neither PeekMessage() nor Yield() will yield if there is a message in the applications queue. So... GetInputState() (which is 3X faster than PeekMessage()) is used to see if there are any mouse, keyboard or, timer input records which will result in message being put into your queue. If this is false the Yield() will probably work and is thus called, otherwise PeekMessage() is called with the NO_YIELD flag to get the next message without yielding excessively and that message is then dispatched. After all messages have been removed then Yield() is called. GetInputState() will fail if the input focus changes so...we enter the PeekMessage() loop every 16th time to handle this eventuality. NOTE: This routine will allow your program to have multiple threads so make sure the approiate controls are disabled or your WinProcs take this into consideration. */ void AplYield() { static int delay = 0; MSG msg; LPMSG lpMsg; if (!(delay++ & 0xf) || GetInputState()) { lpMsg = &msg; while (PeekMessage(lpMsg, NULL, 0, 0, PM_REMOVE|PM_NO_YIELD)) { TranslateMessage(lpMsg); DispatchMessage(lpMsg); } } Yield(); }
mguyott@eriador.prime.com (02/27/91)
For those who are interested ... Here are some additional responses I received via email regarding the problem I was experiencing with PeekMessage(). My thanks to everyone who responded! You're help is greatly appreciated. Marc My original question was: >I would like to use PeekMessage() in a yield loop so that other applications >will be able to run while my application is doing some serious number >crunching. However, I have one concern and that has to do with the >WM_QUIT message. Will PeekMessage() remove a WM_QUIT message from the >windows message queue? If it does can I requeue the message? Perhaps >via PostMessage()? ---- Two of the worst things we teach our children are that a knowledge of science is nice but not necessary, and a knowledge of sex is necessary but not nice. Marc Guyott Constellation Software, Inc. (508) 620-2800 Framingham, Mass. 01701 USA Ext. 3135 mguyott@primerd.prime.com ...!{uunet, decwrl}!primerd.prime.com!mguyott ---- Subject: Re: PeekMessage() loop. From: rafetmad@oxy.edu (David Ronald Giller) To: mguyott@eriador.Prime.COM Organization: Occidental College, Los Angeles, CA 90041 I use a PeekMessage() loop in one of my programs as the main loop, without any problems. Here is the loop section: // Main Message Loop:---------------------------------------------------------- while (TRUE) { if (PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE)) { if (msg.message == WM_QUIT) // WM_QUIT not checked as special case, break; // must check explicitly TranslateMessage(&msg); // Translates virtual key codes DispatchMessage(&msg); // Dispatches message to appropriate window } else { CheckPlayingSong(hWnd); } } return (msg.wParam); // Return the value from PostQuitMessage //----------------------------------------------------------------------------- This works (or seems to :-) exactly the same as a GetMessage() loop with the exception that whenever there is free CPU time, the function CheckPlayingSong() is performed. I BELIEVE that this is the only way to do this. Hope this helps. -Dave David Giller ----- (rafetmad@oxy.edu) or (dgiller@oxy.edu) ------------ Box 134 "Some of us wake up -- others roll over." Occidental College "It's easy to deceive a child." -- John Lydon Los Angeles, CA 90041 ---- Subject: Re: PeekMessage() loop. From: David Ronald Giller <rafetmad%oxy.edu@RELAY.CS.NET> Organization: Occidental College, Los Angeles, CA 90041 I don't think you will have to worry too much about the problem with WM_QUIT (although I could be wrong... I'm no expert!) because of this: Your MainWndProc is always reentrant. That means, if you are processing some information, and the user wants to exit, and you recieve the WM_QUIT in the middle of your data- processing-free-time-via-PeekMessage()-loop (knowatimean?) you can simply kill that 'process' by terminating the app with a processing of the WM_QUIT. Here's a better explanation. If you use the SendMessage() function, your MainWndProc will be stopped where it is, and re-entered (if you sent yourself a message) with the message you sent. This could be useful if you, say, had both a menu item and a control to perform a certain task. The menuitem condition would take care of the actual work. When you push the button, you might want to show some indicator of what is going on, like setting some static field on the screen, then performing the action, then setting the indicator back. well, you would do this by setting the indicator, calling a SendMessage(hThisWnd, WM_COMMAND, IDM_WHATEVERTHEACTIONIS, wParam, lParam), then setting the indicator back. If you need to finish the computation you are doing, you could set a flag during the loop where the PeekMessage occurs, then at the end of your process, send yourself a WM_QUIT. if you just post one in the PeekMessage section, you may find yourself with infinite loop problems. -Good luck, and I hope this helps you. -Dave David Giller ----- (rafetmad@oxy.edu) or (dgiller@oxy.edu) ------------ Box 134 "Some of us wake up -- others roll over." Occidental College "It's easy to deceive a child." -- John Lydon Los Angeles, CA 90041 ----
srw@cci632.cci.com (Steve Windsor) (05/18/91)
Ok all, here is the program segment that Paul Yao gave us in the Windows Applications Programming (Windows AP) Class. To break up long processing chunks, use PeekMessage(), which was originally implemented for the Windows spooler. This segment is intended to replace the GetMessage()...DispatchMessage() code segment in your main message loop: While ( TRUE ) { if ( ( PeekMessage( ,,,, PM_REMOVE ) ) /* Non zero indicates message */ { if ( msg.message == WM_QUIT ) break; TranslateMessage(); DispatchMessage(); } else /* zero, no message waiting */ { // do other work, another process, etc... // PeekMessage() implicitly tells Windows not to idle us if // there are no messages waiting, so it allows // us to do context switching. // An example is in the SDK sample code under // \WINDEV\EXAMPLES\TTY\TTY.C. } } /* end while */ Note I have not checked out the sample program, nor have i tried this segment of code, but it looks ok to me. If someone tries it, let me know. The PM_REMOVE switch in PeekMessage() removes the message from the queue AFTER processing by PeekMessage(). This will either help, or create more confusion. stephen windsor srw@op632.cci.com if PeekMessage( lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg )