编程论坛's Archiver

wlf348 发表于 2008-6-27 19:48

十万火急,菜鸟求助打字测验程序,考试用

期末c++老师的考题是让我们自己做一个小程序(在所给的里面每两人选一道题),老师给出打印的源码(都是一段一段的分开的),让你见一个框架往里插。我什么也不回会求教高手帮帮忙,再过两天就要交了。还要写论文,做ppt到时上台演示。关键是我不懂往哪插,高手做好后可以发到我邮箱,非常谢谢。并希望与高手做一个真正的朋友。
要求:
屏幕上有 三个矩形框,左内有三个气球,分别代表当前输入字符数,错误字符数和用时(秒);出示位置再下方;右便共有两个,上面显示一段范文,下为输入框;
输入(正确)用黑表示,(错)用红色显示;
左方框中,红色气球随输入的字符数而上升,绿色气球随输错而上升,蓝色随所用时间增加而上升;
用菜单选项“开始”开始测验(设置计数器)
预定时间(2分钟)用完后提示的范文字符全部输入后,结束程序并显示信息(用时,正确字符数和错误字符数)
[tk03] 下面时我自己敲出来老师给的代码:
(可能有些输入时的错误)
//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;
                }
        }
}

wlf348 发表于 2008-6-27 19:51

我的邮箱wbl-bo@163.com

页: [1]

Powered by Discuz! Archiver 6.1.0  © 2001-2007 Comsenz Inc.