toannds
asked on
A very simple multi-thread program but couldn't work
Hello,
I'm a beginner to MFC. I wanna practise multi-thread programming so I create a class deriving from CDialog. Its task is simple: it displays the clock in a static text control.
I cannot understand why I keep receiving the "Debug Assertion Failed!" at the line UpdateData(FALSE) of the my UpdateClock() member function. This error occured in the debug version only; the release version worked normally. By tracing I saw the pointer that I catch the ThreadFunc (it is pDlg) and the pParam in AfxBeginThread() are the same. Then where is my mistake?
I tried other way: Pass the window handle of the dialog m_hWnd the ThreadFunc() instead and using the CWnd::FromHandle(HWND hWnd) to get the pointer to my dialog object but this leads to an unhandled exception.
Can you show me the mistake that I made.
Thanks.
Song Toan
toannds@hotmail.com
----------------
Here is my code:
class CMultiThreadDlg : public CDialog
{
public:
// Dialog Data
//{{AFX_DATA(CMultiThreadD lg)
enum { IDD = IDD_MULTITHREAD_DIALOG };
CString m_strTime; // static text control
//}}AFX_DATA
// ... other members ...
protected:
BOOL bContinue;
void UpdateClock();
static UINT ThreadFunc(LPVOID pParam);
// ... other members ...
};
BOOL CMultiThreadDlg::OnInitDia log()
{
CDialog::OnInitDialog();
bContinue = 1; // this flag is used to stop the thread later
pThread = AfxBeginThread(
ThreadFunc,
(LPVOID) this); // pass the pointer as parameter to ThreadFunc()
return TRUE;
}
void CMultiThreadDlg::UpdateClo ck()
{
CTime t;
t = CTime::GetCurrentTime();
m_strTime = t.Format("%H:%M:%S");
UpdateData(FALSE); // Debug Assertion Failed here!
}
UINT CMultiThreadDlg::ThreadFun c( LPVOID pParam ) // this is a static member function
{
CMultiThreadDlg *pDlg = (CMultiThreadDlg *)pParam;
while ( pDlg->bContinue ) pDlg->UpdateClock();
return 0;
}
BOOL CMultiThreadDlg::DestroyWi ndow()
{
bContinue = 0; // terminate the thread
return CDialog::DestroyWindow();
}
I'm a beginner to MFC. I wanna practise multi-thread programming so I create a class deriving from CDialog. Its task is simple: it displays the clock in a static text control.
I cannot understand why I keep receiving the "Debug Assertion Failed!" at the line UpdateData(FALSE) of the my UpdateClock() member function. This error occured in the debug version only; the release version worked normally. By tracing I saw the pointer that I catch the ThreadFunc (it is pDlg) and the pParam in AfxBeginThread() are the same. Then where is my mistake?
I tried other way: Pass the window handle of the dialog m_hWnd the ThreadFunc() instead and using the CWnd::FromHandle(HWND hWnd) to get the pointer to my dialog object but this leads to an unhandled exception.
Can you show me the mistake that I made.
Thanks.
Song Toan
toannds@hotmail.com
----------------
Here is my code:
class CMultiThreadDlg : public CDialog
{
public:
// Dialog Data
//{{AFX_DATA(CMultiThreadD
enum { IDD = IDD_MULTITHREAD_DIALOG };
CString m_strTime; // static text control
//}}AFX_DATA
// ... other members ...
protected:
BOOL bContinue;
void UpdateClock();
static UINT ThreadFunc(LPVOID pParam);
// ... other members ...
};
BOOL CMultiThreadDlg::OnInitDia
{
CDialog::OnInitDialog();
bContinue = 1; // this flag is used to stop the thread later
pThread = AfxBeginThread(
ThreadFunc,
(LPVOID) this); // pass the pointer as parameter to ThreadFunc()
return TRUE;
}
void CMultiThreadDlg::UpdateClo
{
CTime t;
t = CTime::GetCurrentTime();
m_strTime = t.Format("%H:%M:%S");
UpdateData(FALSE); // Debug Assertion Failed here!
}
UINT CMultiThreadDlg::ThreadFun
{
CMultiThreadDlg *pDlg = (CMultiThreadDlg *)pParam;
while ( pDlg->bContinue ) pDlg->UpdateClock();
return 0;
}
BOOL CMultiThreadDlg::DestroyWi
{
bContinue = 0; // terminate the thread
return CDialog::DestroyWindow();
}
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
1) You should not save and use a CWnd pointer at a later time. You should not use a CWnd pointer as a argument passed to the thread function. Where you have:
pThread = AfxBeginThread(ThreadFunc,
(LPVOID) this); // pass the pointer as parameter to ThreadFunc()
return TRUE;
}
do this instead:
pThread = AfxBeginThread(
ThreadFunc,
(LPVOID) this->m_hWnd);
return TRUE;
}
2) To have your thread function notify your main window that something has happened, do this:
::PostMessage(hWnd, WM_USER+1, (WPARAM)wParam, (LPARAM)lParam);
Where wParam and lParam are data values you want sent back to the main window.
pThread = AfxBeginThread(ThreadFunc,
(LPVOID) this); // pass the pointer as parameter to ThreadFunc()
return TRUE;
}
do this instead:
pThread = AfxBeginThread(
ThreadFunc,
(LPVOID) this->m_hWnd);
return TRUE;
}
2) To have your thread function notify your main window that something has happened, do this:
::PostMessage(hWnd, WM_USER+1, (WPARAM)wParam, (LPARAM)lParam);
Where wParam and lParam are data values you want sent back to the main window.
ASKER
And can I use SendMessage() instead of PostMessage()?
ASKER
jhance,
I give you 50 points instead of 10.
Please read the 10109694 question:
https://www.experts-exchange.com/jsp/qShow.jsp?ta=cprog&qid=10109694
Thanks.
I give you 50 points instead of 10.
Please read the 10109694 question:
https://www.experts-exchange.com/jsp/qShow.jsp?ta=cprog&qid=10109694
Thanks.
ASKER
Thank you for your quick answer. May I ask you some more?
1-It's not clear to me that weather I should not use CWnd pointer or I should not use any other class in the that manner (using pointer to a object in ThreadFunction)?
2-Also I want to know how can I get a pointer to my CMultiThreadDlg from the dialog handle that I pass it to the ThreadFunc()? (the CWnd::FromHandle returns the pointer to CWnd only)
Thanks.