【经验】C++|在MFC子线程中,通过正确的传参,访问主线程对话框程序的控件对象、调用类函数

引言

MFC中子线程操控窗口的控件的难点在于:
子线程函数不属于窗口类

比方说,
窗口类CMFCApplication3Dlg的点击事件函数如下:

void CMFCApplication3Dlg::OnBnClickedCheck2()
{
	// 其中uploadThread为子线程函数
	CWinThread* mythread = AfxBeginThread(uploadThread, NULL);
}

而子线程的函数却只能这样:

UINT uploadThread(LPVOID lpParam){}

那么,用子线程访问CMFCApplication3Dlg的类成员呢?

答案——传参

我的需求有两个:
① 在子线程中控制控件;
② 在子线程中使用类函数。

前者传递CWnd*句柄指针即可,而后者传递Dlg*指针即可。全程不需要用到消息机制,就硬传参。

可以看一下2013年这篇博客,它用到了消息机制,也传了参,他是对的,可是这真的很麻烦,不是吗?CSDN博客:MFC子线程访问主线程对话框程序的控件对象_2013-11-27 14:17:08

开始

首先,构建一个参数结构体:

typedef struct Param1 {
	CMFCApplication3Dlg* pDlg;
	CWnd* upBtn;
	CWnd* dlBtn;
	CWnd* upEdit;
	CWnd* dlEdit;
}uploadParam;
uploadParam param_content; //全局定义参数结构体

然后,在你需要的时候,对结构体变量赋值,并传递到子线程里去:

注意下面代码中的this,对于我这种小白来说,根本不知道还有这操作。

void CMFCApplication3Dlg::OnBnClickedCheck2()
{
	param_content.pDlg = this;
	param_content.upBtn = GetDlgItem(IDC_BUTTON6);
	// 其中uploadThread为子线程函数
	CWinThread* mythread = AfxBeginThread(uploadThread, &param_content);
}

传递进去之后,再在子线程中取我们的参数:

UINT uploadThread(LPVOID lpParam)
{
	uploadParam* param = (uploadParam*)lpParam;
	param->upBtn->SetWindowTextA("test");
	//MyClassFunc是你在类里面自定义的函数
	param->pDlg->MyCLassFunc(123);
}

就行了,贼容易。

可能遇到的问题

CreateThread创建线程无法传参:CreateThreadWin32 API中的。MFC要用AfxBeginThread创建线程。

② MSDN官方文档:使用 C++ 和 MFC 进行多线程编程_MSDN。(不详细,不建议看)

posted @ 2021-11-14 10:47  shandianchengzi  阅读(18)  评论(0编辑  收藏  举报  来源