mfc slider control 用法(debug assertion failed错误)

1、单界面使用mfc中的slider控件

①添加button按钮和slider control控件(前者ID;IDOK,后者ID:IDC_SLIDER1)


②添加CSliderCtrl类的对象m_ctrlSlider(全局变量)

CSliderCtrl m_ctrlSlider;

③在DoDataExchange中添加变量和控件关联,注意是CxxxDlg(xxx=工程名字,我就是一直添加错位置,导致出错)

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}
void CdemoDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_SLIDER1, m_ctrlSlider);     //在此添加
}

④在按钮控件中添加

void CdemoDlg::OnBnClickedOk()
{
	m_ctrlSlider.SetRange(0, 100); 
	for (int i= 0; i < 100; i++){
		m_ctrlSlider.SetPos(i);
		Sleep(25);
	}
}

2、单界面使用mfc中的slider控件(使用线程调用

①其余操作不变,在.h中添加一个变量,一个结构体,一个函数即可

//在类中添加,protected类型
CWinThread* pThread; //创建线程
//结构体和方法在头文件最后添加
struct threadInfo //保存线程执行函数参数
{
	CDC *pDC;
	CRect rect;
};
UINT MyFunction(LPVOID lpParam); //线程执行函数

②.cpp中调用修改一下,添加一个全局变量,button下启动线程,线程调用头文件中的函数

threadInfo Info;//保存线程执行函数参数
void Cdemo1Dlg::OnBnClickedOk()
{
	pThread = AfxBeginThread(MyFunction, &Info);//启动线程
}
UINT MyFunction(LPVOID lpParam){
	m_ctrlSlider.SetRange(0, 100);
	for (int i = 0; i < 100; i++){
		m_ctrlSlider.SetPos(i);
		Sleep(25);
	}
	return 0;
}
总结:不用线程写的时候,程序运行时,不能终止。用线程写的时候,程序运行时,可以点击右上角‘X’,可以终止程序。

3、多界面使用mfc中的slider控件

①有两个界面:一个主界面,一个被调用界面(主界面ID:IDD_DEMO_DIALOG,子界面ID:IDD_son

②主界面就留一个button键;子界面的类名为son,有一个button和一个slider控件(前者ID;IDOK,后者ID:IDC_SLIDER1)


③主界面如何实现调用子界面(第一步添加子界面对应的头文件,第二创建该类的对象,库函数调用)

#include"son.h"                       //第一步
void CdemoDlg::OnBnClickedOk()        //第二步
{
	son stp;
	stp.DoModal();
}

④子界面slider功能的实现(步骤如上1)

4、多界面使用进程使用mfc中的slider控件

①同上-->3①

②同上-->3②

③同上-->3③

④同上-->2

⑤错误,虽然在运行的过程中能停止,但是会终止线程,导致赋值指针异常,报错


1)、添加窗口右上角关闭事件的响应函数

界面右键--》类向导--》消息---》WMCLOSE(添加成功,会自动生成OnClose函数)

2)、在关闭函数执行之前,结束线程,也可以停止线程赋值操作也行

思路:定义一个全局变量,触发关闭事件时,修改其值,直接终止线程或者停止线程赋值操作(后者比较麻烦,只是暂停,并没有终止线程,一旦flag的值为假时,该线程又复活了,可以再添加标记,彻底结束这个线程)

int flag;    //方法一、直接终止
UINT MyFunction(LPVOID lpParam){
	flag = 0;
	m_ctrlSlider.SetRange(0, 100);
	for (int i = 0; i < 100; i++){
		m_ctrlSlider.SetPos(i);
		Sleep(25);
		//停止线程
		if (flag){
			return 0;
		}
	}
	return 0;
}
void son::OnClose()
{
	flag = 1;
	CDialogEx::OnClose();
}

int isrun;    //方法二,先停止赋值,再通过标志,终止线程
int flag;
void son::OnBnClickedOk()
{
	// TODO:  在此添加控件通知处理程序代码
	isrun = 0;
	flag = 0;
	pThread = AfxBeginThread(MyFunction, &Info);//启动线程  
}
UINT MyFunction(LPVOID lpParam){
	isrun = 1;
	if (isrun){
		m_ctrlSlider.SetRange(0, 100);
		for (int i = 0; i < 100 && isrun; i++){
			m_ctrlSlider.SetPos(i);
			Sleep(25);
			//暂停线程赋值操作
			while (flag){
			}
		}
	}
	return 0;
}
void son::OnClose()
{
	flag = 1;
	CDialogEx::OnClose();
}
两种方法终止线程,避免错误。             源码下载

猜你喜欢

转载自blog.csdn.net/hqh131360239/article/details/79542747
今日推荐