1)在VS开发环境,基于MFC创建一个名为ThreadProcess的工程,自动生成窗口类CThreadProcessDlg,一个ThreadProcessDlg.cpp和ThreadProcessDlg.h文件
2)在工具栏拉出一个Progress Control控件,默认ID:IDC_PROGRESS1,添加控件变量,设置其变量名为m_speed,
在该窗口类的头文件中的public中自动生成CProgressCtrl m_speed;
3)添加3个按钮控件h和一个Edit Control控件(给其添加int型变量:m_Var1).窗口布局如下图:
4)在ThreadProcess.h文件中的private中添加全局变量
private:
HANDLE m_ThreadSpeed; //声明这个句柄是用于接受创建线程时返回的句柄,可以使用这个句柄对线程控制
5)自己新建.h文件,在该文件中自定义一个结构体,用于传递参数到多线程函数中去。新建.h文件方法:在解决方案中选择 “头文件” -》右键 -》添加 -》新建项 ,选择头文件-》输入名称。我这里的名称为“ThreadFuantion.h”。下面是我新建的头文件中添加的内容。主要是建立了一个结构体,用于存储需要传递到多线程程序中的各种类型的变量
#include "stdafx.h"
#include <iostream>
#include <windows.h>
#include <process.h>
typedef struct tag_Param
{
HANDLE hMutex;
int thread_id;
int var1;
int var2;
CWnd* kk;
bool bStop;
}TESTPARAM;
6)在ThreadProcessDlg.h文件中申明一个结构体。
private:
TESTPARAM TestParam;
7)双击窗体中的【开始】按钮 在其响应函数中创建一个线程:
//开始
void CThreadProcessDlg::OnBnClickedButton1()
{
m_ThreadSpeed = CreateThread(\
0, //lpThreadAttributes:指向SECURITY_ATTRIBUTES型态的结构的指针。
0, //dwStackSize, 设置初始栈的大小,以字节为单位,如果为0,那么默认将使用与调用该函数的线程相同的栈空间大小
ThreadSpeed, //lpStartAddress,指向线程函数的指针,形式:@函数名,函数名称没有限制,
//但是必须以下列形式声明:DWORD WINAPI 函数名 (LPVOID lpParam) ,格式不正确将无法调用成功。
reinterpret_cast<LPVOID *>(&TestParam),//向线程函数传递的参数,是一个指向结构的指针,不需传递参数时,为NULL。
0, //线程标志,可取值如下 a) CREATE_SUSPENDED(0x00000004):创建一个挂起的线程, b) 0:表示创建后立即激活。c)...
0); //保存新线程的id。
// CloseHandle(m_ThreadSpeed); //一般创建后马上关闭线程句柄,因为主线程不关系创建的新线程。如果创建新线程后马上注销的话,
//不能再对线程进行 挂起 唤醒等操作
}
注意:对结构体类型的强制转换,非常必要!!!
8)双击【+1】添加如下代码 每按一次【+1】按钮变量m_Var1自增10;
void CThreadProcessDlg::OnBnClickedButton2()
{
// TODO: 在此添加控件通知处理程序代码
m_Var1+=10;
TestParam.kk = this;
TestParam.var1=m_Var1;
UpdateData(false);
}
9)8)双击【-1】添加如下代码 每按一次【-1】按钮变量m_Var1自减10;
void CThreadProcessDlg::OnBnClickedButton3()
{
// TODO: 在此添加控件通知处理程序代码
m_Var1-=10;
TestParam.kk = this;
TestParam.var1=m_Var1;
TestParam.var2=m_Var1;
UpdateData(false);
}
10)同样在ThreadProcessDlg.cpp文件中添加开辟新线程的执行函数
//线程函数的实现
DWORD WINAPI CThreadProcessDlg::ThreadSpeed(LPVOID lpParameter)
{
int Count;
TESTPARAM *ptr=reinterpret_cast<TESTPARAM *>(lpParameter); //lpParameter参数带来了丰富的信息,具体自己可以在结构体中定义
CThreadProcessDlg *Dlg=(CThreadProcessDlg *)ptr->kk; //TestParam.kk = this;将主窗口的指针带回,方便获取其中变量和资源
CWnd * pwnd = Dlg->GetDlgItem(IDC_PROGRESS1); //通过窗体指针,获取进度条的句柄
CProgressCtrl *Speed = (CProgressCtrl*)pwnd; //获取进度条的指针,从而方便在新开辟的线程中对其操作
Speed->SetRange(0,100); //设置进度条的范围
while(1) //while(1)循环,只要主线程中的m_Var1改变,我们就能在进度条上反映出来
{
Speed->SetPos(Dlg->m_Var1);
_sleep(200);
}
return 0;
}
最终实现:按下【开始】开辟新线程, 按下【+1】或【-10】改变m_Var1,自定义的结构将改变的变量传递给线程执行的函数。从而改变进度条的位置。