一、主线程与子线程通信
方法一:
第一步:#define WM_RECVDATA WM_USER+100
WM_USER
不一定+100,只要大于WM_USER
即可,但要注意不可与其他的自定义消息冲突
1、子线程(要发送消息的线程)
CString str; //将传输的数据转化 成char*
char *ch = new char[10];
WideCharToMultiByte(CP_ACP,0,str,-1,ch,10,NULL,NULL);
//不断调用PostThreadMessage函数,直到函数成功。 这是因为当线程收到这样的函数以后,
//会自动创建消息队列。
while(!::PostThreadMessage(WM_RECVDATA,(WPARAM)ch,0))
{ Sleep(10);
delete[] ch;
}
//此处也可设置全局变量传值,只利用此函数触发主线程函数进行消息处理
2、主线程(接收消息的线程)
重写BOOL VeinDemoDlg::PreTranslateMessage(MSG* pMsg)
BOOL VeinDemoDlg::PreTranslateMessage(MSG* pMsg)
{
//目标线程通过调用PeekMessage强制系统创建一个消息队列
PeekMessage(pMsg,NULL,WM_USER+100,WM_USER+100,PM_NOREMOVE);
//如果是有条件发送,则采用判断语言if进行接收
if(pMsg->message == WM_RECVDATA)
{
//此处添加消息处理函数
}
//如果发送的消息是不间断的,则用while进行接收
while(true)
{
if (GetMessage(&msg,0,0,0))
{ switch (msg.message)
{
case UM_MESSAGE:
char *pch = (char*)msg.wParam;
m_offset_v = atof(pch);//添加消息处理函数
delete[] pch;
break;
}
}
}
return CDialog::PreTranslateMessage(pMsg);
}
BOOL PeekMessage(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax, UINT wRemoveMsg);
LPMSG lpMsg:消息的地址
HWND hWnd:视窗的句柄
UINT wMsgFilterMin, UINT wMsgFilterMax:两个值指示消息范围(都为0或NULL表示传回所有消息
UINT wRemoveMsg:PM_REMOVE
将消息从消息队列中删除,PM_NOREMOVE
保留消息从在消息队列中
参考:https://blog.csdn.net/m0_37884601/article/details/84639830
方法二(推荐):
在MFC中测试通过
在同一个.cpp中
#define WM_CAPTURE_HINT WM_USER + 14
BEGIN_MESSAGE_MAP(VeinDemoDlg, CDialog)
//{{AFX_MSG_MAP(VeinDemoDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_CLOSE, OnClose)
//}}AFX_MSG_MAP
ON_MESSAGE(WM_CAPTURE_HINT, OnCaptureHint)//注意这一条,用于传递消息
END_MESSAGE_MAP()
LRESULT VeinDemoDlg::OnCaptureHint(WPARAM wParam, LPARAM lParam)
{
char * strMessage = (char*)wParam;
//在此可以添加消息处理程序,和主线程中的函数使用相同
LogMessage(strMessage);
delete [] strMessage;
return 0;
}
DWORD WINAPI VeinDemoDlg::MatchProc(LPVOID param)
{
VeinDemoDlg * mainWindow = (VeinDemoDlg *)param;
mainWindow->LogMessageInThread("HelloWorld!");
}
void VeinDemoDlg::LogMessageInThread(char * strFmt, ...)
{
char tempMsg[1024];
CString outMsg = "";
/*---获取参数列表---*/
va_list argp;
va_start(argp, strFmt);
/*---格式化的数据输出到指定的数据流中---*/
_vsnprintf_s(tempMsg, 1024,strFmt, argp);
a_end(argp);
outMsg += tempMsg;
char * strMessage = new char[outMsg.GetLength() + 1];
strcpy(strMessage , (const char*)outMsg.GetBuffer(0));
::PostMessage(GetSafeHwnd(),WM_CAPTURE_HINT,(WPARAM)strMessage,(LPARAM)0);
}
void VeinDemoDlg::LogMessage(char * strFmt, ...)
{
SYSTEMTIME st;
GetLocalTime(&st);
char CurTime[64] = { '\0' };
char tempMsg[1024];
CString outMsg;
sprintf_s(CurTime, "%02d:%02d:%02d.%03d ",st.wHour,st.wMinute,st.wSecond,st.wMilliseconds);
outMsg = CurTime;
/*---获取参数列表---*/
va_list argp;
va_start(argp, strFmt);
/*---格式化的数据输出到指定的数据流中---*/
_vsnprintf_s(tempMsg, 1024,strFmt, argp);
va_end(argp);
outMsg += tempMsg;
m_msgList.InsertString(0,outMsg);
}
二、线程间通信的三种方法
可参考该博文:https://blog.csdn.net/cbnotes/article/details/8516703