written by: lore
email: lore at newty dot de
home: www.newty.de
last updated: 25.07.00
Thread-Control dialog with progress-gauge/texts, cancel/bkgnd-buttons and timer-powered callback of a user-specified function. The dialog can be used modal or non-modal.
The thread-control dialog is used to control an additional thread. You start your thread-function and supply a pointer to an instance of this class in the argument list. In your thread-function you call setStopFlag(bool* flag) and supply the pointer to a flag. This flag is set when the user chooses to stop the thread. So you have got to check this flag periodically in your thread-function. Call shutDown() as the last statement in your thread-function.
Note: ALL actions with the dialog, including the try to close it, only result in setting the stop-flag. The dialog is always closed using shutDown()!.
You can execute the dialog modal or none modal with or without the buttons cancel and background. If executed modal, the button cancel and the x in the titlebar (close window) result in
Annotation: There is no sense in executing the dialog none modal with buttons :-)
You supply the pointer to a callback function and its argument list using
You supply a stop-flag using
If the user hits the x is the titlebar this action results in the same actions as heīd pressed the cancel-button, i.g. the stop-flag is set but the dialog is not closed. The user is informed with a messagebox if no stop flag exists.
You can set the status texts of the dialog using
The button background can be disabled calling:
The following code is an excerpt from the projectīs file main.cpp and shows how to execute some calculation in an additional thread using the thread-control dialog to control execution. There are three functions:
Now, how does it work: First we new an instance of TThreadCtrlDlg, set itīs text-field(s) and supply the pointer to the callback-function. Then we start a new thread using
/****************************************************/ // // usage of thread-control-dialog TThreadCtrlDlg // #include <process.h> // due to: _beginthread() #include "threadCtrlDlg.h" //////////////////////////////////////////////////////////////////////////////////////// // function which is to be called by the thread-control dialog periodically void dispState(void* _dialog) { TThreadCtrlDlg* dialog = (TThreadCtrlDlg*) _dialog; // explicit typecast dialog->setGauge(dialog->progress); // just set the gauge } //////////////////////////////////////////////////////////////////////////////////////// // thread-function: this functions contains the code you want to be executed in an // additional thread. void threadFunc(void* _dialog) { TThreadCtrlDlg* dialog = (TThreadCtrlDlg*) _dialog; // explicit typecast // pass a pointer to the stop-flag to the dialog bool stop=false; dialog->setStopFlag(&stop); // calculate something - note: this loops runs 100 times do { Sleep(100); // calculation is emulated by a sleep-command which stops the thread for 0.1s dialog->progress++; // increment progress-counter if(stop) // check stop-flag and if true: immediately leave the loop break; } while(dialog->progress<100); // end dialog and exit the thread by exiting the function dialog->shutDown(); } /***********************************************************************************************************/ // function shows how to execute threadFunc() in an additional thread. void mainWnd::CmThreadDemo() { // I. example how to execute modal // a) instantiate a thread-control dialog with buttons TThreadCtrlDlg* pCtrlDlg = new TThreadCtrlDlg(this, "testing thread-control dialog", IDD_DIALOG, font, true); // b) set first text-field and callback-function pCtrlDlg->setText1("performing modal"); pCtrlDlg->setCallbackFunc(dispState, (void*) pCtrlDlg, /* call every 0.25 seconds = */250); // c) start additional thread using _beginthread(): the function 'threadFunc' will be called and the pointer // 'pCtrlDlg' will be passed to it as a void-pointer. _beginthread(/*pointer to thread-function*/threadFunc, 4096, /*pointer to argument-list*/void*) pCtrlDlg); // d) execute thread-control dialog modal. note: the additional thread is already running at this moment int returnValue=pCtrlDlg->Execute(); int actualState=pCtrlDlg->progress; // remember dialogīs state for eventual later use // e) delete thread-control dialog delete pCtrlDlg; // II. example how to execute none-modal - note: this code is executed if the user hits the 'background'-button // during the modal execution in I. if(returnValue==ID_BKGND) { // a) instantiate a thread-control dialog without buttons // IMPORTANT: do not use the dialog twice! it is not implemented for this kind of use. you would cause // a lot of problems otherwise: one prob is, that the Execute()-function is left before(!) // the function ShutDown() is left in your additional thread. thus you may come up to this // point here while there is still some code executed in your additional thread. TThreadCtrlDlg* pCtrlDlg = new TThreadCtrlDlg(this, "testing thread-control dialog", IDD_DIALOG, font); // b) set first and second text-field and set callback-function pCtrlDlg->setText1("performing in the background ..."); pCtrlDlg->setText2("... and without any buttons"); pCtrlDlg->setCallbackFunc(dispState, (void*) pCtrlDlg, /* call every 0.25 seconds = */250); // c) start additional thread - note: the same thread-function is used as for modal execution. _beginthread(threadFunc, 4096, (void*) pCtrlDlg); // d) set flag, actual state (progress) and create dialog-window pCtrlDlg->SetFlag(wfDeleteOnClose); // dialog will be deleted when it is closed pCtrlDlg->progress=actualState; pCtrlDlg->Create(); } }Download Example Project