第 47 章
函数主要参数的意义。
? hThread:线程句柄。
? dwThreadAffinityMask:线程的相似xìng掩码。
(2)SetThreadIdealProcessor 函数
该函数用于为线程设定合适的处理器。当线程等待时间到,系统将在这个处理器上执行
指定的线程,如果调用成功,将返回上一次的处理器数目或者MAXIMUM_PROCESSORS,
否则返回-1。它的函数原型如下:
DWORD SetThreadIdealProcessor(
HANDLE hThread,
枫叶文学网www.fywxw.com
第9 章 多线程
·217·
DWORD dwIdealProcessor
);
函数中主要参数的意义如下。
? hThread:线程句柄。
? dwIdealProcessor:可以执行指定线程的处理器数目,如果dwIdealProcessor 的值为
MAXIMUM_PROCESSORS,说明该线程没有合适的处理器。
9.实例:赛马程序
实例9-1:赛马程序实例。源代码在光盘中“\09\实例9-1\Racing”目录下。
为了帮助读者理解上述线程的基本知识,为后续高级技术打好基础,本节的最后给出一
个多线程编程实例,模拟赛马的过程。
(1)创建工程
首先利用VC++6.0 的AppWizard 创建基于对话框的工程Racing,所有设置都采用默认选
项。
给对话框添加控件。包括1 个图片框、1 个组合框、3 个静态文本控件、3 个滑动杆控件、
4 个按钮。控件的属xìng如表9-4 所示。
表9-4 控件属xìng列表
ID 属xìng或作用 控件类型
IDC_RACINGBOX Frcom 图像框控件
IDC_STATIC 速度设置 组合框控件
IDC_STATIC 红马 静态文本控件
IDC_STATIC 绿马 静态文本控件
IDC_STATIC 蓝马 静态文本控件
IDC_SLIDERR 红马速度 滑动杆控件
IDC_SLIDERG 绿马速度 滑动杆控件
IDC_SLIDERB 蓝马速度 滑动杆控件
IDSTART 开始 按钮
IDSTOP 停止 按钮
IDPAUSE 暂停 按钮
IDCANCEL 关闭 按钮
(2)定义数据结构
定义一个包含赛马信息的结构HORSE,代码如下:
typedef struct _horse
{
HWND hWnd; // 窗口句柄
int speed; // 马速度
int x; // 马位置的x 坐标
int y; // 马位置的y 坐标
int size; // 马的大小, 用一个球来表示,size 是半径
COLOR color; // 颜色
CRect rect; // 表示跑道的矩形;
枫叶文学网www.fywxw.com
Visual C++ 6.0 程序设计从入门到精通
·218·
}HORSE, *LPHORSE;
(3)设置全局变量
定义Mutex 句柄和名称的全局变量,代码如下:
// Mutex 对象的名称
char g_strRNcom[64] = "RedHorse";
char g_strGNcom[64] = "GreenHorse";
char g_strBNcom[64] = "BlueHorse";
// Mutex 对象的句柄
HANDLE g_hRMutex;
HANDLE g_hGMutex;
HANDLE g_hBMutex;
(4)添加成员变量
为CRacingDlg 添加3 个赛马信息的成员变量,包括红色、绿色、蓝色3 匹马。添加3
个线程句柄的成员变量,以及一个线程是否暂停的成员变量,代码如下:
// 定义红, 绿, 蓝3 匹马
HORSE m_RedHorse;
HORSE m_GreenHorse;
HORSE m_BlueHorse;
// 定义红, 绿, 蓝3 匹马各自线程的句柄
HANDLE m_hRed;
HANDLE m_hGreen;
HANDLE m_hBlue;
// 是否暂停状态
BOOL m_bPaused;
为控件添加成员变量,代码如下:
// 设置红马的速度
CSliderCtrl m_BSpeed;
// 设置绿马的速度
CSliderCtrl m_GSpeed;
// 设置蓝马的速度
CSliderCtrl m_RSpeed;
// 跑道矩形
CStatic m_RacingBox;
(5)初始化信号量
为CRacingDlg 添加初始化函数InitMutexes,用来创建Mutex 对象,代码如下:
枫叶文学网www.fywxw.com
第9 章 多线程
·219·
BOOL CRacingDlg::InitMutexes()
{
// 初始化红马的Mutex
g_hRMutex = CreateMutex(NULL, FALSE, g_strRNcom);
if(g_hRMutex == NULL)
{
return FALSE;
}
// 初始化绿马的Mutex
g_hGMutex = CreateMutex(NULL, FALSE, g_strGNcom);
if(g_hGMutex == NULL)
{
return FALSE;
}
// 初始化蓝马的Mutex
g_hBMutex = CreateMutex(NULL, FALSE, g_strBNcom);
if(g_hBMutex == NULL)
{
return FALSE;
}
return TRUE;
}
(6)初始化控件
为CRacingDlg 添加初始化函数InitDlgItem,用来初始化对话框的控件,代码如下:
void CRacingDlg::InitDlgItem()
{
// 设置滑动杆的范围和初始位置
m_RSpeed.SetRange(10, 100);
m_RSpeed.SetPos(50);
m_GSpeed.SetRange(10, 100);
m_GSpeed.SetPos(50);
m_BSpeed.SetRange(10, 100);
m_BSpeed.SetPos(50);
// 暂停按钮的初始状态
m_bPaused = FALSE;
枫叶文学网www.fywxw.com
Visual C++ 6.0 程序设计从入门到精通
·220·
CButton* pBtn;
// 开始按钮的状态为TRUE
pBtn = (CButton*)GetDlgItem(IDSTART);
pBtn->EnableWindow(TRUE);
// 暂停按钮的状态为TRUE
pBtn = (CButton*)GetDlgItem(IDPAUSE);
pBtn->EnableWindow(FALSE);
// 结束按钮的状态为TRUE
pBtn = (CButton*)GetDlgItem(IDSTOP);
pBtn->EnableWindow(FALSE);
}
(7)实现线程函数
实现线程函数ThreadProc,代码如下:
extern DWORD WINAPI ThreadProc(LPVOID lpParam)
{
LPHORSE lpHorse;
HANDLE hMutex;
lpHorse = LPHORSE(lpParam);
// 打开Mutex 对象
if( lpHorse->color == RED )
{
hMutex = ::OpenMutex(MUTEX_ALL_ACCESS, FALSE, g_strRNcom);
}
else if ( lpHorse->color == GREEN )
{
hMutex = ::OpenMutex(MUTEX_ALL_ACCESS, FALSE, g_strGNcom);
}
else if ( lpHorse->color == BLUE )
{
hMutex = ::OpenMutex(MUTEX_ALL_ACCESS, FALSE, g_strBNcom);
}
枫叶文学网www.fywxw.com
第9 章 多线程
·221·
else
return 1; // 颜色不对
if( hMutex == NULL )
{
AfxMessageBox("open Mutex error...");
return 1;
}
// 循环,等待信号
while ( true )
{
if ( WaitForSingleObject(hMutex, INFINITE) == WAIT_FAILED )
{
continue;
}
// 马前进
if ( lpHorse->x < lpHorse->rect.right )
{
lpHorse->x ++;
}
// 重绘窗口
InvalidateRect(lpHorse->hWnd, lpHorse->rect, TRUE);
// 释放Mutex
ReleaseMutex(hMutex);
// 等待, 速度快的等待时间短
Sleep(lpHorse->speed);
}
return 0;
}
(8)初始化对话框
改写对话框的OnInitDialog,进行必要的初始化,代码如下:
BOOL CRacingDlg::OnInitDialog()
枫叶文学网www.fywxw.com
Visual C++ 6.0 程序设计从入门到精通
·222·
{
……
// TODO: Add extra initialization here
// 初始化Mutex
InitMutexes();
// 初始化对话框
InitDlgItem();
……
}
(9)绘制场景
为CRacingDlg 添加成员函数DrawScene,用来绘制赛马的场景,代码如下:
// 绘制场景的函数
void CRacingDlg::DrawScene(CPaintDC * pDC)
{
CRect rect;
CBrush redBrush(RGB(255, 0, 0));
CBrush greenBrush(RGB(0, 255, 0));
CBrush blueBrush(RGB(0, 0, 255));
CBrush* oldBrush;
m_RacingBox.GetClientRect(rect);
m_RacingBox.ClientToScreen(rect);
pDC->Rectangle(rect);
// 绘制红马
if( m_hRed )
{
pDC->Rectangle(m_RedHorse.rect);
oldBrush = pDC->SelectObject(&redBrush);
pDC->Ellipse(m_RedHorse.x-m_RedHorse.size, m_RedHorse.y-m_RedHorse.size,
m_RedHorse.x+m_RedHorse.size, m_RedHorse.y+m_RedHorse.size);
pDC->SelectObject(oldBrush);
}
// 绘制绿马
if( m_hGreen )
枫叶文学网www.fywxw.com
第9 章 多线程
·223·
{
pDC->Rectangle(m_GreenHorse.rect);
oldBrush = pDC->SelectObject(&greenBrush);
pDC->Ellipse(m_GreenHorse.x-m_GreenHorse.size, m_GreenHorse.y-m_GreenHorse.size,
m_GreenHorse.x+m_GreenHorse.size, m_GreenHorse.y+m_GreenHorse.size);
pDC->SelectObject(oldBrush);
}
// 绘制蓝马
if( m_hBlue )
{
pDC->Rectangle(m_BlueHorse.rect);
oldBrush = pDC->SelectObject(&blueBrush);
pDC->Ellipse(m_BlueHorse.x-m_BlueHorse.size, m_BlueHorse.y-m_BlueHorse.size,
m_BlueHorse.x+m_BlueHorse.size, m_BlueHorse.y+m_BlueHorse.size);
pDC->SelectObject(oldBrush);
}
}
改写CRacingDlg 的OnPaint 函数,调用DrawScene,代码如下:
void CRacingDlg::OnPaint()
{
if (IsIconic())
{
……
}
else
{
CPaintDC dc(this); // device context for painting
CDialog::OnPaint();
// 绘制场景
DrawScene(&dc);
}
}
(10)响应“开始”按钮
响应“开始”按钮,用来启动线程,代码如下:
void CRacingDlg::OnStart()
{
// TODO: Add your control notification handler code here
枫叶文学网www.fywxw.com
Visual C++ 6.0 程序设计从入门到精通
·224·
DWORD tID;
DWORD code;
CRect clientrect;
CRect racingrect;
GetClientRect(clientrect);
ClientToScreen(clientrect);
m_RacingBox.GetClientRect(racingrect);
m_RacingBox.ClientToScreen(racingrect);
racingrect -= clientrect.TopLeft();
if( !GetExitCodeThread(m_hRed, &code) ||
code != STILL_ACTIVE )
{
// 填写红马信息
m_RedHorse.hWnd = this->GetSafeHwnd();
m_RedHorse.color = RED;
m_RedHorse.speed = m_RSpeed.GetPos();
m_RedHorse.size = 10;
m_RedHorse.rect.TopLeft() = racingrect.TopLeft();
m_RedHorse.rect.right = m_RedHorse.rect.TopLeft().x + racingrect.Width();
m_RedHorse.rect.bottom = m_RedHorse.rect.TopLeft().y + racingrect.Height()/3;
m_RedHorse.x = m_RedHorse.rect.left + m_RedHorse.size;
m_RedHorse.y = m_RedHorse.rect.top + m_RedHorse.rect.Height()/2;
// 创建红马线程
m_hRed = CreateThread(NULL, 0, ThreadProc, &m_RedHorse, 0, &tID);
if(m_hRed == NULL)
{
AfxMessageBox("创建线程失败");
}
}
if( !GetExitCodeThread(m_hGreen, &code) ||
code != STILL_ACTIVE )
{
枫叶文学网www.fywxw.com
第9 章 多线程
·225·
// 填写绿马信息
m_GreenHorse.hWnd = this->GetSafeHwnd();
m_GreenHorse.color = GREEN;
m_GreenHorse.speed = m_GSpeed.GetPos();
m_GreenHorse.size = 10;
m_GreenHorse.rect.TopLeft() = racingrect.TopLeft()+CPoint(0, racingrect.Height()/3);
m_GreenHorse.rect.right = m_GreenHorse.rect.TopLeft().x + racingrect.Width();
m_GreenHorse.rect.bottom = m_GreenHorse.rect.TopLeft().y + racingrect.Height()/3;
m_GreenHorse.x = m_GreenHorse.rect.left + m_GreenHorse.size;
m_GreenHorse.y = m_GreenHorse.rect.top + m_GreenHorse.rect.Height()/2;
// 创建绿马线程
m_hGreen = CreateThread(NULL, 0, ThreadProc, &m_GreenHorse, 0, &tID);
if(m_hGreen == NULL)
{
AfxMessageBox("创建线程失败");
}
}
if( !GetExitCodeThread(m_hBlue, &code) ||
code != STILL_ACTIVE )
{
// 填写蓝马信息
m_BlueHorse.hWnd = this->GetSafeHwnd();
m_BlueHorse.color = BLUE;
m_Blue
松语文学免费小说阅读_www.16sy.com
? hThread:线程句柄。
? dwThreadAffinityMask:线程的相似xìng掩码。
(2)SetThreadIdealProcessor 函数
该函数用于为线程设定合适的处理器。当线程等待时间到,系统将在这个处理器上执行
指定的线程,如果调用成功,将返回上一次的处理器数目或者MAXIMUM_PROCESSORS,
否则返回-1。它的函数原型如下:
DWORD SetThreadIdealProcessor(
HANDLE hThread,
枫叶文学网www.fywxw.com
第9 章 多线程
·217·
DWORD dwIdealProcessor
);
函数中主要参数的意义如下。
? hThread:线程句柄。
? dwIdealProcessor:可以执行指定线程的处理器数目,如果dwIdealProcessor 的值为
MAXIMUM_PROCESSORS,说明该线程没有合适的处理器。
9.实例:赛马程序
实例9-1:赛马程序实例。源代码在光盘中“\09\实例9-1\Racing”目录下。
为了帮助读者理解上述线程的基本知识,为后续高级技术打好基础,本节的最后给出一
个多线程编程实例,模拟赛马的过程。
(1)创建工程
首先利用VC++6.0 的AppWizard 创建基于对话框的工程Racing,所有设置都采用默认选
项。
给对话框添加控件。包括1 个图片框、1 个组合框、3 个静态文本控件、3 个滑动杆控件、
4 个按钮。控件的属xìng如表9-4 所示。
表9-4 控件属xìng列表
ID 属xìng或作用 控件类型
IDC_RACINGBOX Frcom 图像框控件
IDC_STATIC 速度设置 组合框控件
IDC_STATIC 红马 静态文本控件
IDC_STATIC 绿马 静态文本控件
IDC_STATIC 蓝马 静态文本控件
IDC_SLIDERR 红马速度 滑动杆控件
IDC_SLIDERG 绿马速度 滑动杆控件
IDC_SLIDERB 蓝马速度 滑动杆控件
IDSTART 开始 按钮
IDSTOP 停止 按钮
IDPAUSE 暂停 按钮
IDCANCEL 关闭 按钮
(2)定义数据结构
定义一个包含赛马信息的结构HORSE,代码如下:
typedef struct _horse
{
HWND hWnd; // 窗口句柄
int speed; // 马速度
int x; // 马位置的x 坐标
int y; // 马位置的y 坐标
int size; // 马的大小, 用一个球来表示,size 是半径
COLOR color; // 颜色
CRect rect; // 表示跑道的矩形;
枫叶文学网www.fywxw.com
Visual C++ 6.0 程序设计从入门到精通
·218·
}HORSE, *LPHORSE;
(3)设置全局变量
定义Mutex 句柄和名称的全局变量,代码如下:
// Mutex 对象的名称
char g_strRNcom[64] = "RedHorse";
char g_strGNcom[64] = "GreenHorse";
char g_strBNcom[64] = "BlueHorse";
// Mutex 对象的句柄
HANDLE g_hRMutex;
HANDLE g_hGMutex;
HANDLE g_hBMutex;
(4)添加成员变量
为CRacingDlg 添加3 个赛马信息的成员变量,包括红色、绿色、蓝色3 匹马。添加3
个线程句柄的成员变量,以及一个线程是否暂停的成员变量,代码如下:
// 定义红, 绿, 蓝3 匹马
HORSE m_RedHorse;
HORSE m_GreenHorse;
HORSE m_BlueHorse;
// 定义红, 绿, 蓝3 匹马各自线程的句柄
HANDLE m_hRed;
HANDLE m_hGreen;
HANDLE m_hBlue;
// 是否暂停状态
BOOL m_bPaused;
为控件添加成员变量,代码如下:
// 设置红马的速度
CSliderCtrl m_BSpeed;
// 设置绿马的速度
CSliderCtrl m_GSpeed;
// 设置蓝马的速度
CSliderCtrl m_RSpeed;
// 跑道矩形
CStatic m_RacingBox;
(5)初始化信号量
为CRacingDlg 添加初始化函数InitMutexes,用来创建Mutex 对象,代码如下:
枫叶文学网www.fywxw.com
第9 章 多线程
·219·
BOOL CRacingDlg::InitMutexes()
{
// 初始化红马的Mutex
g_hRMutex = CreateMutex(NULL, FALSE, g_strRNcom);
if(g_hRMutex == NULL)
{
return FALSE;
}
// 初始化绿马的Mutex
g_hGMutex = CreateMutex(NULL, FALSE, g_strGNcom);
if(g_hGMutex == NULL)
{
return FALSE;
}
// 初始化蓝马的Mutex
g_hBMutex = CreateMutex(NULL, FALSE, g_strBNcom);
if(g_hBMutex == NULL)
{
return FALSE;
}
return TRUE;
}
(6)初始化控件
为CRacingDlg 添加初始化函数InitDlgItem,用来初始化对话框的控件,代码如下:
void CRacingDlg::InitDlgItem()
{
// 设置滑动杆的范围和初始位置
m_RSpeed.SetRange(10, 100);
m_RSpeed.SetPos(50);
m_GSpeed.SetRange(10, 100);
m_GSpeed.SetPos(50);
m_BSpeed.SetRange(10, 100);
m_BSpeed.SetPos(50);
// 暂停按钮的初始状态
m_bPaused = FALSE;
枫叶文学网www.fywxw.com
Visual C++ 6.0 程序设计从入门到精通
·220·
CButton* pBtn;
// 开始按钮的状态为TRUE
pBtn = (CButton*)GetDlgItem(IDSTART);
pBtn->EnableWindow(TRUE);
// 暂停按钮的状态为TRUE
pBtn = (CButton*)GetDlgItem(IDPAUSE);
pBtn->EnableWindow(FALSE);
// 结束按钮的状态为TRUE
pBtn = (CButton*)GetDlgItem(IDSTOP);
pBtn->EnableWindow(FALSE);
}
(7)实现线程函数
实现线程函数ThreadProc,代码如下:
extern DWORD WINAPI ThreadProc(LPVOID lpParam)
{
LPHORSE lpHorse;
HANDLE hMutex;
lpHorse = LPHORSE(lpParam);
// 打开Mutex 对象
if( lpHorse->color == RED )
{
hMutex = ::OpenMutex(MUTEX_ALL_ACCESS, FALSE, g_strRNcom);
}
else if ( lpHorse->color == GREEN )
{
hMutex = ::OpenMutex(MUTEX_ALL_ACCESS, FALSE, g_strGNcom);
}
else if ( lpHorse->color == BLUE )
{
hMutex = ::OpenMutex(MUTEX_ALL_ACCESS, FALSE, g_strBNcom);
}
枫叶文学网www.fywxw.com
第9 章 多线程
·221·
else
return 1; // 颜色不对
if( hMutex == NULL )
{
AfxMessageBox("open Mutex error...");
return 1;
}
// 循环,等待信号
while ( true )
{
if ( WaitForSingleObject(hMutex, INFINITE) == WAIT_FAILED )
{
continue;
}
// 马前进
if ( lpHorse->x < lpHorse->rect.right )
{
lpHorse->x ++;
}
// 重绘窗口
InvalidateRect(lpHorse->hWnd, lpHorse->rect, TRUE);
// 释放Mutex
ReleaseMutex(hMutex);
// 等待, 速度快的等待时间短
Sleep(lpHorse->speed);
}
return 0;
}
(8)初始化对话框
改写对话框的OnInitDialog,进行必要的初始化,代码如下:
BOOL CRacingDlg::OnInitDialog()
枫叶文学网www.fywxw.com
Visual C++ 6.0 程序设计从入门到精通
·222·
{
……
// TODO: Add extra initialization here
// 初始化Mutex
InitMutexes();
// 初始化对话框
InitDlgItem();
……
}
(9)绘制场景
为CRacingDlg 添加成员函数DrawScene,用来绘制赛马的场景,代码如下:
// 绘制场景的函数
void CRacingDlg::DrawScene(CPaintDC * pDC)
{
CRect rect;
CBrush redBrush(RGB(255, 0, 0));
CBrush greenBrush(RGB(0, 255, 0));
CBrush blueBrush(RGB(0, 0, 255));
CBrush* oldBrush;
m_RacingBox.GetClientRect(rect);
m_RacingBox.ClientToScreen(rect);
pDC->Rectangle(rect);
// 绘制红马
if( m_hRed )
{
pDC->Rectangle(m_RedHorse.rect);
oldBrush = pDC->SelectObject(&redBrush);
pDC->Ellipse(m_RedHorse.x-m_RedHorse.size, m_RedHorse.y-m_RedHorse.size,
m_RedHorse.x+m_RedHorse.size, m_RedHorse.y+m_RedHorse.size);
pDC->SelectObject(oldBrush);
}
// 绘制绿马
if( m_hGreen )
枫叶文学网www.fywxw.com
第9 章 多线程
·223·
{
pDC->Rectangle(m_GreenHorse.rect);
oldBrush = pDC->SelectObject(&greenBrush);
pDC->Ellipse(m_GreenHorse.x-m_GreenHorse.size, m_GreenHorse.y-m_GreenHorse.size,
m_GreenHorse.x+m_GreenHorse.size, m_GreenHorse.y+m_GreenHorse.size);
pDC->SelectObject(oldBrush);
}
// 绘制蓝马
if( m_hBlue )
{
pDC->Rectangle(m_BlueHorse.rect);
oldBrush = pDC->SelectObject(&blueBrush);
pDC->Ellipse(m_BlueHorse.x-m_BlueHorse.size, m_BlueHorse.y-m_BlueHorse.size,
m_BlueHorse.x+m_BlueHorse.size, m_BlueHorse.y+m_BlueHorse.size);
pDC->SelectObject(oldBrush);
}
}
改写CRacingDlg 的OnPaint 函数,调用DrawScene,代码如下:
void CRacingDlg::OnPaint()
{
if (IsIconic())
{
……
}
else
{
CPaintDC dc(this); // device context for painting
CDialog::OnPaint();
// 绘制场景
DrawScene(&dc);
}
}
(10)响应“开始”按钮
响应“开始”按钮,用来启动线程,代码如下:
void CRacingDlg::OnStart()
{
// TODO: Add your control notification handler code here
枫叶文学网www.fywxw.com
Visual C++ 6.0 程序设计从入门到精通
·224·
DWORD tID;
DWORD code;
CRect clientrect;
CRect racingrect;
GetClientRect(clientrect);
ClientToScreen(clientrect);
m_RacingBox.GetClientRect(racingrect);
m_RacingBox.ClientToScreen(racingrect);
racingrect -= clientrect.TopLeft();
if( !GetExitCodeThread(m_hRed, &code) ||
code != STILL_ACTIVE )
{
// 填写红马信息
m_RedHorse.hWnd = this->GetSafeHwnd();
m_RedHorse.color = RED;
m_RedHorse.speed = m_RSpeed.GetPos();
m_RedHorse.size = 10;
m_RedHorse.rect.TopLeft() = racingrect.TopLeft();
m_RedHorse.rect.right = m_RedHorse.rect.TopLeft().x + racingrect.Width();
m_RedHorse.rect.bottom = m_RedHorse.rect.TopLeft().y + racingrect.Height()/3;
m_RedHorse.x = m_RedHorse.rect.left + m_RedHorse.size;
m_RedHorse.y = m_RedHorse.rect.top + m_RedHorse.rect.Height()/2;
// 创建红马线程
m_hRed = CreateThread(NULL, 0, ThreadProc, &m_RedHorse, 0, &tID);
if(m_hRed == NULL)
{
AfxMessageBox("创建线程失败");
}
}
if( !GetExitCodeThread(m_hGreen, &code) ||
code != STILL_ACTIVE )
{
枫叶文学网www.fywxw.com
第9 章 多线程
·225·
// 填写绿马信息
m_GreenHorse.hWnd = this->GetSafeHwnd();
m_GreenHorse.color = GREEN;
m_GreenHorse.speed = m_GSpeed.GetPos();
m_GreenHorse.size = 10;
m_GreenHorse.rect.TopLeft() = racingrect.TopLeft()+CPoint(0, racingrect.Height()/3);
m_GreenHorse.rect.right = m_GreenHorse.rect.TopLeft().x + racingrect.Width();
m_GreenHorse.rect.bottom = m_GreenHorse.rect.TopLeft().y + racingrect.Height()/3;
m_GreenHorse.x = m_GreenHorse.rect.left + m_GreenHorse.size;
m_GreenHorse.y = m_GreenHorse.rect.top + m_GreenHorse.rect.Height()/2;
// 创建绿马线程
m_hGreen = CreateThread(NULL, 0, ThreadProc, &m_GreenHorse, 0, &tID);
if(m_hGreen == NULL)
{
AfxMessageBox("创建线程失败");
}
}
if( !GetExitCodeThread(m_hBlue, &code) ||
code != STILL_ACTIVE )
{
// 填写蓝马信息
m_BlueHorse.hWnd = this->GetSafeHwnd();
m_BlueHorse.color = BLUE;
m_Blue
松语文学免费小说阅读_www.16sy.com