void CDlgTwo::AddToListWhenFinish(CString strName, CString strVersion)
{
int iCnt = m_list.GetItemCount();//Button Wrong会在此抛出异常,调用堆栈查看后发现变量m_list的hWnd=???
CString strIndex = _T("");
strIndex.Format(_T("%.3d"),iCnt + 1);
m_list.InsertItem(iCnt,strIndex);
m_list.SetItemText(iCnt,1,strName);
m_list.SetItemText(iCnt,2,strVersion);
}int iCnt = m_list.GetItemCount();//Button Wrong会在此抛出异常,调用堆栈查看后发现变量m_list的hWnd=???,意思是控件不存在了?但是我有在OnInitDialog中初始化,并且另一个按钮都不会有这个问题。感觉就像是哪里没衔接好,重新来了一样
解决方案 »
- 图片控件连续播放多张,前面的怎样卸载或者隐藏
- 将图片保存到数据库?
- SDI启动时不加载视图??
- 关于new分配内存空间与strlen求其大小的疑问? 在线恭候
- 请大家看看这段代码,我想数据存入数组,但实现不了,帮帮忙吧
- 请问CFORM的问题,我一个程序里面加入好几个FORM,我想实现这样的功能。有不同的消息打开不同的form?
- 画直方图时遇到的问题
- 请教各位大侠:为什么发布版本好用而调试版本不好用
- 调查各位正在使用的VC的版本?
- SDK下,我用CreateWindow创建了一个static的child window,怎么改变它的颜色呢?
- 请问Opencv有连通域检测标识的函数吗?
- mousewheel 如何触发vscroll 事件
{
CDlgOne* pDlg = (CDlgOne*)pParam;
pDlg->Func();
return 0;
}线程可能已经 return !
void CDlgTwo::AddToListWhenFinish(CString strName, CString strVersion)
{
int iCnt = m_list.GetItemCount();//Button Wrong会在此抛出异常,调用堆栈查看后发现变量m_list的hWnd=???
CString strIndex = _T("");
strIndex.Format(_T("%.3d"),iCnt + 1);
m_list.InsertItem(iCnt,strIndex);
m_list.SetItemText(iCnt,1,strName);
m_list.SetItemText(iCnt,2,strVersion);
}int iCnt = m_list.GetItemCount();//Button Wrong会在此抛出异常,调用堆栈查看后发现变量m_list的hWnd=???,意思是控件不存在了?但是我有在OnInitDialog中初始化,并且另一个按钮都不会有这个问题。感觉就像是哪里没衔接好,重新来了一样
UI操作一般最好在UI线程
你可以在你的代码里这样试一下:void CDlgOne::OnBnClickedButton1()
{
// TODO: Add your control notification handler code here
CTestListDlg *p = (CTestListDlg*)GetParent();
((CTestListDlg*)GetParent())->AddToInstall(_T("Name_New"),_T("Version_New"));
}
void CDlgOne::Func()
{
CTestListDlg *p = (CTestListDlg*)GetParent();
((CTestListDlg*)GetParent())->AddToInstall(_T("Name_New"),_T("Version_New"));
}
分别点下两个按钮,调试看看两次GetParent()获取到的父窗口指针CTestListDlg *p的指一不一样。
我这里测试一次是0x004af538 一次是0x02b9fc40
也就是说它根本不是同一个对象,在线程里面获取到的这个是临时创建的,这个临时创建的对象内部的“东西”不全,没有CListCtrl m_list;这些东西。如果还不理解,可以在CTestListDlg中增加一个公有成员变量int m_data;
然后在主窗口上增加一个按钮“赋值”,这个“赋值”按钮点下后给m_data赋值为99。
程序运行后,先点一下“赋值”按钮,然后点“Button OK”,调试可以发现
CTestListDlg *p = (CTestListDlg*)GetParent();后,p->m_data的值是多少,是99,没有问题。
然后点击“Button Wrong”,调试可以发现
CTestListDlg *p = (CTestListDlg*)GetParent();后,p->m_data的值是多少,是0!有问题!
因为前后两个p指向的根本不是同一个对象,在新开线程中获取到的这个p是个新创建的临时对象,内部根本没有那些其他的东西。这些东西在《MFC windows程序设计》和《深入浅出MFC》中都有讲到,其实完全不必去了解MFC内部的这些细节,只要按照《MFC windows程序设计》等书上所说的,只在主线程中操作界面,规规矩矩的来,肯定不会出这种问题。
for(i = 0 ; i < nNumberOfThreads ; i++ )
{
//初始化每个线程的上下文,用于传递给线程函数
pThreadsContext = new THREAD_CONTEXT;
pThreadsContext->pWorkQueue = this;
pThreadsContext->pThreadData = ThreadData == NULL? NULL : ThreadData[i];
//创建线程
m_phThreads[i] = CreateThread(
NULL,
0,
CWorkQueue::ThreadFunc,
pThreadsContext,
0,
&dwThreadId); if(m_phThreads[i] == NULL)
{
delete pThreadsContext;
m_nNumberOfThreads = i;
Destroy();
return false;
}
}void CDlgEntryKM2::OnTimer(UINT_PTR nIDEvent)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
if( nIDEvent == 1 )
{
if( KillTimer( nIDEvent ) )
{
m_pLastWorkItem = new CWorkItemBaseInfo( this, RIGHT_NAME_KM2 );
// 更新用户界面的线程就是在这里启动的
theApp.m_WorkQueue.InsertWorkItem( m_pLastWorkItem );
}
} CDialog::OnTimer(nIDEvent);
}void CDlgEntryKM2::PrepareSearch()
{
KillTimer( 1 );
SetTimer( 1,200,NULL );
}// 这就是更新用户界面的线程函数
void CDlgEntryKM2::StartSearch( CWorkItemBaseInfo * pWorkItemBaseInfo )
{
_BeginTry; _STARTPROMPT; GetDlgItem(IDC_BTN_SAVE)->EnableWindow( FALSE );
GetDlgItem(IDC_BTN_SAVE2)->EnableWindow( FALSE );
GetDlgItem(IDC_BTN_SAVE3)->EnableWindow( FALSE );
GetDlgItem(IDC_BTN_SAVE4)->EnableWindow( FALSE );
SetDlgItemText( IDS_PROMPT,_T("") );
//UpdateData();//多线程里不能用UpdateData
if( !m_ListCtrl.DeleteAllItems() ) return; //CString strExamDateSearch;
//CTime tm;
//((CDateTimeCtrl*)GetDlgItem(IDC_DTP_EXAMDATE_SEARCH))->GetTime(tm);
//strExamDateSearch = tm.Format( _T("%Y-%m-%d") );
CString strArchiveID,strArchiveID2,strName,strIDCard;
GetDlgItemText( IDE_ARCHIVE_ID_SEARCH,strArchiveID );
GetDlgItemText( IDE_ARCHIVE_ID_SEARCH2,strArchiveID2 );
GetDlgItemText( IDE_DRIVER_NAME_SEARCH,strName );
GetDlgItemText( IDE_DRIVER_IDCARD_SEARCH,strIDCard );
strArchiveID.Remove(' ');strArchiveID2.Remove(' ');strName.Remove(' ');strIDCard.Remove(' ');
int nScSel = m_cmbSchoolSearch.GetCurSel();
int nCtpClsSel = m_cmbCartypeClass.GetCurSel();
//条件全部为空,返回
if( nScSel < 0 && nCtpClsSel < 0 && strArchiveID.IsEmpty() && strName.IsEmpty() && strIDCard.IsEmpty() )
return;