MFC 用户界面线程传递大量数据到主线程

Fengyq2009 2013-09-11 11:18:14
我需要从txt文档读取大量测量数据到程序处理和显示,如果都在主线程实现,程序界面在读数和处理的时候界面就出现假死。觉得很不舒服。
现在我采用用户界面线程,主线程启动子线程后,在子线程完成txt数据读取,然后将数据传递到主线程显示。

现在问题是,数据量很大,怎么从子线程传递到主线程呢?
看网上说公共变量可以,但是不建议用。。。。
MFC传递指针又不允许。。。。。
应该怎样才能传递呢?请大家帮帮忙。最好有具体详细点的代码示例。谢谢啦
...全文
524 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
davidyu720 2013-09-16
  • 打赏
  • 举报
回复
引用 10 楼 Fengyq2009 的回复:
[quote=引用 9 楼 Kaile 的回复:] 用一个结构体全局变量,里面开一个buffer,作保存数据的地方, 线程之间传结构体的地址,是安全的,因为这个结构体不是MFC中自带的,只要你自己负责线程安全就可以了
你好,我想问下,我在线程中定义了 struct sTxtData { CString strDate; CString strTime; float mValue; }; sTxtData* myData; 然后每次我读上来的数据都赋给 myData->strDate=strToShow; myData->strTime=strToShow; myData->mValue=atof(strToShow); 后,我再发消息: SendMessage(GetMainWnd()->m_hWnd,WM_MYMESSAGE,WPARAM(myData),0); 问题1:这样发消息对吗? 问题2:在主线程的消息函数中我该怎样接收呢? 谢谢啦,我基础不行。[/quote] 如果你用 SendMessage,那这样写代码是可以的:发送线程不需要new,接收线程也不需要delete,比较简单。 接收线程使用强制转换 (sTxtData*)myData 但是,使用SendMessage的话,会使得接收线程在没有处理完WM_MYMESSAGE消息之前,发送线程会一直等待。 如果程序运行速度正常,那就使用SendMessage。 如果觉得程序运行速度不理想,可以改用PostMessage,或者WM_COPYDATA消息。
Fengyq2009 2013-09-16
  • 打赏
  • 举报
回复
似乎需要用WM_COPYDATA消息。。。。。 大家帮我出出注意啦!!!!!!!
Fengyq2009 2013-09-16
  • 打赏
  • 举报
回复
引用 9 楼 Kaile 的回复:
用一个结构体全局变量,里面开一个buffer,作保存数据的地方, 线程之间传结构体的地址,是安全的,因为这个结构体不是MFC中自带的,只要你自己负责线程安全就可以了
你好,我想问下,我在线程中定义了 struct sTxtData { CString strDate; CString strTime; float mValue; }; sTxtData* myData; 然后每次我读上来的数据都赋给 myData->strDate=strToShow; myData->strTime=strToShow; myData->mValue=atof(strToShow); 后,我再发消息: SendMessage(GetMainWnd()->m_hWnd,WM_MYMESSAGE,WPARAM(myData),0); 问题1:这样发消息对吗? 问题2:在主线程的消息函数中我该怎样接收呢? 谢谢啦,我基础不行。
Fengyq2009 2013-09-16
  • 打赏
  • 举报
回复 1
结贴之前,总结下解决过程及结果。 真心话,像我们这样半道出家的,真的需要好好学习MSDN上的实例。最后解决办法也是MSDN的实例。 第一步:定义结构体(在头文件中)

#pragma pack(1)
struct sTxtData
{
	CString strDate;
	CString strTime;
	CString strValue;
};
#pragma  pack;
定义结构体对象和COPYDATASTRUCT对象

sTxtData* pData=new sTxtData();
COPYDATASTRUCT cpdsTruct;
将每行从txt文档读来的数据赋给pData的对应变量: pData->strDate=strToShow; pData->strTime=strToShow; pData->strValue=strToShow; 然后将结构体信息赋给消息准备传递的cpdsTruct cpdsTruct.dwData=0; cpdsTruct.cbData=sizeof(sTxtData); cpdsTruct.lpData=(PVOID)pData; 然后发送消息WM_COPYDATA SendMessage(GetMainWnd()->m_hWnd,WM_COPYDATA,NULL,(LPARAM)&cpdsTruct); 第二步:重载WM_COPYDATA消息 然后在BOOL ***::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct) 中添加: CString mDate,mTime,mValue; sTxtData* myRData=(sTxtData*)(pCopyDataStruct->lpData); mDate=myRData->strDate; mTime=myRData->strTime; mValue=myRData->strValue; 至此,利用界面线程打开txt文件中一行数据就都传递到主线程了。 提醒:没有安装MSDN的孩纸们,赶紧安装。没有那玩意,痛苦着呢……………………
modyaj 2013-09-16
  • 打赏
  • 举报
回复
我自己是这么使用的 发送时myData用对象 SendMessage(GetMainWnd()->m_hWnd,WM_MYMESSAGE,(WPARAM)(&myData),0); 拷贝时就能直接拷贝对象内存地址
傻X 2013-09-16
  • 打赏
  • 举报
回复
MFC传递指针又不允许。。。。。 你确定说的是线程,不是进程么? 怎么不能传了?WM_COPYDATA是跨进程的。
Fengyq2009 2013-09-16
  • 打赏
  • 举报
回复
引用 13 楼 modyaj 的回复:
[quote=引用 10 楼 Fengyq2009 的回复:] [quote=引用 9 楼 Kaile 的回复:] 用一个结构体全局变量,里面开一个buffer,作保存数据的地方, 线程之间传结构体的地址,是安全的,因为这个结构体不是MFC中自带的,只要你自己负责线程安全就可以了
你好,我想问下,我在线程中定义了 struct sTxtData { CString strDate; CString strTime; float mValue; }; sTxtData* myData; 然后每次我读上来的数据都赋给 myData->strDate=strToShow; myData->strTime=strToShow; myData->mValue=atof(strToShow); 后,我再发消息: SendMessage(GetMainWnd()->m_hWnd,WM_MYMESSAGE,WPARAM(myData),0); 问题1:这样发消息对吗? 问题2:在主线程的消息函数中我该怎样接收呢? 谢谢啦,我基础不行。[/quote] 1.这么发送时可以的 2.在处理线程那边做个消息映射 BEGIN_MESSAGE_MAP(CDlgRightView, CDialog) ON_MESSAGE(WM_MYMESSAGE,M_ProcFun)//M_ProcFun是你的处理函数 END_MESSAGE_MAP() M_ProcFun函数中定义myData的对象 mydata memcpy( &mydata, (myData)wParam, sizeof(myData) ); 直接拷贝 取出数据就是了[/quote] memcpy( &mydata, (myData)wParam, sizeof(myData) ); 这一句报错cannot convert from 'unsigned int' to 'struct sTxtData' 什么情况呢?
modyaj 2013-09-16
  • 打赏
  • 举报
回复
引用 10 楼 Fengyq2009 的回复:
[quote=引用 9 楼 Kaile 的回复:] 用一个结构体全局变量,里面开一个buffer,作保存数据的地方, 线程之间传结构体的地址,是安全的,因为这个结构体不是MFC中自带的,只要你自己负责线程安全就可以了
你好,我想问下,我在线程中定义了 struct sTxtData { CString strDate; CString strTime; float mValue; }; sTxtData* myData; 然后每次我读上来的数据都赋给 myData->strDate=strToShow; myData->strTime=strToShow; myData->mValue=atof(strToShow); 后,我再发消息: SendMessage(GetMainWnd()->m_hWnd,WM_MYMESSAGE,WPARAM(myData),0); 问题1:这样发消息对吗? 问题2:在主线程的消息函数中我该怎样接收呢? 谢谢啦,我基础不行。[/quote] 1.这么发送时可以的 2.在处理线程那边做个消息映射 BEGIN_MESSAGE_MAP(CDlgRightView, CDialog) ON_MESSAGE(WM_MYMESSAGE,M_ProcFun)//M_ProcFun是你的处理函数 END_MESSAGE_MAP() M_ProcFun函数中定义myData的对象 mydata memcpy( &mydata, (myData)wParam, sizeof(myData) ); 直接拷贝 取出数据就是了
贪食蛇男 2013-09-11
  • 打赏
  • 举报
回复
1. 子线程把要传递的内容写入文件或注册表 2. 子线程向主线程发消息,比如自定义消息 3. 主线程在自定义消息回调中读文件或注册表
Kaile 2013-09-11
  • 打赏
  • 举报
回复
用一个结构体全局变量,里面开一个buffer,作保存数据的地方, 线程之间传结构体的地址,是安全的,因为这个结构体不是MFC中自带的,只要你自己负责线程安全就可以了
homesos 2013-09-11
  • 打赏
  • 举报
回复
float* pTxtDate; -->是从文本文件中加载内容,那么内容应该当作字符串来处理,即使内容是一些浮点数,此时也是字符串表达方式,所以不用float来保存文本文件内容,用char *更合适一些,当然用void *也行,只要有内存来保存内容即可。
homesos 2013-09-11
  • 打赏
  • 举报
回复
str.Format("%.2f",wParam);---->仅仅是打印了wParam本身的地址,而不是它所指向的内存内容。
homesos 2013-09-11
  • 打赏
  • 举报
回复
引用 4 楼 Fengyq2009 的回复:
我现在这么做的:

float* pTxtDate; 
pTxtDate=new float[mTotalOpenNum];
//mTotalOpenNum是要读取数据的总数
.....
.....
//将数据都读取到pTxtDate后
PostMessage(GetMainWnd()->m_hWnd,WM_MYMESSAGE,(WPARAM)pTxtDate,0);
]; 这样的话我能够紧跟着delete [] pTxtDate;吗? 还有在我的消息函数中:

CString str;
str.Format("%.2f",wParam);
怎么没有传过来数据呢? 请大家帮我看看,谢谢!
思路没错,写法上楼主搞错了。 直接开个char数组读取,读完后发消息(数组指针,内容长度),窗口里收到消息后,直接赋值给CString就可以了。
Fengyq2009 2013-09-11
  • 打赏
  • 举报
回复
咋没有回复呢?等了一整天。。。。 是因为我用MFC 用户界面线程的原因吗? 怎么没有回复呢?谢谢啦
Fengyq2009 2013-09-11
  • 打赏
  • 举报
回复
我现在这么做的:

float* pTxtDate; 
pTxtDate=new float[mTotalOpenNum];
//mTotalOpenNum是要读取数据的总数
.....
.....
//将数据都读取到pTxtDate后
PostMessage(GetMainWnd()->m_hWnd,WM_MYMESSAGE,(WPARAM)pTxtDate,0);
]; 这样的话我能够紧跟着delete [] pTxtDate;吗? 还有在我的消息函数中:

CString str;
str.Format("%.2f",wParam);
怎么没有传过来数据呢? 请大家帮我看看,谢谢!
Fengyq2009 2013-09-11
  • 打赏
  • 举报
回复
引用 1 楼 hiroyukki 的回复:
1. 子线程把要传递的内容写入文件或注册表 2. 子线程向主线程发消息,比如自定义消息 3. 主线程在自定义消息回调中读文件或注册表
我就是觉得在主线程读txt文档数据有假死的现象,所以让子线程读。 如果子线程读完存到文件,再主线程读。哪还不如主线程直接读呢?。。。
96掌门师兄 2013-09-11
  • 打赏
  • 举报
回复
怎么不允许传递指针呢? 后台程序读取,开辟空间,填入消息,将空间起始地址作为消息参数发给UI对话框,UI显示后删除空间。。
VC实例精通一书的源码。 第2章(\Chapter02) 示例描述:本章介绍常用Win32控件的使用方法。 01_EditDemo 演示静态文本、文本框、按钮控件的使用方法 02_CheckBoxDemo 演示复选框和单选按钮控件的使用方法。 03_ComboBoxDemo 演示组合框和列表框控件的使用方法。 04_ScrollBarDemo 演示滚动条控件的使用方法。 05_SpinDemo 演示数值调节按钮的使用方法。 06_ProgressDemo 演示进度条控件的使用方法。 07_SliderDemo 演示滑块控件的使用方法。 08_HotkeyDemo 演示热键控件的使用方法。 09_ListCtrlDemo 演示列表控件的使用方法。 10_TreeCtrlDemo 演示树形控件的使用方法。 11_RichEditDemo 演示格式文本框的使用方法。 12_TabCtrlDemo 演示属性页的使用方法。 13_AnimateDemo 演示动画控件的使用方法。 14_DateTimeDemo 演示日期时间选择控件的使用方法。 15_CalendarDemo 演示日历控件的使用方法。 16_IPCtrlDemo 演示IP输入框的使用方法。 第3章(\Chapter03) 示例描述:本章介绍高级Win32控件的使用方法。 01_MenuDemo 演示窗体菜单的使用方法。 02_PopMenuDemo 演示弹出式菜单的使用方法。 03_ToolbarDemo 给窗体添加标准工具栏。 04_Toolbar256 使工具栏支持256色位图。 05_StatusBarDemo 在窗体的状态栏区域输出信息。 06_ColorStatusBar 在状态栏添加彩色渐变进度条。 07_ToolTipDemo 使用ToolTip显示即时提示。 第4章(\ Chapter04) 示例描述:本章介绍窗体的使用方法和使用技巧。 01_WindowDemo 演示创建和显示窗体的方法。 02_TopMostWnd 让窗体保持在桌面最顶层。 03_TransparentWindow 创建半透明窗体。 04_EllipticalWindow 创建椭圆窗体。 05_TextPathWnd 创建文字异形窗体。 06_ImagePathWnd 根据图片创建异形窗体。 07_AnimatedWnd 以动画方式显示和隐藏窗体。 08_AutoSize 让窗体上的控件自动适应窗体大小。 09_AutoSizeEx 多个控件改变大小时防止闪烁。 10_LimitSize 限制窗体的最大和最小尺寸。 11_AutoPos 让窗体具有停靠效果。 12_EnumWnd 枚举系统中的窗口。 第5章(\ Chapter05) 示例描述:本章介绍创建对话框以及通用对话框的使用技巧。 01_ModalDlg 显示模式对话框。 02_ModallessDlg 显示非模式对话框。 03_OpenFileDemo 使用打开文件对话框。 04_SaveFileDemo 使用保存文件对话框。 05_FontDlgDemo 使用字体选择对话框。 06_FontDlgDemo_Color 使用字体选择对话框。 07_PreviewFileDlg_Demo 为打开文件对话框增加预览功能。 08_InputDlg_Demo 从内存创建对话框。 第6章(\ Chapter06) 示例描述:本章介绍Windows应用程序消息循环的原理和消息处理技巧。 01_PeekMsgDemo 传递并响应Windows消息。 02_SendMsg 发送Windows消息。 03_MsgInMfc 了解MFC的映射消息机制。 04_UserMsg 使用自定义消息。 05_DoubleEdit_Demo 拦截并处理Win32控件的消息。 第7章(\ Chapter07) 示例描述:本章介绍Windows系统和外壳编程的技巧。 01_TimerDemo 使用计时器。 02_RegDemo 访问系统注册表。 03_SuperPwd 用随机数生成强力密码。 04_ShellOpen 打开一个和程序相关联的文档。 05_ClipboardDemo 访问Windows剪切板。 06_ClipboardMonitor 监视剪切板内容变化。 07_TrayIconDemo 使用系统托盘图标。 第8章(\ Chapter08) 示例描述:本章介绍在应用程序中使用Windows基本设备的方法和技巧。 01_MouseSample 处理鼠标消息。 02_KeyTest 处理键盘消息。 03_MouseMoving 利用客户区鼠标消息拖动无边框窗体。 04_NCMsg 利用非客户区鼠标消息控制无边框窗体。 05_LockMouse 限制鼠标移动区域。 06_MyEvent 模拟键盘鼠标消息。 07_ClipboardHelper 使用系统热键消息使后台程序得到通知。 第9章(\ Chapter09) 示例描述:本章学习Windows进程的创建和管理方法。 01_StartProcess 创建和结束进程。 02_RedirectStdio 用匿名管道获取控制台程序的输出。 03_CatchError 拦截并处理外部进程的错误。 04_SingleInstance 防止应用程序运行多个实例。 05_ProcessMsg 用消息在进程间通讯。 06_MappingFile 用内存映射文件在进程间通讯。 07_ProcessList 枚举并得到系统中所有进程信息。 第10章(\ Chapter10) 示例描述:本章学习Windows线程的创建和管理方法。 01_PrimeNumberFinder 线程用户界面。 02_PrimeNumberFinderEx 创建和结束线程。 03_PrimeNumberFinal 用临界区对象同步线程。 04_BigPrimeNumber 用事件对象同步线程。 05_SemaphoreDemo 用信号量对象同步线程。 06_ThreadPriority 调整线程优先级。 第11章(\ Chapter11) 示例描述:本章学习使用VC6进行图形图像开发的技巧。 01_ZoomBitmap 用DC对象缩放位图。 02_DrawLine 用画笔对象画线。 03_BrushDemo 用画刷对象填充区域。 04_RollText 在屏幕上输出文本。 05_PicShow 使用GDI+读取不同格式的图片。 06_PicShowEx 使用GDI+保存不同格式的图片。 07_Snap 制作屏幕截图程序。 08_Watermark 给图片增加版权信息。 第12章(\ Chapter12) 示例描述:本章学习使用VC6进行文件IO开发的技巧。 01_BinaryView 用基本API编写二进制编辑器。 02_MyCompressor 用MFC类编写文件压缩软件。 03_DirMonitor 监控硬盘上文件的变化。 04_HddSpace 获取本机所有磁盘及其空间使用情况。 05_WideText 文本保存及编码方式。 06_XmlReader 读写XML文件。 07_SerialPort 读写串口数据。 第13章(\ Chapter13) 示例描述:本章学习使用VC6进行数据库开发的方法和技巧。 01_ODBC_Source 创建ODBC数据源。 02_ODBC_Demo 通过ODBC访问Access数据库。 03_ADO_Demo 通过ADO访问据库。 04_ExecProc 调用SQL Server的存储过程。 05_TransExec 事务处理SQL Server命令。 06_BinData 存取数据库中的图片。 07_CreateMdb 在程序中动态生成Access数据库。 第14章(\ Chapter14) 示例描述:本章学习使用VC6进行网络开发的方法和技巧。 01_UdpClient 建立UDP连接客户端。 02_UdpServer 建立UDP连接服务器端。 03_TcpClient 建立TCP连接客户端。 04_TcpServer 建立TCP连接服务器端。 05_MfcSock 使用MFC的SOCKET类。 06_MyWebProtocol 注册自己的浏览器地址栏协议。 07_GetHttpStr 抓取网页内容。 08_VisualPing 基于ICMP编写网络速度监控程序。 第15章(\ Chapter15) 示例描述:本章介绍一些Windows高级编程技术。 01_AppSnap 制作鼠标HOOK。 02_PasswordShow 用鼠标HOOK读取密码框中的内容。 03_KeyVoice 制作键盘HOOK。 04_SysKey 用键盘HOOK屏蔽系统按键。 05_DlgSkinDemo 用HOOK技术给对话框换肤。 06_PeExport 分析DLL文件获取其导出函数列表。 第16章(\ Chapter16) 示例描述:本章介绍VC6在多媒体开发方面的应用技术。 01_BgMusic 用基本API播放声音。 02_MP3Player 用MCI播放音频。 03_MyReal 调用RealPlayer播放音频文件。 04_Recorder 制作录音机程序。 05_GifCtrl 在VC中显示动态的GIF动画。 06_FlashWnd 在VC中播放Flash动画。 07_MediaPlayer 在VC中播放视频。 08_CaptureVideo 在VC中实现视频采集及截图功能。 第17章(\ Chapter17) 示例描述:本章介绍VC6在ActiveX方面的应用技术。 01_MyActiveX 创建ActiveX控件。 02_MyActiveX2 为ActiveX控件增加属性和方法。 03_ActiveXInDlg 在应用程序中使用ActiveX控件。 04_ActiveXInWeb 在浏览器中使用ActiveX控件。 05_MyActiveX3 在VC中显示动态的GIF动画。 06_RegOCX 在程序中注册和注销ActiveX控件。 第18章(\ Chapter18) 示例描述:本章介绍如何将应用程序制作成完整的应用软件的技术。 01_MyHelp 制作帮助文件。 02_Setup 制作安装程序。 03_MultiLanguage 让应用程序界面支持多语言。 04_MultiLanguageEx 多语言的字符串常量。 05_SetupEx 制作多语言的安装程序。

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧