概述
UpdateData(true); //true是把对话框的内容赋值给变量,false是把变量的内容显示给对话框
MFC中跨线程UpdateData(FALSE)报错 ASSERT FAILD问题
MFC程序,在给控件关联的变量赋值后,需要调用UpdateData(FALSE)后才能更新到界面,但是有时候却报错:
断言宏失败,在wincore.cpp的如下位置:
CObject* p=NULL;
if(pMap)
{
ASSERT( (p = pMap->LookupPermanent(m_hWnd)) != NULL ||
(p = pMap->LookupTemporary(m_hWnd)) != NULL);
}
ASSERT((CWnd*)p == this); // must be us
这个问题其实是由于跨线程访问UI元素导致的,微软在MSDN中做了如下描述:
In a multi-threaded application written using MFC, you should not pass MFC objects across thread boundaries. As a general rule, a thread should access only those MFC objects that it creates. Failure to do so may cause run-time problems including assertions or unexpected program behavior.
也就是说,MFC的UI线程是线程相关的,每个窗口的HandleMap是储存在创建UI那个线程的堆栈里面的(thread-local-storage (TLS) ),所以,你要是在另一个线程里面通过某种方式调用UI的UpdateData(FALSE)函数,他将无法正确执行。
知道了原因就好办事了,下面提供两种解决方法:
1、通过GetDlgItem(IDC_XXX)取得控件后SetWindowText()
这种方式之所以能得逞,是因为调用SetWindowText 会导致 WM_SETTEXT被发送给目标窗体,由消息机制负责处理:
ctrlDlg->GetDlgItem(IDC_EDIT19)->SetWindowText(A2W(pData));
2、自定义一个消息,将Update消息发送到UI线程,在UI线程的对话框中处理消息,自己执行UpdateData(FALSE)函数的调用。
“ 一种是用FromHandle来获得一个CWnd*,然后再调用UpdateData,这个方案我没有实验成功,结果是错虽然不报了,但是界面也没有被更新.
另外一种是通过发消息的方法转到UI线程去处理.可以在窗口映射一个消息,比如ON_MESSAGE(WM_UPDATEDATA, OnUpdateData),然后用SendMessage(WM_UPDATEDATA, FALSE)传消息给窗口,窗口的消息处理肯定是在UI线程里面,这时候可以用
LRESULT CProtectPage::OnUpdateData(WPARAM wParam, LPARAM lParam)
{
UpdateData(wParam);
return 0;
}
来更新界面,实验是成功的,ASSERT就被消除了.”
转载自:http://hi.baidu.com/sicceer/item/3580d9e88286d2abc00d754f
最后
以上就是大方火为你收集整理的MFC中,执行程序出现断言错误的全部内容,希望文章能够帮你解决MFC中,执行程序出现断言错误所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复