十万火急,菜鸟求助打字测验程序,考试用
期末c++老师的考题是让我们自己做一个小程序(在所给的里面每两人选一道题),老师给出打印的源码(都是一段一段的分开的),让你见一个框架往里插。我什么也不回会求教高手帮帮忙,再过两天就要交了。还要写论文,做ppt到时上台演示。关键是我不懂往哪插,高手做好后可以发到我邮箱,非常谢谢。并希望与高手做一个真正的朋友。要求:
屏幕上有 三个矩形框,左内有三个气球,分别代表当前输入字符数,错误字符数和用时(秒);出示位置再下方;右便共有两个,上面显示一段范文,下为输入框;
输入(正确)用黑表示,(错)用红色显示;
左方框中,红色气球随输入的字符数而上升,绿色气球随输错而上升,蓝色随所用时间增加而上升;
用菜单选项“开始”开始测验(设置计数器)
预定时间(2分钟)用完后提示的范文字符全部输入后,结束程序并显示信息(用时,正确字符数和错误字符数)
下面时我自己敲出来老师给的代码:
(可能有些输入时的错误)
//Typing Test View.h : interface of the CTyping Test View class
#define TIMELIMIT 120 时间120秒
class CTyping Test View :public CView
{
public:
CString m_strText; //范文文本
int m_nCurCharPos; //当前要输入的字符在范文中的位置
char m_CurChar; //用户实际输入的字符
bool m_bJustCorrect; //用户输入的字符是否正确
bool m_bJustPressKey; //用户是否刚输入字符
int m_nTotalNum; //总录入字符数
int m_nWrongNum; //录入错误字符数
int m_nTimeCount; //时钟计数器
CPoint m_pointCursor; //当前输入字符在测试区的显示位置
CRect m_rectInfor; //信息窗大小
CRect m_rectModel; //范文窗大小
CRect m_rectTest; //测试窗大小
CRect m_rectTotalBall; //红球位置
CRect m_rectWrongBall; //绿球位置
CRect m_TimeBall; //蓝球位置
CBitmap m_bmpTotal; //红球位图
CBitmap m_bmpWrong; //绿球位图
CBitmap m_bmpTime; //蓝球位图
int m_nTimeStep; //蓝球步进量
int m_nCharStep; //红绿球步进量
bool m_bStarsted; //开始练习标示
void Initialize(); //初始化函数
void ShowBKgnd(CDC*pDC,CDC*pMemDC); //显示背景函数
void ShowContent(CDC*pDC); //显示范文函数
void ShowChar(CDC*pDC); //显示用户输入的字符的函数
};
自定义函数initialize()用来初始化状态变量,代码如下;
voidCTypingTestView::Initialize()
{
//气球的初始位置
m_rectTotalBall=CRect(m_rectInfor.left+1,m_rectInfor.bottom-49,m_rectInfor.left+48,
m_rectInfor.bottom);
m_rectWrongBall=CRect(m_rectInfor.left+48,m_rectInfor.bottom-49,m_rectInfor.left+95,
m_rectInfor.bottom);
m_rectTimeBall=CRect(m_rectInfor.left+95,m_rectInfor.bottom-49,m_rectInfor.left+143,
m_rectInfor.bottom); // 设置当前所要输入的字符在范文中的起始位置
m_nCurCharPos=0;//用户输入字符在测试中的显示位置
m_point(m_rectTest.left+1,m_rectTest.top+1);//输入总字符数`错误时间初始化
m_nTotalNum=0;
m_nWrongNum=0;
m_nTimeCount=TIMELIMIT;
m_bStarted=false;
m_bjustPressKey=false;
m_bjustCorrect=false;
}
自定义函数ShowBkGnd()用来显示整个背景:
void CTypingTestView::ShowBkGnd(CDC*pDC,CDC*pMemDC)
{CBrush BKBsh(RGB(0,0,100));
pDC->SelectObject(&BKBsh);
pDC->Rectangle(0,0,800,500);
CBrush InforBsh(RGB(0,225,0));
pDC->SelectObject(&InforBsh);
pDC->Rectangle(&m_rectInfor);
pDc->Draw3dRect(&m_rectInfor,RGB(0,0,0),RGB(255,255,255));
CBrush MedolBsh(RGB(125,0,125));
pDC->SelectObject(&MedolBsh);
pDC->Rectangle(&m_rectModel);
pDC->Draw3dRect(&m_rectModel,RGB(0,0,0),RGB(255,255,255));//画测试输入框
CBrush TestBush(RGB(255,255,255));
pDC->SelectObject(&TestBsh);
pDC->Rectangle(&m_rectTest);
pDC_Draw3dRect(&m_rectTest,RGB(0,0,0),RGB(255,255,255));//提示显示文字
pDC->SetBKColor(RGB(0,0,100));
COLORREF oldColor=pDC->SetTextColor(RGB(0,255,0));
pDC->TextOut(m_rectInfor.left,m_rectInfor.top-20,_T("信息区"));
pDC->SetTextColor(RGB(200,0,200));
pDC->TextOut(m_rectModel.left,m_rectModel.top-20,_T("范文区"));
pDC->SetTextColor(RGB(200,0,0));
pDC->TextOut(m_rectrectTest.left,m_rectTest.top-20,_T("测试区"));
pMemDC->SelectObject(&m_bmpTotal);
pDC->BitBlt(m_rectTotalBall.left,m_rectTotalBall.top,48,48,pMemDC,0,0,SRCCOPY);
pDC->TextOut(m_rectInfor.left+1,m_rectInfor.bottom+2,_T("录入数"));
CString tmp;
tmp.Format("%d",m_nTotalNum);
pDC->TextOut(&m_rectInfor.left+16,&m_rectInfor.bottom+22,tmp);
pMemDC->SelectObject(&m_bmpWrong);
pDC->BitBlt(m_rectWrongBall.left,m_rectWrongBall.top,48,48,pMemDC,0,0,SRCCOPY);
pDC->TextOut(&m_rectInfor.left+48,&m_rectInfor.bottom+2,_T("错误数"));
tmp.Format("%d",m_nWrongNum);
pDC->TextOut(&m_rectInfor.left+60,m_rectInfor.bottom+22,tmp);
pMemDC->SelectObject(&m_bmpTime);
pDC->BitBlt(m_rectTimeBall.left,m_rectTimeBall.top,48,48,pMemDC,0,0,SRCCOPY);
pDC->TextOut(m_rectInfor.left+95,&m_rectInfor.bottom+2,_T("剩余时间"));
tmp.Format("%d",m_nTimeCount);
pDC->TextOut(&m_rectInfor.left+120,m_rectInfor.bottom+22,tmp);
pDC->SetTextColor(oldColor);
}
自定义函数ShowContent()用来显示范文,以回车符作为换行标志;
void CTypingTestView::ShowContent(CDC*pDC)
{
CPoint tmp=CPoint(m_rectModel.left+1,m_rectModel.top+1);
for(int i=0;i<m_strText.GetLength();i++)
{switch(m_strText[i])
{case'\r'://如果是回车换行显示
tmp.x=m_rectModel.left+1;
tmp.y+=30;
break;
default:
pDC->SetBkColor(RGB(125,0,125));
pDC->SetTextColor(RGB(255,255,0));
tmp.x+=10;
pDC->TextOut(tmp.x-10,tmp.y,m_strText[i]);
break;
}
}
}
自定义函数ShowChar()用来显示用户输入的字符:
void CTypingTestView::ShowChar(CDC*pDC)
{
pDC->SetBkColor(RGE(255,255,255)); //如果用户的输入正确
if(m_bjustCorrect)
pDC->SetTextColor(RGE(0,0,0)); //用黑色显示
else
pDC->SetTextColor(RGE(255,0,0)); //否则用红色显示
pDC->TextOut(m_pointCursor.x-10,m_pointCursor.y,m_CurChar);
}
在视图类的构造函数中,代码如下:
CTypingTestView::CTypingTestView()
{
//范文初始化,\r代表回车符
m_strText="Thepastyears,justlikeasong,\ralwaysfingerinmyheart,\revokingthosegloriousmemories.";
//三个背景框的位置
m_rectInfor=CRect(10,40,154,405);
m_rectModel=CRect(180,40,720,180);
m_rectTest=CRect(180,270,720,410);
//装入红、绿、蓝、三个气球的位图
m_bmpTotal.LoadBitmap(IDB_RED);
m_bmpWrong.LoadBitmap(IDB_GREEN);
m_bmpTime.LoadBitmap(IDB_BLUE);
BITMAP bitMap;
m_bmpTotal.GetBitmap(&bitMap);
//计算时间气球的步进量,这样当时间结束时气球刚好到达顶部
m_nTimeStep=m_rectInfor.Height()/(TIMELIMIT+3);
//计算每个字符的步进量,这样当字符输完事气球刚好到达顶部
m_nCharStep=(m_rectInfor.Height()-bitMap.bmHeight)/(m_strTect.GetLength()-2);
//初始化状态变量
Initialize();
}
"开始"菜单的消息处理:
void CTypingTestView::OnStart()
{
if(!m_bStarted)
{
SetTimer(1,1000,NULL) //开始计时
m_bStarted=true; //设置开始标识
}
}
定时器的消息处理主要更新时间计数器和气球位置,并判断时间是否结束:
void CTypingTestView::OnTimer(UINT nIDEvent)
{
m_nTimeCout--; //时间计数器减一秒
//擦除时间气球
InvalidateRect(CRect(m_rectInfor.left+16,m_rectInfor.bottom+22,m_rectInfor.left+150,m_rectInfor.bottom+42));
InvalidateRect(&m_rectTimeBall); //改变气球位置
m_rectTimeBall.top-=m_nTimeStep;
m_rectTimeBall.bottom-=m_nTimeStep; //刷新
InvalidateRect(&m_rectTimieBall,FALSE);
if(m_nTimeCount==0) //时间到,结束
{
CRect rectTmp=CRect(m_rectInfor.left+16,m_rectInfor.bottom+22,m_rectInfor.right.bottom+22+15);
InvalidateRect(rectTmp);
KillTimer(1);
CString tmp;
tmp.Format("%d",TIMELIMIT-m_nTimeCount);
CString tmpl="规定时间已到!";
tmpl+="用时"+tmp+"秒";
tmp.Format("%d",m_nTotalNum-m_nWrongNum);
tmp;+="正确字符数"+tmp+";";
tmp.Format("%d",m_nWrongNum);
tmpl+="错误字符数"+tmp;
MessageBox(tmpl);
Initialize();
Invalidate();
}
CView::OnTimer(nDEvent);
}
键盘消息相应函数处理用户的字符输入,
void CTypingTestView::OnChar(UINT nChar,UINT nRepCnt,UINT nFlags)
{
if(m_bStarted)
{
if(nChar>32&&nChar<=126) //所有可见的ASCII码字符的输入
{
m_nTotalNum++; //输入字符总数加一
//刷新显示
InvalidateRect(&m_rectTotalBall);
m_rectTotalBall.top-=m_nCharStep;
m_rectTotalBall.bottom-=m_nCharStep;
InvalidateRect(&m_rectTotalBGall,FALSE);
if((char)nChar!=m_steText[m_nCurCharPos]) //如果输入字符和范文不同
{
m_nWrongNum++; //错误字符加一
//刷新显示
InvalidateRect(&m_rectWrongBall);
m_rectWrongBall.top-=m_nCharStep;
m_rectWrongBall.bottom-=m_nCharStep;
InvalidateRect(&m_rectWrongBall,FALSE);
m_bjustVorrect=false; //验证状态变量置假
}
else
m_bjustCorrect=ture; //验证状态变量置真
m_CurChar=nChar;//记录用户的输入以便显示
m_nCurCharPos++;//字符位置加一
CRect tmp=CRect(m_pointCursor.x,m_pointCursor.y,m_pointCursor.x+10,m_pointCursor.y+30);
InvalidateRect(&tmp,FALSE);//刷新显示
//范文中的回车作为范文的换行符,用要求用户输入
if(m_nCurCharPos<m_strText.GetLength()&&m_strText[m_nCurCharPos]=='\r')
{
m_nCurCharPos++//跳过回车,前进到下一个字符
m_pointCursor=CPoint(m_rectTest.lsft+1,m_pontCursor.y+30);//显示位置换行
}
else
m_pointCursor.x=m_pointCursor.x+10;
m_bJustPressKey=true;
if(m_nTotalNum>=(m_strText.GetLength()-2))//判断范文是否已经输完
{
CRect rectTmp=CRect(m_rectInfor.left+16,m_rectInfor.bottom+22.m_rectInfor.right,m_rectInfor.bottom+22+15);
InvalidateRect(rectTmp);
KillTimer(1);
CString tmp;
tmp.Format("%d",TIMELIMIT-m_nTimeCount);
CString tmpl="输入范文结束!";
tmpl+="用时"+tmp+"秒;";
tmp.Format("%d",m_ntotalNum-m_nwrongNum);
tmp;+="正确字符数"+tmp+";";
tmp.Format("%d",m_nWrongNum);
tmpl+="错误字符数"+tmp;
MessageBox(tmpl);
Initialize();
Invalidate();
}
}
}
}
修改视图类的OnDraw函数:
void CTypingTestView::OnDraw(CDC*pDC)
{
CTypingTestDoc*pDoc=GetDocument();
ASSERT_VALID(pDoc);
CDC MemDC;
MemDC.CreateCompatibleDC(pDC);
ShowBkGed(pDC,&MemDC);
ShowContent(pDC);
if(m_bStarted)
{
if(m_bJustPressKey)
{
ShowChar(pDC);
m_bJustPressKey=false;
}
}
}