Introduction

Creating a separate thread in your application in order to execute some time consuming operations is very simple. You just call AfxBeginThread() with the appropriate parameters and that's it. But Microsoft wants the controlling function either to be a global function or to be a static class member function; which in both cases means that you don't have access to your class member variables or methods from within the controlling function. This article shows you a little trick on how to do this and keep your source OO.

Step-by-Step

Create your project as usual, add your dialogs, controls and all the stuff.

Create your classes for the dialogs using Class Wizard, and assign variables to your controls.

For the class you want to implement multithreading, edit the header file adding the following code:

This was the first hit I got on google when searching for "afxBeginThread member function", so I feel need to make it clear that this solution is obviously flawed and incorrect.

As pointed out before, the proposed solution will cause a memory leak because delete on THREADSTRUCT is not called. If, however, one calls delete after AfxBeginThread, we will get an undeterministic result. For if the thread for some reason takes a long time to start, delete may be called before the static function can read the parameters in the THREADSTRUCT, and then we have no idea what the memory area the pointer points to contains.

Hi!
I'm trying to implement a multi-client server and when i run my code y receive an Access Violation on the ThreadProc when i call conn->Connect.Receive. The struct Conexiones is well defined? How can my ListenSocket could hear and accept new connections. This is part of my code:

I am very interested in this method, I tried to implement it but I had a problem.
The fact is, in my case, I am not using a CDialog derived class but a class like this one :
class ATL_NO_VTABLE CPropPage :
public CComObjectRootEx,
public CComCoClass,
public IPropertyPageImpl,
public CDialogImpl
{
So I can not implement the DoDataExchange function that is (I think) important to have a good behavior of the software.
The thread starts because I see the MessageBox "Thread is started!" but the progress bar is not updated with the different step of progression.

Is the DoDataExchange function the problem ? Somebody has other ideas ?
Thanks.

I am doing some OpenGL drawing in MFC view.
I have a OpenGL class which is used as the base class for MFC view. Then using display lists i have tried to put the drawing on the view. But in tha case of huge point sets, the View doest respond because of openGL drawing.

Then i thought of using threads for openGL.Now i want to implement a thread for drawing openGL stuff.

I have one static UINT threadfunc(LPVOID param) and void threadfunc() declared.
Then i have tried to begin the thread.
I did not get any compilation, linker errors.

This is a slight different question than the previous memory leak one. I have converted the demo project to Visual studio 7.1 and compiled it under the debug mode, and this is what I get when I clicked on "Start" to run the thread.

Thanks a lot. Your article really got me out of a fix. I have though 1 problem. I have a class X that instantiates a class CSerialPort (freeware).
I am spawning a thread so that I can wait for a COM event. I tried WaitEvent like so
ts->this->m_Port.WaitEvent(dwMask);
it is exceptioning at this point. Could someone tell me why that is happening and what I could do about it?
Thanks

From PEPE2207
Hi, Enis, Recently I tried your threaddemo article and I found it works fine, but I am a bit confuse because I can not discover where is deleted the _param pointer releasing the heap memory asigned to the ts THEADSTRUCT instance that you were using the new istruction. Sincerely

and when i press the button to return to my main program it hangs any idea
void CUploadForm::OnButtonReturn()
{
CMainFrame* pFrame = (CMainFrame*)GetParentFrame();
pFrame->SwitchToForm(IDD_NOPDCITATION_FORM);
pFrame->SetWindowText(_T("Cite Capture"));

I used this example and it works fine if i do it exactly like he has. But what if i actually want to do something inside the thread. I can't.I have member control called m_ball1 and a HICON called m_h0;I want to update the m_ball1 within the thread but i can't.i keep getting the errorerror C2228: left of '.SetIcon' must have class/struct/union typeerror C2597: illegal reference to data member 'CCash3mfcDlg::m_h0' in a static member function

I have everything exactly like the author of this demo has except my Classname is different I used CCash3mfcDlg.

I have this in the cpp. If i // it out the program works just like the demo.What am I doing wrong cause i would really like to incorporate this into my program.

UINT CCash3mfcDlg::StartThread(LPVOID param){

THREADSTRUCT* ts = (THREADSTRUCT*)param;

//here is the time-consuming process which interacts with your dialog AfxMessageBox ("Thread is started!");

I am just guessing here, based on my own challenges with multi-thread, but perhaps it will help you (?)

The multi thread functions must be static, and there are restrictions on the kinds of access static functons can have. I am guessing m_h0 is not static and therefore not directly acessible by the static multi thread func.

Basically a static function (and static variables) only exists once in memory, regardless of the number of times you instantiate an object from a class. This means a static function cannot know about the specific instance of an object and ita members (at least not directly.

I.e. if class CTest has member NotStatic, and static member Static, then

A static function in CTest using NonStatic, would not directly know which instance (T1 or T2) to use, and therefore fails.

However, if you somehow pass the static function enough info to resolve the referencing (usually by a this pointer), you are ok.

Therefore you might try referencing m_h0 using the _this pointer - as far as I can see the THREADSTRUCT includes a _this pointer, which would let the static function access the specific instance of CCash3mfcDlg which holds the specific instance of m_h0. I am guessing the m_ball1 is also non static.

//m_ball1.SetIcon(m_h0); changed to use this pointer
ts->_this->m_ball1.SetIcon(ts->_this->m_h0);

Nitpicking: Why set the icon in a thread, rather than before calling thread in an initialize function? If you have to do it you should probably have a function

CCash3mfcDlg::SetIcon() {
m_ball1.SetIcon(m_h0);
}

and call it from your thread like this
ts->_this->SetIcon();

PS If you are just learning C++, you might want to start easier than multi threading , but good luck, I admire your courage.

Thanks for your help and encouragement on the project. I actually completed it. You were right about the static pass in the thread. here is what i did.And as for the setting of the icon I did that for a specific reason. Maybe not the most suffient at the time but I am still learning. I have 3 icons on the screen to represent balls from 0 to 9 and i randomly generate a number sequence consisting of three numbers while the thread runs. and it displays that number sequence represented as balls. and I run it in the thread so it makes the balls look as if they are spinning.

here is a portion of the source pertaining to the thread.http://rafb.net/paste/results/rx590089.html

BTW, the link http://rafb.net/paste/results/rx590089.html does not seem to work

As for my nitpick about setting icons, please ignore that.
If you are trying to do sprite like animation (using icons because they can have transparency) running the "frames" from a worker thread seems like a good solution (IMO).

It was my understanding that you should not pass pointers to CWnd objects like dialogs into threads, but pass the handle (using GetSafeHwnd), and then retrieve pointer in thread using CWnd* pWnd = CWnd::FromHandle(pParam).

But, I might be wrong - I am here becuse the examples showing the above does not seem to work for me when trying to give me access to a dialog from within a thread
(the returned pointer seems to point to some other uninitialized instance)