📄 racingdlg.cpp
字号:
// RacingDlg.cpp : implementation file
//
#include "stdafx.h"
#include "Racing.h"
#include "RacingDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
extern DWORD WINAPI ThreadProc(LPVOID lpParam);
extern char g_strRName[64];
extern char g_strGName[64];
extern char g_strBName[64];
extern HANDLE g_hRMutex;
extern HANDLE g_hGMutex;
extern HANDLE g_hBMutex;
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CRacingDlg dialog
CRacingDlg::CRacingDlg(CWnd* pParent /*=NULL*/)
: CDialog(CRacingDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CRacingDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CRacingDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CRacingDlg)
DDX_Control(pDX, IDC_SLIDERR, m_RSpeed);
DDX_Control(pDX, IDC_SLIDERG, m_GSpeed);
DDX_Control(pDX, IDC_SLIDERB, m_BSpeed);
DDX_Control(pDX, IDC_RACINGBOX, m_RacingBox);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CRacingDlg, CDialog)
//{{AFX_MSG_MAP(CRacingDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDSTART, OnStart)
ON_BN_CLICKED(IDSTOP, OnStop)
ON_WM_HSCROLL()
ON_BN_CLICKED(IDPAUSE, OnPause)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CRacingDlg message handlers
BOOL CRacingDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
// 初始化mutex
InitMutexes();
// 初始化对话框
InitDlgItem();
return TRUE; // return TRUE unless you set the focus to a control
}
void CRacingDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CRacingDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CPaintDC dc(this); // device context for painting
CDialog::OnPaint();
// 绘制场景
DrawScene(&dc);
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CRacingDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
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;
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);
}
BOOL CRacingDlg::InitMutexes()
{
// 初始化红马的Mutex
g_hRMutex = CreateMutex(NULL, FALSE, g_strRName);
if(g_hRMutex == NULL)
{
return FALSE;
}
// 初始化绿马的Mutex
g_hGMutex = CreateMutex(NULL, FALSE, g_strGName);
if(g_hGMutex == NULL)
{
return FALSE;
}
// 初始化蓝马的Mutex
g_hBMutex = CreateMutex(NULL, FALSE, g_strBName);
if(g_hBMutex == NULL)
{
return FALSE;
}
return TRUE;
}
// 绘制场景的函数
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 )
{
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);
}
}
void CRacingDlg::OnStart()
{
// TODO: Add your control notification handler code here
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 )
{
// 填写绿马信息
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_BlueHorse.speed = m_BSpeed.GetPos();
m_BlueHorse.size = 10;
m_BlueHorse.rect.TopLeft() = racingrect.TopLeft()+CPoint(0, racingrect.Height()*2/3);
m_BlueHorse.rect.right = m_BlueHorse.rect.TopLeft().x + racingrect.Width();
m_BlueHorse.rect.bottom = m_BlueHorse.rect.TopLeft().y + racingrect.Height()/3;
m_BlueHorse.x = m_BlueHorse.rect.left + m_BlueHorse.size;
m_BlueHorse.y = m_BlueHorse.rect.top + m_BlueHorse.rect.Height()/2;
// 创建蓝马线程
m_hBlue = CreateThread(NULL, 0, ThreadProc, &m_BlueHorse, 0, &tID);
if(m_hBlue == NULL)
{
AfxMessageBox("创建线程失败");
}
}
// 设置按钮状态
CButton* pBtn;
pBtn = (CButton*)GetDlgItem(IDSTART);
pBtn->EnableWindow(FALSE);
pBtn = (CButton*)GetDlgItem(IDPAUSE);
pBtn->EnableWindow(TRUE);
pBtn = (CButton*)GetDlgItem(IDSTOP);
pBtn->EnableWindow(TRUE);
}
void CRacingDlg::OnStop()
{
// TODO: Add your control notification handler code here
// 存放线程的退出码
DWORD code;
if (!GetExitCodeThread(m_hRed, &code) ||
code == STILL_ACTIVE)
{
TerminateThread(m_hRed, code);
CloseHandle(m_hRed);
}
if (!GetExitCodeThread(m_hGreen, &code) ||
code == STILL_ACTIVE)
{
TerminateThread(m_hGreen, code);
CloseHandle(m_hGreen);
}
if (!GetExitCodeThread(m_hBlue, &code) ||
code == STILL_ACTIVE)
{
TerminateThread(m_hBlue, code);
CloseHandle(m_hBlue);
}
// 初始化对话框控件
InitDlgItem();
}
void CRacingDlg::OnCancel()
{
// TODO: Add extra cleanup here
OnStop();
// 释放Mutex资源
CloseHandle(g_hRMutex);
CloseHandle(g_hGMutex);
CloseHandle(g_hBMutex);
CDialog::OnCancel();
}
void CRacingDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
// TODO: Add your message handler code here and/or call default
if( WaitForSingleObject(g_hRMutex, INFINITE) != WAIT_FAILED )
{
m_RedHorse.speed = 100 - m_RSpeed.GetPos();
ReleaseMutex(g_hRMutex);
}
if( WaitForSingleObject(g_hGMutex, INFINITE) != WAIT_FAILED )
{
m_GreenHorse.speed = 100 - m_GSpeed.GetPos();
ReleaseMutex(g_hGMutex);
}
if( WaitForSingleObject(g_hBMutex, INFINITE) != WAIT_FAILED )
{
m_BlueHorse.speed = 100 - m_BSpeed.GetPos();
ReleaseMutex(g_hBMutex);
}
CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
}
void CRacingDlg::OnPause()
{
// 得到button的指针
CButton* pBtn = (CButton*)GetDlgItem(IDPAUSE);
// 改变按钮的名称
if( !m_bPaused )
{
SuspendThread(m_hRed);
SuspendThread(m_hGreen);
SuspendThread(m_hBlue);
pBtn->SetWindowText("继续");
}
else
{
ResumeThread(m_hRed);
ResumeThread(m_hGreen);
ResumeThread(m_hBlue);
pBtn->SetWindowText("暂停");
}
// 改变按钮的状态
m_bPaused = !m_bPaused;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -