Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How to interrupt a do while loop 1

Status
Not open for further replies.

RichBrowne

Programmer
Jun 28, 2002
4
US
I use a do..while loop to read and display time left in a minute-long process. When time=0, I exit. I need to program a pause button which interrupts the loop. I need something equivalent to the VB DoEvents process to allow loop to be interrupted.
 
To get the best results, you need to look at creating the loop in a separate thread. You would pass into the thread a pointer to a structure containing the relevant details required to process the loop along with some kind of flag to terminate/suspend/resume the loop if the user hits a button. Don't forget to include a call to the [tt]Sleep()[/tt] function within the loop, even if it's sleeping for 1 millisecond at a time.

If you don't have any idea how to go about this then let me know and I'll post some sample code.

:)
tellis.gif

programmer (prog'ram'er), n A hot-headed, anorak wearing, pimple-faced computer geek.
 
It can be done even easier:
Use the WaitForSingleObject in your loop to wait for an event you set when you hit the button.
Greetings,
Rick
 
This is a condensed version of what I'm doing now. If I understand you correctly, I need to put this entire code in a thread, and this will allow me to handle button clicks while the playback is progressing. And, yes, I would appreciate sample code. Threads are something I've heard of but never used. Thanks.


//This starts playback on a GVG Profile video server
if (! VdrShuttle(vdrHandle, SHUTTLE_RATE)) {
//Display error & exit
return(FALSE);
}
/* Wait while movie plays. When newpos and oldpos are the same, we've finished playing out.*/
newpos = 0;
do {
oldpos = newpos;
Sleep(100); /* wait 1/10th second */
newpos = VdrGetPosition(vdrHandle );
//newpos is amount of clip that has played
//expressed in video frames
} while (newpos > oldpos);

//When finished playing, put system in idle
if (!VdrIdle(vdrHandle)) {
//Display error & exit
return(FALSE);
}






 
Rick (LazyMe)
I'm sorry, I'm a VB programmer forced to use C++ to be able to utilize the manufacturer's SDL to control a Video Server.

I need to program a "Pause" button to stop the playback loop. Could you please post some sample code that uses the WaitForSingleObject function to check for a button click? Thanks.
Rich
 
WaitForSingleObject() may be a quick fix but any program and future projects that uses such processing will always benefit from using multiple threads. It really doesn't take that much to implement a separate thread and, once done, the results are well worth the effort.

[tt]
// First, create some kind of structure to control
// and prime your thread. As a simple example, this
// will be some kind of progress bar which increments
// the bar by 5% every half second

struct MyThreadStruct
{
unsigned progAmt;
bool abort;
};

// To create a thread using MFC (which I'm assuming
// you are) you need to have a CWinThread* member in
// your class that you'll be spawning the thread from.
// For example, suppose you'll be wanting to spawn
// your thread from a dialog box, you will probably
// have your dialog's class with the CWinThread* member
// and controlling structure in it like so:

class MyDialogClass : public CDialog
{
...... // <- usual stuff here

public:
static UINT MyThreadFunction(LPVOID);

CWinThread* mThread;
MyThreadStruct mControl;
};


// This function is the one that the thread runs in
// it takes an LPVOID parameter so you can more or
// less pass anything in - this is usually some kind
// of structure which will contain all the details
// that the tread needs to run
// This function can either be global or a static
// member function of a class

UINT MyDialogClass::MyThreadFunction(LPVOID param)
{
MyThreadStruct* info = (MyThreadStruct*)param;

while (!info->abort && progAmt<100)
{
// paint the progress bar using
// info->progAmt as the amount


info->progAmt += 5; // increment by 5%
::Sleep(500) // sleep for half second
}

return (0);
}


// Now when it comes to spawning your thread, you'll
// use the ::AfxBeginThread() function and pass in the
// name of your thread processing function and the
// address of whatever structure you created to prime
// and control the thread.
// So, somewhere in your dialog's class code you need
// to spawn the thread and kick it off running.
// Perhaps this can be done when the user clicks a
// button or something!

void MyDialogClass::OnClickStartButton()
{
// first prime the controlling structure
mControl.abort = false;
mControl.progAmt = 0;

// spawn the thread and begin running it
mThread = ::AfxBeginThread(
MyDialogClass::MyThreadFunction,
(LPVOID)&mControl);
}


// Now suppose you dialog has a button for suspending
// and resuming the thread. You can use the functions
// SuspendThread() and ResumeThread() to pause and
// resume it.

void MyDialogClass::OnClickPauseButton()
{
// pause the thread but do not kill it
mThread->SuspendThread();
}

// If you want to stop the thread altogether...
void MyDialogClass::OnClickStopButton()
{
mControl->abort = true;
}[/tt]
tellis.gif

programmer (prog'ram'er), n A hot-headed, anorak wearing, pimple-faced computer geek.
 
The movie is already playing in a separate thread. It seems to me that the only thing that needs to be done is waiting fot the movie to have been finished, isn't it? This means that the main thread won't have anything else to do when the movie plays, am I right? Starting a second thread is always better when doing some lenghty background process, but it seems to me that this is not a background process, since the main thread has nothing else to do but waiting....

If this is NOT the case use the code gednick supplied (although he uses MFC, if you're not using MFC better go straight into the CreateThread API, which is very similair).

If you're not interested in creating a second thread:
Look at the CreateEvent / SetEvent / WaitForSingleObject functions in the MSDN. Use CreateEvent to create an event an obtain the handle to it. Use SetEvent in your button-click handler. Use WaitForSingleObject to monitor the event (timeout of some milliseconds).
Greetings,
Rick
 
Rick,
Actually, the movie is running on a remote Grass Valley Profile server. I'm sending commands to the server via a TCP/IP connection. While I'm in the loop waiting for the movie to finish, my app is totally locked up. It won't respond to button clicks or anything. So, it's not running in a thread, and I think the threading approach is the way to go.

Another way that might work (that occurred to me after I posted) was to get rid of the loop and put the newpos = VdrGetPosition(vdrHandle) code in a timer that fires every 0.1 sec. That way, the app will know when the movie finishes, but it should also respond to key strokes while the movie is playing, and I can pause, end, etc. at will.

In any event, Rick & gednick, thanks for your postings. Very educational and a big help!
Rich
 
It is running in a thread, but the do-while loop does not provide for any user interaction (it locks up the system). WaitForSingleObject ensures that the thread is temporarely consuming no resources (almost no). This should provide the system the oppurtunity to send the message......
Greetings,
Rick
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top