书籍:《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);
}

编译执行查看效果

相关内容

 详细介绍GetMessage()-CSDN博客

详细介绍MFC中工作线程和消息线程-CSDN博客

详细分析MFC中的消息线程和窗口线程-CSDN博客

Logo

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

更多推荐