当前位置: 首页 > news >正文

MFC应用程序,工作线程学习记录

如何在一个MFC应用程序中添加控制台输出(printf、cout)?

目标:在MFC应用程序中也可以使用cout,printf进行Debug

在程序初始化时(InitInstance中,位于“工程名.cpp”中)调用
AllocConsole(); // 分配控制台
freopen("CONOUT$", "w", stdout); // 将stdout重定向到控制台参数意义:
第一个参数 CONOUT$ : Windows 系统中的 “控制台输出设备”(Console Output)
是一个特殊的设备名(而非普通文件路径);
第二个参数 w :文件打开模式(Write,写入模式,还有其他模式)
第三个参数 stdout : 要重定向的标准流(Standard Output,标准输出)freopen函数意义:
核心作用是重新关联标准流(如 stdin/stdout/stderr)与指定的文件或设备
简单说就是 “重定向输入 / 输出的目标”
示例:freopen("log.txt", "w", stdout);(后续 printf 内容会写入 log.txt)。从属于C 标准库函数(头文件 <cstdio> 或 <stdio.h>)

这样操作以后,在启动MFC程序之后,会额外启动一个控制台窗口用来查看输出




如何简单实现多线程?(AfxBeginThread函数实现)

目标:使用多线程完成简单任务,并输出到控制台上

首先我们需要一个用于多线程执行的任务函数

UINT MyWorkerThread(LPVOID pParam) 
{for (int i = 0; i < 100; i+=25) {printf("工作线程运行中%d%%\r\n", i);Sleep(1000);}printf("工作线程执行完毕!\n");return 0;
}

这里需要注意:

用 MFC 的 AfxBeginThread 或 Windows API 的 CreateThread必须符合 UINT/DWORD 返回值 + LPVOID 参数的原型。该函数的“格式”是十分严格的,必须写成“返回值为UINT、参数为LPVOID” 这样的格式

但是,如果:使用 C++ 标准库 std::thread:无强制原型限制,函数可以灵活定义。

或者:直接同步调用(非线程):无任何限制,但也不是多线程


其次我们要设定启动该线程的方式方法,比如说启动应用程序即刻启动,还是点击某个按键后触发(这里我使用的是点击一个按钮触发该线程)

如何添加按钮这里不多赘述:

void CTest24ThreadDlg::OnButtonStart()
{printf("线程即将启动\r\n");AfxBeginThread(MyWorkerThread,NULL);    //创建并启动多线程printf("线程结束了吗?\r\n");
}

最后观察运行结果,并进行测试。执行完,结果应该是:

线程即将启动
线程结束了吗?
工作线程运行中:0%
工作线程运行中:25%
工作线程运行中:50%
工作线程运行中:75%
工作线程执行完毕!



工作线程与主线程(UI线程)通信及其交互

目标:通过工作线程,消息模式,来使得主线程完成反馈,而非单纯控制台反馈。

模式简述:
发送命令,准备工作:主线程(UI线程)通过发送指令令工作线程工作(或创建工作线程等)

受到命令,开始工作:工作线程完成自己的工作(UI线程仍可独立运行,不会阻塞)

完成工作,进行反馈:工作线程反馈完工信息等,反馈给主线程,令其有相应的反馈(弹窗等)

这就是一个消息模式流程。后续将围绕这几步骤进行实践


规定消息:无论是主界面还是工作界面都需要约定好的消息进行通信

这里采用宏定义进行定义消息:

#define MESSAGE_A 8888注意:宏定义的数值不可随便定义,因为有些数值已经被系统占用了
WM_USER + 100 是推荐的起始值,确保唯一性(据说)

处理函数:

在主线程窗口类中,声明并实现消息处理函数,用于接收工作线程的消息并更新 UI

放在“工程名Dlg.h”位置,即主线程窗口类(c工程名Dlg 类)中Protected处afx_msg LRESULT UpdateUI(WPARAM wParam, LPARAM lParam);代码命名要求较为严苛:除函数名外几乎无法修改
afx_msg 关键字必须添加在函数声明前,用于告诉 MFC 消息映射机制:“这是一个消息处理函数”
返回值类型 LRESULT固定为 LRESULT(32 位整数类型),用于表示消息处理的结果
(大多数情况下返回 0 即可)
WPARAM wParam, LPARAM lParam,必须包含这两个参数:
WPARAM:传递短整数或指针(32/64 位系统中长度与平台一致)。
LPARAM:传递长整数或指针
(功能与 WPARAM 类似,历史上为区分长度设计。现在两者在 32/64 位系统中通常等价)。
这两个参数是 Windows 消息机制的标准设计,用于传递消息的附加数据(如进度值、指针等)。

在源文件(工程名Dlg.cpp)中绑定消息与处理函数(消息映射)

在源文件(工程名Dlg.cpp)中绑定消息与处理函数(消息映射)ON_MESSAGE(MESSAGE_A, &CMessageTestDlg::UpdateUI) ON_MESSAGE(消息ID, 消息处理函数指针)要求放在
BEGIN_MESSAGE_MAP(C工程名Dlg, CDialog)  /(即你的主窗口类,其父类)//{{AFX_MSG_MAP(CMessageTestDlg)ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_QUERYDRAGICON()ON_BN_CLICKED(IDC_BUTTON1, MessageSend)//}}AFX_MSG_MAPON_MESSAGE(MESSAGE_A, &C工程名Dlg::UpdateUI)END_MESSAGE_MAP()
这里,也就是夹在begin和end中间
注意Begin后面的参数,要是自己主窗口那个类,其他的是其他窗口的
这串代码是一个消息映射宏,每一个界面都会有,只不过是有没有内容,内容一样不一样的区别

主线程消息处理函数:

位于工程名Dlg.cpp中,信息映射后面LRESULT CMessageTestDlg::UpdateUI(WPARAM wParam, LPARAM lParam) 
{MessageBox(_T("工作线程任务已完成!"), _T("提示"), MB_OK);return 0;
}注意,定义同样严苛:LRESULT 类名::函数名(WPARAM wParam, LPARAM lParam);

发送消息:仍设计为点击按钮发送消息

未完待续

http://www.dtcms.com/a/524139.html

相关文章:

  • 在什么网站做公司人员增减wordpress主题标签
  • 广州新塘网站制作推广网站服务器检测
  • 金仓多模数据库:电子证照系统国产化替代MongoDB的优选方案
  • SQL之键与约束——数据库设计的基石与数据完整性的守护者
  • 百度网站收录查询地址保定网站推广多少钱
  • 移动端网站如何开发一呼百应网
  • Spring Boot集合RabbitMQ
  • 傻瓜式大型网站开发工具金融 网站 源码
  • 精准与安全并重!NHVOC-1 (C) 型便携式 VOCs 分析仪(PID + 催化氧化 - NDIR)深度解析
  • WPF ComboBox 样式
  • paddlenlp 3.x 版本使用uie-m-base报错找不到 static/inference.pdmodel
  • 郑州市有做网站的吗wordpress如何设置点击直接下载
  • 深度学习打卡第TR5周:Transformer实战:文本分类
  • 一个强大的开源OCR工具,基于DeepSeek OCR
  • 【AI工具】Lyra超级元提示词原文分享:颠覆AI交互逻辑的「提问式」优化工具
  • 企业级表单与文件上传统一管理方案
  • 报错解决:IEEE latex模版中thanks不显示 隶属关系 / 邮箱不显示
  • 第四章:向量数据库:解锁Embeddings价值的钥匙
  • 微信的微网站模板下载wordpress 后台502
  • 基于JavaWeb技术的在线考试系统设计与实现
  • Function Calling VS MCP
  • 找公司网站建设销售网页
  • C++仿muduo库高并发服务器项目:Channel模块
  • 网站开发前端php 后端python张家界seo
  • [特殊字符]兰亭妙微审美积累|总结三个情感化设计细节✨
  • 【数列求和】
  • 第一章-第二节-Cursor IDE与MCP集成.md
  • 做网站的的人收入多少钱wordpress 4.8.4 漏洞
  • 网站开发的英文书有什么如何做网站好看
  • 前端如何判断用户是否离开了当前页面?