Multithread with MFC 4.2

How can I implement a multithread functionality in my program in order to start a ca. 2 minutes longing procedure without interrupting users work?
Please show me what I have to initialize, where do I have to place the code, how I call the routine and what have to be done after the procedure has finished?
trouvainAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

IgorGrebnevCommented:
In general you need to start additional thread with ( for example ) AfxBeginThread.
I show you haw I would implement the code:
Lets say you have dialog box with the button "Start Calculation"

ON_COMMAND( IDC_STARTCALC,OnStartCalculation)
ON_COMMAND( IDC_CALCFINISHED, OnCalcFinished )


UINT CalcProc( LPVOID pMyDlg )

{ return (CMyDlg*)pMyDlg->CalcProc();
}

void CMyDlg::OnStartCalculation()

{//---------- THREAD_PRIORITY_BELOW_NORMAL - thus the user //interface is not affected by calculation. You can also use
//THREAD_PRIORITY_NORMAL
  AfxBeginThread( ::CalcProc, this, THREAD_PRIORITY_BELOW_NORMAL );
//-- Updates user interface and variables to show that // calculation starts
......
}

UINT CMyDlg::CalcProc()

{//----------- Makes long calculation
  __int64 count = 0;
  while ( count++ < 0xFFFFFFFFFFFF )
  {
  }
//--------- The calulation finished. Updates the interface
  PostMessage( WM_COMMAND, IDC_CALCFINISHED, 0 );
//  Or optinally message box
  AfxMessageBox( "Calculation Finished" );
  return 0;
}

void OnCalcFinished()

{//-------- Updates user interface that calculation finished
...
}

When the function CalcProc() exits the calculation is finished.
You should be careful whiel accessing variables and user interface from CalcProc(), because it executes from contenst of another thread. There are problems with syncronisation and thread local storage. Thus I prefer to post command message to the dialog to announce finish of calculation, instead of taking some action inside of CalcProc().
I can give you more advises if you ask specific questions.
Yours, Igor.
   
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
trouvainAuthor Commented:
Thanks for it. After I tried it I immediatly was shocked that I wasn't aware to ask how I can throw out data by that thread:
This thread is created as a worker thread but also this thread has to report the process of his work. I do this by inserting text into a dialog box with an CEdit field in it. But this time it returns the failure "Access violation". therefore my question: how can I share this dialog box which is an element of my derived CMDIFrameWnd ?
Hope you can manage this!
0
IgorGrebnevCommented:
Dear  trouvain,
I am sorry I didn't your comment - do you have dialog or class derived from CMDIFrameWnd, where the CEdit field.
IN general the multithreading with MFC is tricky, you cannot pass freely the CWnd pointer from one thread to another. IN general hte safe way is to update the internal data structures ( your data ) and post user-defined notification messages to the main window.

In my example you can access member variables of CMyDlg and you can change the test in the controls:
UINT CMyDlg::CalcProc()

{//----------- Makes long calculation
__int64 count = 0;
while ( count++ < 0xFFFFFFFFFFFF )
{ if ( count == 1000000 )
  { CWnd *pControl = GetDlgItem( IDC_SHOWNUMBER );
    char buffer[0x20];
    itoa( count, buffer, 10 );
    pControl->SetWindowText( buffer );
  }
}
//--------- The calulation finished. Updates the interface
PostMessage( WM_COMMAND, IDC_CALCFINISHED, 0 );
// Or optinally message box
AfxMessageBox( "Calculation Finished" );
return 0;
}
Write if you have more comments.
 
0
trouvainAuthor Commented:
Hi Igor,
Unfortunately are my surroundings different:
The worker thread is called from a message handler of CMDIMyFrame. My reporting routine is implemented as a dialog which is a member of CMDIMyFrame. Since there existing more than only one functionality I have a global report function. This function gets the dialog pointer via calling AfxGetMainWindow. But every time I try to get the dialog pointer by referencing ((CMDIMyFrame*)AfxGetMainWindow())->m_dlgReport->SetWindowText(...);
I get a access violation failure.
Is there at all a way to access data respective functions of another thread?
In case there is please explain me for a last time how to do it.
Many thanks in advance.
Marcel
0
IgorGrebnevCommented:
Try to save the pointer to mainWnd in global variable and use it

glb_pMyMDIFrame->m_dlgReport->SetWindowText(...);
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
System Programming

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.