分享

MFC如何在线程中实时刷新界面

 禁忌石 2017-03-30

1.工作者SendMessage让UI线程去更新界面
2.不要把CWnd指针传递到线程中,而是把CWnd所对应的HWND窗口句柄传递进去,
在线程内部,直接使用该句柄,使用windows API来更新界面,而不要在线程中用CWnd的方法来更新界面。
因为MFC不是线程安全的。


请问老师,为什么不能用CWnd方法来更新界面。能详细解释下吗?
为什么我用
//===================第1种在线程中更新界面的方式=================================
HANDLE thread1=CreateThread(NULL,0,xianchen,m_hWnd,0,NULL); //传入窗口句柄。m_hWnd

//线程中的代码
CfeizuobiaoDlg * pp=(CfeizuobiaoDlg * )CWnd::FromHandle((HWND)canshu); //通过窗口句柄得到窗口的对象指针
pp->GetDlgItem(IDC_EDIT4)->SetWindowTextW(_T("我是菜鸟?")); //通过窗口对象,更新界面


//===================第2种在线程中更新界面的方式===================
CWnd *hwnd = GetDlgItem(IDC_EDIT4); //得到控件句柄
HANDLE thread1=CreateThread(NULL,0,xianchen,hwnd,0,NULL); //传入得到的控件句柄。

//线程中的代码
CWnd *pp=(CWnd*)canshu;  //得到控件句柄。
pp->SetWindowTextW(_T("我是菜鸟。")); //显示


//===================第3种在线程中更新界面的方式=========================
HANDLE thread1=CreateThread(NULL,0,xianchen,this,0,NULL); //传入当前窗口的对象。

//线程中的代码
CfeizuobiaoDlg * pp=(CfeizuobiaoDlg * )canshu;  //直接得到窗口的对象
pp->GetDlgItem(IDC_EDIT4)->SetWindowTextW(_T("我是菜鸟!")); //显示

都可以成功更新的啊。


这样做都能实现效果,但是之所以不能这样做,是因为有可能产生问题,虽然出现问题的概率很低很低,但仍然无法保证百分百不出问题,自己写一些小程序的话当然没有关系,但如果写一些正式的商业软件,特别是需要7X24小时稳定运行的软件,都不会这样做。其实这是一个多线程编程的问题,并不只是在MFC中需要注意,在所有多线程并发编程中都应该注意,当你直接把CWND指针传递到工作者线程中以后,现在就有两个线程(UI线程和工作者线程)都可以同时调用这个CWND指针的方法,而MFC不像STL那样,MFC的对象不是线程安全的,访问的时候都没有加锁,程序运行起来后,可能出现这样一个状况,即某个时刻,两个线程同时调用了同一个CWND对象的方法,就会带来一些不可预料的多线程竞态问题,从而出现一些不可预料的错误。你要这样想,我们在多线程编程中,多个线程需要访问同一个变量的时候,是不是应该加锁访问,那么UI线程和工作者线程在访问同一个CWND对象时,也应该如此,如果没有加锁,岂不是就容易出现问题。
这一点在《MFC windows程序设计》和MSDN文档上都说过了,虽然出错概率很低,但我们也应该规范编程。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多