先看一下效果图..
进度条的进度是创建一个新的线程控制,当单击"开始"按钮时,就创建一个线程,在这个线程中控制进度条的进度,这样就可以对窗口进行其他
操作,要是没有创建一个新的线程控制进度,则整个程序需要等待进度条执行完后才能进行其他操作....
对于进度条控件关联了一个控件变量m_speed
CProgressCtrl m_speed;
DDX_Control(pDX, IDC_PROGRESS1, m_speed);
在头文件中
声明线程函数
static DWORD WINAPI ThreadSpeed(LPVOID lpParameter);
这里需要注意我为什么将线程函数声明为静态函数,后面我会讲解
声明这个句柄是用于接受创建线程时返回的句柄,可以使用这个句柄对线程控制,如挂起,唤醒以及终止等等操作
HANDLE m_ThreadSpeed;
声明的按钮函数,双击按钮由编译器自动生成的
afx_msg void OnBnClickedButton2(); //"开始"按钮函数
afx_msg void OnBnClickedButton1(); //"挂起"按钮函数
afx_msg void OnBnClickedButton3(); //"唤醒"按钮函数
afx_msg void OnBnClickedButton4(); //"终止"按钮函数
在cpp文件中
线程函数的实现
DWORD WINAPI CSpeedDlg::ThreadSpeed(LPVOID lpParameter) { CProgressCtrl *Speed = (CProgressCtrl*)lpParameter; Speed->SetRange(0,100000); //设置进度条的范围 for (int i = 0; i < 100000; i++) { Speed->SetPos(i); //进度条的位置 } return 0; }
"开始"按钮函数的实现
void CSpeedDlg::OnBnClickedButton2() { // TODO: 在此添加控件通知处理程序代码 m_ThreadSpeed = CreateThread(0,0,ThreadSpeed,&m_speed,0,0); //创建线程 }
线程挂起时进度条停止前进,当线程唤醒时进度条继续前进,当线程终止时,进度条永远不会在前进,除非再次单击"开始"按钮创建新线程进度条从新开始
//挂起线程函数 void CSpeedDlg::OnBnClickedButton1() { // TODO: 在此添加控件通知处理程序代码 SuspendThread(m_ThreadSpeed); //挂起线程函数,参数为线程句柄 } //唤醒线程函数 void CSpeedDlg::OnBnClickedButton3() { // TODO: 在此添加控件通知处理程序代码 ResumeThread(m_ThreadSpeed); //唤醒挂起的线程 } //终止线程函数 void CSpeedDlg::OnBnClickedButton4() { // TODO: 在此添加控件通知处理程序代码 TerminateThread(m_ThreadSpeed,0); //终止线程 SendMessage(WM_CLOSE); //发送WM_CLOSE消息关闭窗口,退出程序 }
这里我来谈谈为什么线程函数声明时为什么要定义成静态,如果不是静态函数则在CreateThread()函数中引用线程函数
出错,看图片
因为我定义的线程函数在类里,如果不是静态函数,调用时需要定义一个对象,有对象调用该函数,而我这里定义为静态函数使得这个函数
不属于任何对象,可以直接调用,就可以解决上面图片里出的问题,如果线程函数定义为一个全局变量,也就是在类的外面定义,则不需要这样
定义为静态函数,
因为我这里把线程函数定义为了静态变量,而m_spend不是静态变量,它是进度控件的控件变量,定义为CProgressCtrl类的对象,我不知怎么
来把它定义为静态的,如果直接static CProgressCtrl m_speed,这样的话会出错,这样m_speed不能在线程函数中使用,出现的错误是
所以我的解决办法是让m_speed作为参数传给线程函数,然后在线程函数中定义一个CProgressCtrl类的指针类型对象来接受m_speed,
不过这里要记得类型的强制转换,修改后正如上面线程函数实现代码一样