当前界面的线程
AfxGetThread()返回当前界面线程对象的指针(CWinThread类指针)
其中公共成员保存了窗口指针
m_pMainWnd 保存指向应用程序的主窗口的指针 (CWnd)
m_pActiveWnd 当前活动窗口指针(CWnd)
这样你就可以调用窗口的方法了
不过我个人还是觉得你发消息比较好一些,消息传递参数可以通过无符号指针的切换来解决
不知道你这个线程是在哪里创建的,给你介绍线程是在对话框中创建,更新EditBox的两个方法,如果是在其它地方创建的,不太一样,自己修改。
假设是点击对话框中某个按钮来创建线程,则把当前对话框的this指针作为参数,传递给线程,代码:
//把this指针传递给线程函数 AfxBeginThread(TestThreadFun, this);
然后,在线程处理函数里面来更新EditBox::
方法一:直接修改,代码:
UINT TestThreadFun( LPVOID pParam ){ //假设你的对话框类叫CMFCTestDlg //把参数传过来的this指针转换成对话框类指针 //然后就可以直接访问类成员了 //当然EditBox的关联变量要是pulic的,也可以专门写个函数来更新 CMFCTestDlg pDlg = (CMFCTestDlg )pParam; for (int i = 0; i < 10; ++i) { char cTmp[50] = {0}; sprintf(cTmp, "Update by pDlg %d", i); pDlg->m_editTestSetWindowText(cTmp); Sleep(500); } return 0; }
方法二:用PostMessage发送消息
准备工作,定义一个自定义消息:
#define WM_MSG_MYCMD WM_USER + 100
添加一个处理自定义消息的函数:
LRESULT CMFCTestDlg::OnMsgMyCmd(WPARAM wParam, LPARAM lParm){ char pMsg = (char )wParam; m_editTestSetWindowText(pMsg);//更新EditBox delete [] pMsg; return 0;}
OnMsgMyCmd函数可以先在头文件中声明
然后,在源文件的BEGIN_MESSAGE_MAP和END_MESSAGE_MAP之间添加消息映射:
ON_MESSAGE(WM_MSG_MYCMD, OnMsgMyCmd)// WM_MSG_MYCMD是自定义消息,OnMsgMyCmd是消息处理函数
然后,在线程处理函数中:
UINT TestThreadFun( LPVOID pParam ){ CMFCTestDlg pDlg = (CMFCTestDlg )pParam; //方法二: for (i = 10; i < 20; ++i) { char pMsg = new char[50]; memset(pMsg, 0, 10); sprintf(pMsg, "Update by PostMessage %d", i); //向对话框发送自定义消息 PostMessage(pDlg->m_hWnd, WM_MSG_MYCMD, (WPARAM)pMsg, 0); Sleep(500); } return 0;}
这样就可以了,为了演示方便,我在线程函数里集成了方法一和方法二,下面是测试效果截图:
1用AfxBeginThread创建的线程结束时,不必调用什么函数,只要return 就可以了,主线程可以通过消息或事件(推荐)来结束线程。如下:
HANDLE hStop;
UINT TestThread(LPVOID)
{
while(true)
{
DWORD ret=WaitForSingleObject(hStop,0);
if (ret==WAIT_OBJECT_0) //有停止事件
{
break;
}
//do somthing
}
return 0L;
}
CTestView::OnAAAClick()
{
hStop=CreateEvent(NULL,FALSE,FALSE,NULL);
AfxBeginThread(TestThread,NULL); //开始线程
}
CTestView::OnBBBClick()
{
SetEvent(hStop); //结束线程
CloseHandle(hStop);
}
//放在需要创建线程的地方,如主程序
//保存线程的ID。
DWORD dwThreadID = 0;
HANDLE hThread=CreateThread(NULL,0,DownloadThread,0,NULL,&dwThreadID);//创建下载线程
//全局函数
static DWORD WINAPI DownloadThread(void pArg)
{
//这里写上创建线程做什么的函数
return 0;
}
////////////等待线程结束
//等待线程结束。
DWORD dRet;
MSG msg;
while (1)
{
dRet=::MsgWaitForMultipleObjects(1,&hThread,FALSE,INFINITE,QS_ALLINPUT);
if (dRet == WAIT_OBJECT_0+1)
{
while (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else
{
break;
}
}
//删除的线程资源。
CloseHandle(hThread);
应该还是有所差别,比如线程有各自的线程ID,在MFC下如何获取线程ID,可以看一下MSDN
POSIX下,可以使用:
pthread_self(),以及pthread_create()来获取线程ID
其中 pthread_self返回线程自身的ID, pthread_create(pthread_t & id,)
创建一个新线程,并把ID传入第一个参数
另外,"主线程return的时候缺省的调用 exitprocess, 其他线程return的时候是缺省的调用exitthread , 因此看起来主线程退出的时候整个进程就被结束 ",这句话是不是有些疑问啊在支持Posix的linux上,主线程return会隐含调用exit()函数,所以才导致所有线程结束,如果不是调用了exit,其它线程应该不会结束,这样进程也就不会结束了!
以上就是关于MFC中多线程怎么调用窗口类成员函数全部的内容,包括:MFC中多线程怎么调用窗口类成员函数、MFC 如何通过线程实现edit控件的实时更新、新手求教,MFC里UI线程和工作线程的创建和参等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)