The functionality of the dialog:
When you will hit the start button one message will be posted to the thread.
pThreadEx1->PostThreadMessage(WM_THREADSTART, 0, 0);
Concomitantly a timer will be created that will fire at 0.1 seconds.
At this period will be posted recalculating messages:
pThreadEx1->PostThreadMessage(WM_THREADRECALCULATE, m_edit_dim, m_edit_pow);
If you hit Pause button the next message will be sent:
pThreadEx1->PostThreadMessage(WM_THREADPAUSE, 0, 0);
To stop the thread use Stop button:
pThreadEx1->PostThreadMessage(WM_THREADSTOP, 0, 0);
NOTE! Every post have three arguments one is the message definition (WM_THREADSTOP for example). This ones are defined in the header section of the thread class:
#define WM_THREADSTART (WM_USER + 101)
#define WM_THREADSTOP (WM_USER + 102)
#define WM_THREADPAUSE (WM_USER + 103)
#define WM_THREADRECALCULATE (WM_USER + 104)
The other two parameters are a WPARAM and a LPARAM that are in my case user defined. For example the WM_THREADSTOP message will not use WPARAM or LPARAM, that’s way I have left the spaces empties (or zero). For the recalculate message WM_THREADRECALCULATE I need to send the matrix dimension and one other parameter.

When you close this dialog a WM_DESTROY message will be fired. The implementation of OnDestroy will contain few code lines that kill the thread and delete it so that no memory leaks will appear.
void CThreadTestDlg::OnDestroy()
{
CDialog::OnDestroy();
BOOL rez;
DWORD exitcd;
rez = GetExitCodeThread(pThreadEx1->m_hThread, &exitcd);
if(rez && (exitcd == STILL_ACTIVE))
rez = TerminateThread(pThreadEx1->m_hThread,0);
delete pThreadEx1;
}
The functionality of the thread:
No code adding to:
CThreadEx1()
~CThreadEx1()
InitInstance()
ExitInstance()
OnIdle(LONG lCount)
This is the IsIdleMessage method:
BOOL CThreadEx1::IsIdleMessage(MSG* pMsg)
{
if(pMsg ->message==WM_THREADSTART)
{
start = TRUE;
pause = FALSE;
for(int i=0; i<500; i++)
for(int j=0; j<500; j++)
A[i][j] = 1;
}
if(pMsg ->message==WM_THREADSTOP)
{
start = FALSE;
pause = FALSE;
} if(pMsg ->message==WM_THREADPAUSE)
{
if(start == TRUE)
pause = !pause;
}
if(pMsg ->message==WM_THREADRECALCULATE)
{
if((start == TRUE) && (pause == FALSE))
{
int dim = pMsg->wParam;
int pow = pMsg->lParam;
int B[500][500];
int sum;
for(int i=0; i
{
for(int j=0; j
{
for(int k=0; k
{
sum = A[i][k]*A[k][j];
}
B[i][j] = A[i][j];
}
}
return CWinThread::IsIdleMessage(pMsg);
}
The thread will receive messages in the function above and will switch after the message type to do the appropriate work. I have used two variables start and stop that are thread-globally and point me if the thread is start/stop or if it’s paused.
Summary:
Thread:
- create class derived from CWinThread
- use the constructor, the destructor, InitInstance() and ExitInstance() to initialize and cleanup the thread.
- OnIdle(LONG lCount) occurs when no messages are in the queue
- receive messages in IsIdleMessage(MSG* pMsg) using if(pMsg->message==WM_THREADSTART) {…}
Application:
- create thread
o pThreadEx1 = new CThreadEx1();
o pThreadEx1->CreateThread();
- send messages to thread
o pThreadEx1->PostThreadMessage(WM_THREADSTART, 0, 0);
- delete thread
o BOOL rez;
o DWORD exitcd;
o rez = GetExitCodeThread(pThreadEx1->m_hThread, &exitcd);
o if(rez && (exitcd == STILL_ACTIVE))
o rez = TerminateThread(pThreadEx1->m_hThread,0);
o delete pThreadEx1;
Conclusion:
Even in this article I have covered just a minimal part of the thread technology, I have showed you that threading is necessary when you want to separate two businesses. You can easily create your own example starting from the summary.
By: Dragos BREZOI
Attachments
Source Files thread vc++
Project Files thread vc++