Re: AfxBeginThread in mainframe.c???
thanks for your answer. I`m not sure if I made some ugly stupid
mistakes, but my OnTermThread() function called by the OnClose()
function in the mainframe will be called for one thread several
times.
At startup of all threads I collected them in an CwordArray in the
mainframe - which is working;
m_threadMsgIDs includes the mesage-nbr to terminate the thread (like
UWM_TERM_THREAD in your example)
OnClose() mainframe:
void CMainFrame::OnClose()
{
m_MainWndIsClosing = TRUE;
if(!CleanupThreads())
{ /* threads running */
TRACE(_T("%s: CAsyncServerDlg::OnClose: deferring close\n"),
AfxGetApp()->m_pszAppName);
return;
} /* threads running */
CFrameWnd::OnClose();
}
BOOL CMainFrame::CleanupThreads()
{
INT_PTR size = m_threadIDs.GetSize();
if(size == 0)
return TRUE;
for (INT_PTR i = 0; i < size; i++)
{ /* scan threads */
// if (!::PostThreadMessage(m_threadIDs[i], UWM_TERM_THREAD, 0,
0))
if (!::PostThreadMessage(m_threadIDs[i], m_threadMsgIDs[i], 0,
0))
{ /* failed */
m_threadIDs.RemoveAt(i);
m_threadMsgIDs.RemoveAt(i);
} /* failed */
} /* scan threads */
// Note that if PostThreadMessage has failed and all the target
threads have
// been removed from the array, we are done
if(m_threadIDs.GetSize() == 0)
return TRUE;
return FALSE;
}
LRESULT CMainFrame::OnConnectionClose(WPARAM, LPARAM lParam)
{
TRACE(_T("%s: CAsyncServerDlg::OnConnectionClose\n"), AfxGetApp()-
m_pszAppName);
PostMessage(WM_CLOSE);
return 0;
}
In my specific thread, I`ve one function installed to terminate the
thread: this function is called several times for the same thread
until the thread will be terminated. ftHandle is a handle to the
serial port.
void CSerialWrite::OnTermThread(WPARAM, LPARAM)
{
ASSERT(ftHandle != NULL);
ASSERT(target != NULL);
if(target != NULL)
{ /* send notification */
TRACE(_T("%s: CConnectSoc::DoClose: sent
UWM_CONNECTIONCLOSE(0, 0x%x)\n"), AfxGetApp()-
m_pszAppName, ::GetCurrentThreadId());
target->PostMessage(UWM_CONNECTIONCLOSE, 0,
(LPARAM)::GetCurrentThreadId());
} /* send notification */
//close handle
FT_W32_CloseHandle(ftHandle);
::PostQuitMessage(0);
}
int CSerialWrite::ExitInstance()
{
//::CloseHandle(WriteEvent);
ASSERT(target != NULL);
if(target != NULL)
target->PostMessage(UWM_THREADCLOSE, 0, (LPARAM)m_nThreadID);
return CWinThread::ExitInstance();
}
BOOL CSerialWrite::InitInstance()
{
if (ftHandle == INVALID_HANDLE_VALUE)
return FALSE; // FT_W32_CreateDevice failed
target->PostMessage(UWM_THREADSTART, UWM_TERM_THREAD,
(LPARAM)m_nThreadID);
return TRUE;
}
/* init ports and start all threads
*/
BOOL CSerialPort::InitPorts(CWnd *wnd)
{
for(int i=0; i<8; i++)
{
ftHandle = FT_W32_CreateFile((LPCTSTR)&Buffer[i][0],GENERIC_READ|
GENERIC_WRITE,0,0,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | //FILE_FLAG_OVERLAPPED |
FT_OPEN_BY_DESCRIPTION,
0);
if (ftHandle == INVALID_HANDLE_VALUE)
return FALSE; // FT_W32_CreateDevice failed
CSerialWrite *m_SerialWriteThread;
/* start thread to tx packets */
m_SerialWriteThread = (CSerialWrite
*)AfxBeginThread(RUNTIME_CLASS(CSerialWrite),
THREAD_PRIORITY_NORMAL, // priority
0, // default stack size
CREATE_SUSPENDED); // don't run right away
if (m_SerialWriteThread == NULL)
{ /* failed to start */
return FALSE;
}
//get variable (wnd and ftHandle to CSerialWrite)
m_SerialWriteThread->SetTarget(wnd);
m_SerialWriteThread->SetHandle(ftHandle);
m_SerialWriteThread->ResumeThread();
}
Maybe you will find some ugly mistakes.
best regards
Hans