In order to exit the loop I have set up a boolean variable that, when set, is used to exit the loop.
Problem is, the loop does not yield to other processes (ie being able to press the "Quit" button, which sets the boolean variable enabling a way to exit the loop).
VB has a DoEvents function which allows other processes to be carried out in a loop such as this.
Since C++ does not have DoEvents I used the following in it's place.
The most straight-forward solution is to run your loop in a separate thread. Otherwise, as you already found out, your program will not "yield" any processor time to handling of other tasks in your program, like clicking on the "Quit" button.
This transforms your message loop into a sort of poor-man's multi-threaded app, except that there's only one thread. To work successfully, however, you will need to ensure that your "continual loop" is actually broken up into iterations, and that only one iteration is run before yielding to the PeekMessage part of the message loop.
Incidentally, I won't tell you why your app is crashing (even though it's fairly evident) because your design is truly "not recommended". See, for example, the comments on PeekMessage in "The n Habits of Highly Defective Windows Applications" at http://www.flounder.com/badprogram.h...age%20anywhere
My project requires a continual loop.
The following code compiles and runs, but crashes with the error
The instruction at "0x00000064" refrenced memort at "0x00000064". The memory could not be "read".
when the Quit button is depressed.
Can anyone spot the problem?
The PeekMessage, DispatchMessage and TranslateMessage functions use MSG type not UINT as parameters. Try this :
Code:
do
{
MSG msg;
while ( PeekMessage (&msg, NULL, 0, 0, PM_REMOVE) )
{
DispatchMessage (&msg);
TranslateMessage (&msg);
}
}
while (bQuit == FALSE);
A.M.
My Latest Articles: CCustomBitmapButton - An owner-draw button and a frame for the caption bar, in one class. CCustomTabCtrl - A clone of the Excel tab sheet control.
I checked out PeekMessage on the ....badprogram... link
I could not understand anything the author was trying to say (except I am breaking every rule in the book)
because his code snippets all use MFC, which I know nothing about.
I also looked at the "game loop" links you provided, and they seem identical to what I am trying to do except
they wrap this "continual loop" around the WinMain message pump.
In my situation I only wanted to activate this loop at a press of a button (and exit it in the same way).
If I still am not understanding what you are trying to say, please respond.
You may also want to check your CPU utilization when running this loop. You might want to put a Sleep in there to yield to other running processes (such as the operating system)...
Code:
do
{
MSG msg;
while ( PeekMessage (&msg, NULL, 0, 0, PM_REMOVE) )
{
DispatchMessage (&msg);
TranslateMessage (&msg);
Sleep(0);
}
}
while (bQuit == FALSE);
Sleep(0) should not be used here. It causes the current thread to yield the remainder of its time-slice to any other thread in the system with a higher current priority. It therefore will do two things here which seem wrong: it will rob your own program of valuable CPU time that it probably needs to complete its own tasks, and it will mask problems caused by incorrect program architecture that improperly over-utilizes the CPU.
The thread scheduler in Windows is smarter than your program about when to stop your program (at the natural end of its timeslice) and to let others run in their timeslice. Let Windows do its job.
@mmscg: To use the "game loop", your "run" button should merely set a global boolean to TRUE, and your "quit" button should set it to false. Then, in the main message loop, test the value of the global and run your "contiual loop" if it's TRUE and don't if it's FALSE.
Removing the sleep prevents the windows task scheduler from doing its job, by forcing this thread to consume almost all of the spare CPU cycles in the machine.
By giving up the remainder of the timeslice, you are permitting window to perform other essential scheduling.
Otherwise in a tight loop, like this...
while(1)
;
This thread will use 100% of the CPU, regardless of its thread priority and other applications will not have their required share of the slices.
In fact I would go as far as saying that without the sleep in his loop, the thread will consume 100% of his CPU, while it is sitting doing (next to) nothing.
DoEvents is a Visual Basic function that yields execution so the operating system can process other events. This function cleans out the message loop and executes any other pending business in the Visual Basic runtime. Upon completing the pending business execution, the function calls the Sleep function with zero (0) as the argument so that the remaining time slice can be used to check the queue.
The Sleep 32-bit API function is a subset of the DoEvents function. The Visual Basic program calling the function and the Visual Basic runtime executable and interactions with Windows are immediately put to sleep by this function. The programs remain inactive for the time in milliseconds specified in the Sleep argument.
The Sleep function allows you to specify the amount of time your applications are inactive. The DoEvents function returns control to the Visual Basic program after the operating system has finished processing the events in its queue and all keys in the SendKeys queue have been sent.
Don't try to use VB concepts in Win32 programming, at least not without understanding the full VB framework. For example, if the text you quoted is referring to the Win32 Slepp() API function, then it makes no sense to say that "the Sleep function [is called] with zero (0) as the argument so that the remaining time slice can be used to check the queue." The Win32 Sleep function immediately yields the time-slice, so that there's nothing left with which to "check the queue". Tis makes me think that the quoted text is referring to some VB wrapper to the Sleep() function, that does some extra work with the VB framework before it calls the actual Win32 Sleep() function.
You need to describe what you want to do in your "continual loop". But again, I strongly recommend against Sleep(0), and you probably will not need it.
@Nigel: I know you disagree, but Sleep(0) is usually a sign of architecture that needs improvement. For example, the programmer does not know why the app is eating 100% CPU time and feels it should not be, but can't figure out any other way to stop it, so he sticks a Sleep(0) (or worse, a Sleep(100)) in it. This would be a bad reason to use Sleep().
One common use of Sleep(0) is in multi-threaded situations, where you need to play some sort of inter-thread "catch up" and you have determined that one thread has done all it can for now, and must wait for another thread to complete processing that the first thread needs. In such a situation, the first thread's continued use of its time-slice is wasteful, since we already know that it can't do anything further; it should therefore yield its time-slice, and Sleep(0) might make sense here. (WaitForSingleObject might make more sense, but each situation should be evaluated on its own.)
Mike
PS: There's almost never a justification for using Sleep(100), or anything above Sleep(0), for the reason that the "100" is usually an arbitrary number that the programmer found experimentally to "get it to work", without fully understanding why it didn't work in the first place. This is guaranteed to fail on someone else's system, at some time in the future.
You need to describe what you want to do in your "continual loop". But again, I strongly recommend against Sleep(0), and you probably will not need it.
I thought I would be able to complete this on my own... I was wrong.
I was continuing with the "double-buffering" for graphics. I could not get the previous one working, so I continued to read up on the subject, thought I understood it, implemented it in VB (works GREAT), and now trying to build it in C++ Win32.
The "continual loop" is there to generate random graphics in the "PictureBox", so that I could watch the effect with double-buffering ON and OFF (I didn't want to use a timer).
I am posting my code. It builds and runs, but NO graphics appears in my "PictureBox".
I tried calling UpdateFrame in the WM_PAINT handler, and InvalidateRect whereI had called UpdateFrame.
This didn't work, and in fact caused strange screen behaviour.
If anyone is able to help, it would be appreciated, as I am becoming very frustrated, that this graphics part is not really sinking-in for me.
always returns zero (ditto GraphicObject[i].y1, GraphicObject[i].x2,GraphicObject[i].y2, etc.)
yet I know MoveGraphicObject is calculating the values correctly because I do a similar test inside that function, and values other than zero are displayed.
Can anyone see, what I am doing incorrectly in this regard?
* The Best Reasons to Target Windows 8
Learn some of the best reasons why you should seriously consider bringing your Android mobile development expertise to bear on the Windows 8 platform.