MFC中多线程怎么调用窗口类成员函数

MFC中多线程怎么调用窗口类成员函数,第1张

当前界面的线程

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线程和工作线程的创建和参等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/9529157.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-29
下一篇 2023-04-29

发表评论

登录后才能评论

评论列表(0条)

保存