[例8.10]PostThreadMessage发送消息给无窗口的消息线程
书籍:《Visual C++ 2017从入门到精通》环境:Visual Studio 2022。
·
书籍:《Visual C++ 2017从入门到精通》
环境:Visual Studio 2022
新建对话框工程

增加控件
创建线程函数
//作用:定义两个用户自定义消息 MYMSG1 和 MYMSG2,基于 WM_USER(值为 0x0400)扩展,确保不与系统消息冲突。
//用途:用于线程间通信,分别处理字符串和整数数据。
#define MYMSG1 WM_USER + 1
#define MYMSG2 WM_USER + 2
//线程函数
DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
MSG msg;
CString* pstr, str;
int n;
/*消息循环(GetMessage)
行为:阻塞等待消息,直到收到 WM_QUIT(返回 0)或发生错误(返回 - 1)。
参数:NULL 表示接收所有消息,无窗口句柄过滤。
潜在问题:若线程无窗口且无需处理系统消息(如 WM_PAINT),可优化为仅处理自定义消息。*/
while (GetMessage(&msg, NULL, NULL, NULL))
{
//消息处理
switch (msg.message)
{
//操作:将 msg.wParam 强制转换为 CString* ,弹出对话框显示字符串。
case MYMSG1:
pstr = (CString*)msg.wParam;
AfxMessageBox(*pstr);
break;
//操作:将 msg.wParam 转换为整数 n,格式化为字符串后弹出对话框。
case MYMSG2:
n = msg.wParam;
str.Format(_T("%d"), n);
AfxMessageBox(str);
break;
}
}
return 0;
}
为“创建线程”按钮控件添加事件处理函数
双击“创建线程”按钮控件,自动生成事件处理函数,编辑如下:
//该函数是 MFC 对话框类 CTest810Dlg 的按钮点击事件处理函数。当用户点击按钮时,执行以下操作:
//调用 CreateThread 创建一个新线程,执行线程函数 ThreadProc。
//关闭线程句柄(通过 CloseHandle)。
//将线程 ID 保存到成员变量 m_dwThID 中。
void CTest810Dlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
/*线程句柄关闭时机
问题:CloseHandle 立即关闭句柄,但线程可能仍在运行。
风险:关闭句柄不会终止线程,但若线程后续尝试操作已关闭的句柄(如通过 GetCurrentThread() 获取句柄),会导致错误。
改进建议:
若需管理线程生命周期,保留句柄直至线程结束(如调用 WaitForSingleObject)。
若无需管理,当前代码是安全的(线程独立运行)。*/
CloseHandle(CreateThread(
NULL, // 安全属性(默认):使用默认安全描述符,允许子进程继承句柄(若需独立性,需设置 SECURITY_ATTRIBUTES)。
0, // 堆栈大小(默认):使用系统默认堆栈大小(通常为 1MB)。
ThreadProc, // 线程函数:新线程执行的入口函数,需符合 DWORD WINAPI ThreadProc(LPVOID lpParameter) 格式。
NULL, // 传递给线程函数的参数(未使用):线程函数无法直接接收参数(需通过全局变量或其他方式共享数据)。
NULL, // 创建标志(同步创建):同步创建线程:主线程等待新线程完成初始化后再继续执行(通常可忽略,不影响功能)。
&m_dwThID)); // 接收线程ID的指针:保存新线程的 ID,可用于后续操作(如 OpenThread 或 TerminateThread)。
}
为“发送线程消息1”按钮控件添加事件处理函数
双击该控件,自动生成对应的单击按钮事件处理函数,并编辑如下:
//该函数是 MFC 对话框类 CTest810Dlg 的第二个按钮点击事件处理函数。当用户点击按钮时,执行以下操作:
//创建一个本地 CString 对象 str,内容为 "祖国"。
//通过 PostThreadMessage 向线程 ID 为 m_dwThID 的线程发送自定义消息 MYMSG1,并将 str 的地址作为 WPARAM 参数传递。
//主线程休眠 100 毫秒。
void CTest810Dlg::OnBnClickedButton2()
{
// TODO: 在此添加控件通知处理程序代码
// 创建本地 CString 对象
CString str = _T("祖国");
// 向目标线程发送消息
PostThreadMessage(m_dwThID, MYMSG1, WPARAM(&str), 0);
// 主线程休眠 100 毫秒
Sleep(100);
}
为“发送线程消息2”按钮控件添加事件处理函数
双击该控件,自动生成对应的单击按钮事件处理函数,并编辑如下:
//该函数是 MFC 对话框类 CTest810Dlg 的按钮点击事件处理函数。当用户点击按钮时,执行以下操作:
//定义一个局部整型变量 n,赋值为 100。
//通过 PostThreadMessage 向线程 ID 为 m_dwThID 的目标线程发送自定义消息 MYMSG2,并将 n 的值转换为 WPARAM 类型传递。
//主线程休眠 100 毫秒。
void CTest810Dlg::OnBnClickedButton3()
{
// TODO: 在此添加控件通知处理程序代码
// 定义局部变量并赋值
int n = 100;
// 向目标线程发送消息
PostThreadMessage(m_dwThID, MYMSG2, WPARAM(n), 0);
// 主线程休眠 100 毫秒
Sleep(100);
}
编译执行查看效果



相关内容
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)