概述
线程间通信有两种方法
- 使用全局变量
- 使用自定义消息
自定义消息实例
主线程向CCalculateThread线程发送WM_CALCULATE消息,CCalculateThread线程处理后向主线程发送WM_DISPLAY消息。
1 Dialog设计
- 添加三个单选按钮Radio Button IDC_RADIO1,IDC_RADIO2,IDC_RADIO3,标题命名为10,50,100。
- 添加Button按钮。命名为SUM,ID为IDC_SUM
- 添加编辑框Edit Control。
2 主线程设计
- 头文件中添加变量:int nAddend,代表加数的大小。
- 分别双击三个单选按钮,添加消息响应函数:
void CMultiThread7Dlg::OnBnClickedRadio1()
{
// TODO: Add your control notification handler code here
nAddend=10;
}
void CMultiThread7Dlg::OnBnClickedRadio2()
{
// TODO: Add your control notification handler code here
nAddend=50;
}
void CMultiThread7Dlg::OnBnClickedRadio3()
{
// TODO: Add your control notification handler code here
nAddend=100;
}
- 并在OnInitDialog函数中完成相应的初始化工作
((CButton*)GetDlgItem(IDC_RADIO1))->SetCheck(TRUE);
nAddend=10;
- 头文件中声明消息映射宏
#define WM_DISPLAY WM_USER+2
为了防止用户定义的消息ID与系统的消息ID冲突,MS定义了一个宏WM_USER,小于WM_USER 的ID被系统使用,大于WM_USER的ID被用户使用 - 添加消息映射
ON_MESSAGE(WM_DISPLAY,OnDisplay)
- 设计消息响应函数
LRESULT CMultiThread7Dlg::OnDisplay(WPARAM wParam,LPARAM lParam)
{
int nTemp=(int)wParam;
CString strTime;
strTime.Format(_T("%d"),nTemp);
::SetDlgItemText(AfxGetApp()->m_pMainWnd->GetSafeHwnd(),IDC_EDIT,strTime);
return 0;
}
此处如果使用strTime.Format(("%d"),nTemp),可能会出现错误:没有与列表参数匹配的重载函数,因为字符串有两种类型,char和wchar_T,分别用于多字节字符和unicode字符,两者分别有各自的字符串处理函数。
- 双击SUM:
void CMultiThread7Dlg::OnBnClickedSum()
{
// TODO: Add your control notification handler code here
m_pCalculateThread= (CCalculateThread*)AfxBeginThread(RUNTIME_CLASS(CCalculateThread));
Sleep(500);
m_pCalculateThread->PostThreadMessage(WM_CALCULATE,nAddend,NULL);
}
次线程设计
- 添加类,父类为CWinThread,类名为CCalculateThread。
- 头文件中声明消息映射宏
#define WM_CALCULATE WM_USER+1
- 添加消息映射
ON_THREAD_MESSAGE(WM_CALCULATE,OnCalculate)
ON_THREAD_MESSAGE指明由哪个函数来处理用户定义的消息。当使用CWinThread类的时候,必须用ON_THREAD_MESSAGE来代替ON_MESSAGE。用户定义的消息是指那些不属于标准的Windows WM_MESSAGE的消息。对于每一个要映射到消息处理函数的用户定义函数,在消息映射中必须有且只能有一个ON_THREAD_MESSAGE宏语句。 - 设计消息处理函数
void CCalculateThread::OnCalculate(UINT wParam,LONG lParam)
{
int nTmpt=0;
for(int i=0;i<=(int)wParam;i++)
{
nTmpt=nTmpt+i;
}
Sleep(500);
::PostMessage((HWND)(GetMainWnd()->GetSafeHwnd()),WM_DISPLAY,nTmpt,NULL);
}