关于MFC 线程中调用TeeChart控件的问题

yang_yulei 2014-06-04 08:26:44
关于MFC 线程中调用TeeChart控件的问题

程序的功能是,从socket中获取数据,并把这个数据在菜单窗口中显示曲线。

我用的是单文档菜单设计,先在CMainFrame中分割了3个窗口(这三个窗口都要显示来自socket的数据曲线)
这三个窗口是对话框视图,其上有TeeChart控件来做曲线显示。

然后启一个线程来recv网络上传来的数据,且把分割窗口得到的那3个对话框视图的指针放在结构体中,作为线程的参数。(因为我要在

线程中用对话框视图上的TeeChart显示曲线)

在线程中每接到一次数据就在这3个窗口实时显示。(调用TeeChart的函数)


现在问题是这样做,运行时,在进入thread线程,对TeeChart控件操作时,报错:Debug Assertion Failed!在winocc.cpp第356行错误
我找到文件 356行是 ASSERT(m_pCtrlSite!=NULL); //not an OLE control
在网上查 出现这个错误的原因是 在调用控件时(我这里应该是TeeChart)控件还没有初始化完成,m_pCtrlSite为NULL。

那什么时候分割的窗口上的TeeChart控件才初始化完呢?
我尝试让这个thread线程sleep几十秒,还是没用。
神奇的是,我在调用TeeChart控件之前加上AfxMessageBox("") ;弹出一个对话框,就没问题了。。。。

很奇怪。有懂MFC的朋友知道这是怎么回事么?

大意代码如下:

在CMainFrame::OnCreateClient中分割的

........
CTeeSYView * pView1 = (CTeeSYView*)m_wndSplitter2.GetPane(0,0);
CTeeFFTPBView * pView2 = (CTeeFFTPBView*)m_wndSplitter2.GetPane(1,0);
CTeeFFTSIGView * pView3 = (CTeeFFTSIGView*)m_wndSplitter2.GetPane(2,0); //获取那3个分割窗口的指针


viewPointsObj.pMainFrame = this ;
viewPointsObj.pTeeSYView = pView1 ;
viewPointsObj.pTeeFFTPBView = pView2 ;
viewPointsObj.pTeeFFTSIGView = pView3 ;
//调用线程
AfxBeginThread(&thread,&viewPointsObj);


UINT thread(LPVOID p)中


TeeChart的初始化(这里就出错了)
......
while(s!=SOCKET_ERROR)
{
//循环接收客户端的数据
s=recv(socketPtr->msgsock[msgcount],buff,100,0);

//把数据绘图
//---在此处添加teeChart代码。(要显示的数据在buff字符串中)

}

...全文
432 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
xiaosuiba 2015-01-20
  • 打赏
  • 举报
回复
官方论坛曾经讨论过,仅ocx版线程不安全,建议缓存数据到界面线程,然后用timer画,我们的项目就是这样实现的,效果还不错。
yang_yulei 2014-06-25
  • 打赏
  • 举报
回复
引用 5 楼 60 的回复:
在Windows平台上: 不要在后台线程中直接操作主界面。 不要让多个线程操作界同一个面。 解决方法是: 当后台线程收到数据并进行适当的处理,然后给界面发消息,让界面重绘。
我把相关代码从线程中移出来了,还是有问题,最终发现应该是在视图类中添加的ActiveX控件引发的问题。 如何在 MFC单文档 对话框视图中 插入 ActiveX控件? 我想在单文档程序的一个分割窗口中添加TeeChart控件,分割窗口是对话框视图类,其中没有OnInitDialog(); 我在WM_CREATE消息的OnCreate响应函数中,操作控件,会报错。因为没有调用CDialog::OnInitDialog();对话框上的控 件没有生成。 但是这不是一个对话框,是继承自CFromView的伪对话框,无法调用CDialog::OnInitDialog()。 (用Create动态创建也不行。) 怎么办?
060 2014-06-24
  • 打赏
  • 举报
回复
在Windows平台上: 不要在后台线程中直接操作主界面。 不要让多个线程操作界同一个面。 解决方法是: 当后台线程收到数据并进行适当的处理,然后给界面发消息,让界面重绘。
yang_yulei 2014-06-24
  • 打赏
  • 举报
回复
引用 5 楼 60 的回复:
在Windows平台上: 不要在后台线程中直接操作主界面。 不要让多个线程操作界同一个面。 解决方法是: 当后台线程收到数据并进行适当的处理,然后给界面发消息,让界面重绘。
这样还是不行。 我觉得问题是出在 向线程传递的指针有问题。 我把显示界面的指针打包传给thread,然后使用显示界面的指针时出问题。 给界面发消息还是要用到界面的指针,这个指针有问题。 以前在某书中看过说不能给线程传窗口等的指针。
buyong 2014-06-13
  • 打赏
  • 举报
回复
引用 3 楼 yang_yulei 的回复:
这个方案考虑过,但觉得不可行。 TeeChart是调用一次函数 绘制一个点, 所以把它放在recv之后,这样每来一次数据其就被激活一次 绘一个点,这样能绘出实时曲线。 如果把它放在主线程中绘制不知如何做 才能绘出实时曲线。 线程每获取一次数据就通知主线程么?不行啊,主线程不能阻塞啊。
做个Timer,每秒Invalidate一次,强制重绘。
yang_yulei 2014-06-04
  • 打赏
  • 举报
回复
这个方案考虑过,但觉得不可行。 TeeChart是调用一次函数 绘制一个点, 所以把它放在recv之后,这样每来一次数据其就被激活一次 绘一个点,这样能绘出实时曲线。 如果把它放在主线程中绘制不知如何做 才能绘出实时曲线。 线程每获取一次数据就通知主线程么?不行啊,主线程不能阻塞啊。
buyong 2014-06-04
  • 打赏
  • 举报
回复
尤其控件初始化,不能放到一个线程里
buyong 2014-06-04
  • 打赏
  • 举报
回复
我觉得应该在线程中将接收到的数据传出来,在主线程中进行绘制

24,854

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 工具平台和程序库
社区管理员
  • 工具平台和程序库社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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