MFC工作线程中获得视图类指针问题

今天写的代码很无语,原来稳稳妥妥的代码,在线程中却神乎其神的不管用了。我查了网上的资料,只收集到一位高手的留言:

通常来讲,在MFC中,跨线程是不能传递CWnd对象指针的。因为在每个线程中都有一个自己的内部map,该map记录了HWND和与之对应的CWnd对象。当一个CWnd对象被创建时,它的HWND和CWnd对象指针就会被记录到该线程中的map,但其他的线程的map没有记录。
当跨线程传递CWnd指针时,调用CWnd的某些函数时,这些函数会进行有效性检查,也就是检查map,因为map中没有相应的记录,就会报错。通常这个错误是 AsserValid(this)
所以,在MFC中跨线程传递参数,最好传递句柄HWND,而不是CWnd对象指针。

 

目前只需记住不能用AfxGetMainWnd()->MDIGetActive()->GetActiveView();来得到指针。

而且需要稍微注明一下,AfxGetMainWnd()是通过得到模块状态AFX_MODULE_STATE来取得,如果在MFC线程中调用,理应得到此线程的模块变量,即m_pMainWnd,然后在线程中得到的是进程中主线程的主窗口变量:m_pMainWnd。但是AfxGetMainWnd()在本线程没有窗口时,会调用主线程的主窗口的m_pMainWnd,所以在线程中用AfxGetMainWnd()是有值的。但是这个值悬乎,或者说并不可用,因为用它去调用MDIGetActive(),再调用GetActiveView()是不行的。有人说因为线程map而使得指针与其句柄没有关联起来,以至于调用某些需要检查句柄是否有效的函数的时候会出问题。说了这么多,只是想说,在自己创建的线程中使用AfxGetMainWnd()再去得到其他的东西是不行,但也别盲目排斥某些MFC类指针的使用。

 

另外记录一下其他两种可以获得可用的视图指针的办法:

1:把要用的指针放在自己派生自CWinApp的类里,然后在线程用使用AfxGetApp()得到App类对象指针,在去得到自己的视图指针,这个肯定没问题,每个应用程序只有一个app对象,所以可以使用它来取得相应参数。

2:用结构体把所有想传的变量都加进去,然后传进去使用。

 

目前使用没有问题,没有碰到上面那位高手提到的map映射问题。

 

另外提醒一点:

不要在view类的OnInitUpdate里面调用AfxGetMainWnd()->MDIGetActive();因为这个时候子框架还不能算生成,所以调用得到的子框架指针是不用的。可能因为创建视图的地方是在CFrameWnd::CreateView(),是有CFrameWnd调用的。有点糊涂,具体原因现在不明白。

 

时间: 2024-09-15 13:43:07

MFC工作线程中获得视图类指针问题的相关文章

代码-【MFC,VS2013中使用Serialport类的问题???急】

问题描述 [MFC,VS2013中使用Serialport类的问题???急] 10C 上位机软件.1.在VC6.0中用SerialPort类,数据的传输完全没有问题.[我代码没有问题]2.使用串口精灵传输命令没有问题.[我机器没有问题]3.但是我现在将代码用在VS2013发送数据就完全没有反应.[同样的代码同样的机器用VS2013就有问题]VS2013中我把数据发送分为2个部分:①初始化串口+②发送数据命令.如果每次发送格式是:①初始化串口+②发送数据命令[没有问题]如果格式是:②发送数据命令[

详解Android中用于线程处理的AsyncTask类的用法及源码_Android

为什么要用AsyncTask我们写App都有一个原则,主线程不能够运行需要占用大量CPU时间片的任务,如大量复杂的浮点运算,较大的磁盘IO操作,网络socket等,这些都会导致我们的主线程对用户的响应变得迟钝,甚至ANR,这些会使应用的用户体验变差,但是有时又的确需要执行这些耗时的任务,那么我们通常可以使用AsyncTask或者new Thread 来处理,这样把任务放入工作线程中执行,不会占用主线程的时间片,所以主线程会及时响应用户的操作,如果使用new Thread来执行任务,那么如果需要中

如何在普通类实例的线程过程中,同步调用执行在类实例自身所在的原来的那个线程中的方法

问题描述 如何在普通类实例的线程过程中,同步调用执行在类实例自身所在的原来的那个线程中的方法如后代码,是一个常见的实例,讲的是通过Control.Invoke在线程函数中,同步调用窗体主线程中的Form1实例的普通方法txt.但问题是,很多时候我们自己自定义的类,并不是从Control类继承的,从而也没有这个功能的Invoke方法供调用,这种类要怎么设计呢?虽然说用的示例代码是vb.net的,但严格来说,这个和语言无关,是一个.net开发的基本问题.ImportsSystemImportsSys

详解Android中用于线程处理的AsyncTask类的用法及源码

为什么要用AsyncTask 我们写App都有一个原则,主线程不能够运行需要占用大量CPU时间片的任务,如大量复杂的浮点运算,较大的磁盘IO操作,网络socket等,这些都会导致我们的主线程对用户的响应变得迟钝,甚至ANR,这些会使应用的用户体验变差,但是有时又的确需要执行这些耗时的任务,那么我们通常可以使用AsyncTask或者new Thread 来处理,这样把任务放入工作线程中执行,不会占用主线程的时间片,所以主线程会及时响应用户的操作,如果使用new Thread来执行任务,那么如果需要

略谈如何从工作线程中弹出对话框

工作线程,在一些技术文章被称为辅助线程,是相对于主线程而言的.在工作线程中使用界面需要一些技巧.我就曾在工程线程中弹出对话框中遇到过莫名奇妙的错误.下面就我的经验谈谈如何从工作线程中弹出对话框(暂时只讲方法,原理还没彻底弄清楚).   实际上在工作线程中直接弹出模式对话框中在debug模式下有时出错(这里的有时的意思是必然会出错,但是不是每次都出错),弹出模式对话框的代码如下:   DWORD WINAPI RecvThread(LPVOID lpParam)    // 工作线程函数 {   

MFC框架程序中全屏显示特性的实现

在开发图像显示程序以及视频应用程序时,常常需要全屏显示特性,比如ACD See和豪杰解霸等应用都有全屏显示功能.本文将介绍如何在MFC框架程序中实现视图的全屏显示,也就是说将标题.菜单.工具栏.状态栏以及窗口的所有边框全部被隐藏,视图充满整个屏幕.并提供全屏显示与框架窗口之间的快捷切换操作. 大家知道,在MFC框架中并没有提供现成的类或者函数来实现全屏显示特性,至少我到目前为止是没有发现.但是要实现这个特性也并不难.其基本思路是调整主窗口的大小和位置,使视图的显示充满屏幕.它需要以屏幕左上角为原

如何在android的jni线程中实现回调

JNI回调是指在c/c++代码中调用java函数,当在c/c++的线程中执行回调函数时,会导致回调失败. 其中一种在Android系统的解决方案是: 把c/c++中所有线程的创建,由pthread_create函数替换为由Java层的创建线程的函数AndroidRuntime::createJavaThread. 假设有c++函数: [cpp] view plaincopy void *thread_entry(void *args)   {       while(1)       {    

多线程-Qt 在次线程中截图问题

问题描述 Qt 在次线程中截图问题 我在用QT做一个软件控件的软件,服务端需不断地截取屏幕图像然后发送给客户端,这就需要服务端开一个独立的线程完成 截图->传送 .但是Qt里限制在线程中创建QWidget类及其子类,所以无法在线程中 完成截图的操作(我用的QPixmap中的grabWindow方法). QPixmap属于QWidget的子类,每当在线程中执行截图: pixmap = QPixmap::grabWindow(..),的时候,程序会崩溃. 求各位研究过这个的大哥帮帮忙,看看怎么解决,

更新MFC中的视图,跟踪.NET Framework中的事件

本文配套源码 如何更新MFC中的视图? 如何跟踪.NET Framework 中的事件? 我在 MDI 程序中打算通过 CMainFrame 中的定时器事件来更新所有的子窗口. 视图用于显示许多图表.用如下的代码只能更新当前活动窗口: GetActiveWindow()->GetActiveView()->GetDocument() 是否有其它的方法从 CMDIFrame 类中获得所有的子窗口或者所有的文档? Makarand 你的情况并不罕见.许多采集实时数据的程序需要定时更新屏幕.即使你的