既然你是要在子窗口显示进度条,那天在资源中编辑对话框嘛,添加了进度条,然后为这个对话框创建一个类,在对话框类中的函数中处理你的进度条啊,在DoMoal之后自然会执行进度条的代码了,比如你可以再InitDIalog中初始化进度条为50%等等
子线程中不能 *** 作主线程的控件具,体实现方法见上个提问,另外,UpdateData不要在子线程中用会卡的!
以下是我搜集的MFC多线程应注意的事项,很乱但很有用:
--------------------------------------------------------------------------------
MFC多线程编程注意事项 -
--------------------------------------------------------------------------------
关于启动线程时传输窗口对象(指针?句柄?)的问题:
在选择菜单中的开始线程后:
void cmainframe::onmenu_start()
{
afxbeginthread(mythread, this);
}
线程函数如下:
uint mythread(lpvoid pparam)
{
cmainframe pmainfrm = (cmainframe )pparam;
}
问题一:
这样的代码是不是有问题?
(文档中说线程间不能直接传输mfc对象的指针,应该通过传输句柄实现)
问题二:
这样使用开始好像没有问题,直接通过pmainfrm访问窗口中的view都正常。
但发现访问状态条时:
pmainfrm->m_wndstatusbarsetpanetext(2, "test);
出现debug assertion failed!(在窗口线程中没有问题)
位置是wincorecpp中的
assert((p = pmap->lookuppermanent(m_hwnd)) != null ||
(p = pmap->lookuptemporary(m_hwnd)) != null);
为什么访问view能正常,但访问状态条时不可以呢?
问题三:
如果通过传输句柄实现,怎样做呢?
我用下面的代码执行时有问题:
void cmainframe::onmenu_start()
{
hwnd hwnd = getsafehwnd();
afxbeginthread(mythread, hwnd);
}
uint mythread(lpvoid pparam)
{
cmainframe pmainfrm = (cmainframe )(cwnd::fromhandle((hwnd)pparam));
}
执行时通过线程中得到pmainfrm,访问其成员时不正常。
网友:hewwatt
大致原因解释如下:
1 mfc的大多数类不是线程安全的,cwnd及其消息路由是其中之最
2 mfc界面类的大多数方法,最后都是通过sendmessage实现的,而消息处理的
过程中会引发其他消息的发送及处理。如果消息处理函数本身不是线程安全的
你从工作线程中调用这些方法迟早会同你界面线程的用户消息响应发生冲突
3 cxxxx::fromhandle会根据调用者所在线程查表,如果查不到用户创建的cxxxx
对应对象,它会创建一个临时对象出来。由于你在工作线程中调用该方法,当然不可能查到界面主线程中你所建立起来的那个对象了。这时mfc会你创建一个临时对象并返回给你,你根本不可能期望它的成员变量会是有意义的。
所以要用也只能用cwnd::fromhandle,因为它只包含一个m_hwnd成员。 不过,要记住
跨线程直接或间接地调用::sendmessage,通常都是行为不可预测的。
1工作线程给主线程发消息使用的是SendMessage和PoseMessage函数。这两个函数的区别在于SendMessage函数是阻塞方式,而PoseMessage函数是非阻塞方式。如果不是严格要求工作线程与主线程必须同步执行,则推荐使用PoseMessage。
2不要在线程函数体内 *** 作MFC控件,因为每个线程都有自己的线程模块状态映射表,在一个线程中 *** 作另一个线程中创建的MFC对象,会带来意想不到的问题。更不要在线程函数里,直接调用UpdataData()函数更新用户界面,这会导致程序直接crash。而应该通过发送消息给主线程的方式,在主线程的消息响应函数里 *** 作控件。
3在主线程中不要使用WaitForSingleObject和WaitForMultipleObjects两个函数等待线程退出,其原因就是有导致程序死锁的隐患,特别是线程函数里调用了SendMessage或是直接 *** 作了MFC对象,更易出现此种现象。为解决这一问题,微软特提供了一个函数,MsgWaitForMultipleObjects。
照着网上的例子,写了在主线程中等待单个线程退出的程序:
DWORD dRet=-2;
MSG msg;
BOOL bWaitAll=FALSE;
int nWaitCount=2; //初始等待的线程数目
while (1)
{
dRet=MsgWaitForMultipleObjects(1,句柄的指 针,bWaitAll,INFINITE,QS_ALLINPUT);
if (dRet == WAIT_OBJECT_0 + 1)
{
TRACE("收到消息,函数返回值为%d \n",dRet);
while (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else if (dRet == WAIT_OBJECT_0 )
{
TRACE("线程退出了\n");
break;
}
}//end while
}
实际使用中,在主线程中使用WaitForMultipleObjects导致界面线程在子线程结束前失去响应,而使用MsgWaitForMultipleObjects则很好的解决了这个问题。
本文来自CSDN博客,转载请标明出处:>
只要能获取文档类指针就可以了阿,在你的对话框cpp文件包含MainFrmh和Doch,需要保存数据的时候获取文档类指针来 *** 作就可以了: ((CDoc )((CMainFrame )AfxGetMainWnd())->GetActiveDocument())->方法
子窗口获得父窗口指针 GetParent();
比如父窗体如下
CParentDlg : public CDialog
{
public:
CButton m_bt;
}
子窗体 *** 作父窗体的按钮m_bt,可以这样(CParentDlg )GetParent()->m_btSetWindowText("hello");
基类CWinApp的构造里有进行设置,构造theApp全局对象时会先调用基类构造,把指针保存下来
pModuleState->m_pCurrentWinApp = this;
然后AfxGetApp可以获得这个结构,从里面拿出m_pCurrentWinApp
#define afxCurrentWinApp AfxGetModuleState()->m_pCurrentWinApp
_AFXWIN_INLINE CWinApp AFXAPI AfxGetApp()
{ return afxCurrentWinApp; }
以上就是关于mfc中怎么获取子窗口中控件的指针全部的内容,包括:mfc中怎么获取子窗口中控件的指针、求mfc线程问题,、MFC中SDI框架下多级对话框与文档类的数据交换等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)