AfxGetMainWnd in worker threads
Recently I faced an issue in one of my project code bases. There is a worker thread (created using CreateThread native API) which calls AfxGetMainWnd() MFC function and since worker threads doesn’t have a main window associated with it, CWnd::Create( …WS_CHILD… ) call fails. A window created with WS_CHILD needs a parent window but AfxGetMainWnd() returned NULL hence the crash.
So I searched using Google and found suggestions ranging from sending window handle as the custom parameter to the thread and then passing this on to the function were the Create function call is made! But that call is about 20 functions deep :roll:. The calls go from one class to another, this means I’ve got to carry this darn handle that far, naah I decided, I’m not going to do that. So I set about exploring other possibilities.
Then a pretty cool thought 💡 struck me, AfxGetMainWnd() calls AfxGetThread(), which returns NULL which in turn results in a NULL window handle. So I thought a possible solution will be to create a CWinThread object using AfxBeginThread(WorkerThread). Then another novel thought came that I can set the main window’s handle to m_pMainWnd member variable of this CWinThread object…
CWinThread* pThread = AfxBeginThread( (AFX_THREADPROC)ThreadProc, (LPVOID)this, THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED, NULL ); pThread->m_pMainWnd = AfxGetMainWnd(); // Possibly already set by above call pThread->ResumeThread();
So this does the trick for me and my project. Now calls to AfxGetMainWnd in this worker thread succeeds, haven’t seen any issue with this so far. If you find any, please post as a comment.