Oh, Joseph, thank you so much for such a thorough answer. I'll start
detailed reading of it right away. I've found in Code Project some
like what I need. But the problem is (as I figure, may be I'm wrong)
class. This member function uses all kinds of variables and other
"Universal Progress Dialog". So I'll read you answer in detail and
hope it'll help me.
On Nov 24, 1:11 pm, Joseph M. Newcomer <newco...@flounder.com> wrote:
The easiest way to do this is to do the lenghty computation in a separate thread. See my
essay on worker threads on my MVP Tips site.
If you are programming in MFC, there is no option to "enable multiple thread support"
because it is ALWAYS enabled, ALL the time, for EVERY project. The only special case is a
console project, where you have to instruct the compiler to use the multithreaded
libraries (which should not exist, since they serve no known purpose these days).
class CMyWhatever : public ... {
... stuff
protected:
volatile BOOL stopper; // set to FALSE in constructor
CCancelDialog * canceller; // set to NULL in constructor
void CMyWhatever::OnBnClickedDoIt()
{
stopper = FALSE;
AfxBeginThread(worker, this);
canceller = new CCancelDialog;
canceller->Create(CCancelDialog::IDD, this);
updateControls(); // for dialog-based apps
}
UINT CMyWhatever::OnCancelRequest(WPARAM, LPARAM)
{
canceller->DestroyWindow();
stopper = TRUE;
return 0;
}
void CCancelDialog::OnCancel()
{
}
void CCancelDialog::OnOK()
{
}
void CCancelDialog::OnClose()
{
}
void CCancelDialog::OnBnClickedCancel()
{
GetParent()->SendMessage(UWM_MY_CANCEL_REQUEST);
}
Note that you really want to add the virtual handlers OnCancel, OnOK and OnClose and have
empty bodies. Throw away both the OK and Cancel buttons, create a new one called
IDC_CANCEL or some other name *other* than IDCANCEL, and add a handler as shown.
In CMyWhatever you will add the following handler to the class declaration
afx_msg LRESULT OnCancelRequest(WPARAM, LPARAM);
and in the message map you will add
ON_REGISTERED_MESSAGE(UWM_MY_CANCEL_REQUEST, OnCancelRequest)
(note that I'm using my preference of a registered window message; if you use a WM_APP
message, it would be ON_MESSAGE)
/* static */ UINT CMyWhatever::worker(LPVOID p)
{
CMyWhatever * me = (CMyWhatever *)p;
me->RunMyThread();
return 0;
}
void CMyWhatever::RunMyThread()
{
while(!stopper)
{
...my thread thing, keep looping after some steps, or check stopper as needed
}
PostMessage(UWM_MY_THREAD_IS_DONE);
}
You will add to your whatever class the handler for OnThreadDone and the message map entry
to map this user-defined message to the OnThreadDone handler
UINT CMyWhatever::OnThreadDone(WPARAM, LPARAM)
{
if(canceller != NULL)
canceller->DestroyWindow();
canceller = NULL;
updateControls(); // for dialog-based apps
return 0;
}
void CCancellerDialog::PostNcDestroy()
{
CDialog::PostNcDestroy();
delete this;
}
The updateControls function is defined in my essay on dialog control management and would
apply ONLY if you are a dialog-based app; this would enable or disable any controls that
would apply to the launching of a second thread.
If you are an MDI or SDI app, you would instead add ON_UPDATE_COMMAND_UI handlers which
would have the form
void CMyWhatever::OnUpdateSomeMenuItem(CCmdUI * pCmdUI)
{
pCmdUI->EnableWindow(canceller == NULL); // disable if thread running
}
and the complementary test to *enable* if the the thread is running
See my essay on message management to see how to handle registered and WM_APP-based
messages.
These essays can be found onwww.flounder.com/mvp_tips.htm
There are several examples of multithreaded apps on my site as well.
joe
On Fri, 23 Nov 2007 07:39:28 -0800 (PST), Alex <alsim...@hotmail.com> wrote:
Hi, all
My application has some functionality which can take a long time to
process. So I would like to give the user an opportunity to stop the
process. Something like popping up small window with the "Cancel"
button, which if pressed, can break the code execution.
So does anybody know some example how this could be done? As I
suspect it will require start of another thread. I've never worked
with multiple threads. I read some articles from MSDN, but the
problem was that I even couldn't find setting in my project properties
to enable multi thread runtime support. Neither in VS6, nor in VS7.
So any help will be appreciated,
Thanks,
Alex
Joseph M. Newcomer [MVP]
email: newco...@flounder.com
Web:http://www.flounder.com
MVP Tips:http://www.flounder.com/mvp_tips.htm