一个键盘程序的开发实例

发表于:2007-07-01来源:作者:点击数: 标签:
这个程序本来是写给我得女友,因为她刚刚开始学习计算机所以他要学习键盘指法。程序是基 于对话框的应用程序。(本人用的 开发 环境是VC.net)这个程序加入了一个名为 CC lr Button的类 这是一个基于CButton的派生类。当对话框初始化函数中(OnInitDialog())设置


 这个程序本来是写给我得女友,因为她刚刚开始学习计算机所以他要学习键盘指法。程序是基
于对话框的应用程序。(本人用的开发环境是VC.net)这个程序加入了一个名为CClrButton的类
这是一个基于CButton的派生类。当对话框初始化函数中(OnInitDialog())设置了以下内容
m_strtest="asdfghjklrtetioertrjbnxcniisns";//设置了要测试的内容
m_bBegin=FALSE;//设置了游戏是否处于开始状态
m_charlen=0;//要测试文字的个数
m_iError=0;//统计数据的错误字节数
//下面四行在给统计数据区设置文字
GetDlgItem(IDC_WORD)->SetWindowText("测试区");
GetDlgItem(IDC_RIGHT)->SetWindowText("???");
GetDlgItem(IDC_COUNTCHAR)->SetWindowText("???");
GetDlgItem(IDC_ERROR)->SetWindowText("???");
//在给按钮进行初始化和初始化着色
initialize();
ReColor();


当单击开始时执行以下操作
m_iError=0;//将错误数赋值为0
//以下是来显示统计数据区的测试字符总数和输入错误字符数
CString strcharcount,strerror;
strcharcount.Format("%d",m_strtest.GetLength());
GetDlgItem(IDC_COUNTCHAR)->SetWindowText(strcharcount);
//这两个函数是显示错误字节数和错误率
ShowError(m_iError);
ShowErrorLv(m_iError);
//将“开始”按钮设置为不可用
GetDlgItem(IDC_BUTTON2)->EnableWindow(FALSE);
//安装钩子(键盘钩子)
hHook=SetWindowsHookEx(WH_KEYBOARD,KeyFunc,0,GetCurrentThreadId());
//设置两个时钟(这也是这个程序的核心程序,后面我会详细介绍)
SetTimer(1,2000,NULL);
SetTimer(2,750,NULL);
//设置开始状态
m_bBegin=TRUE;
//还没有按下键盘
m_bin=false;


以下是显示错误字节数和错误率的函数
// 显示错误字节数
void CKeyIIIDlg::ShowError(int m_error)
{
  CString str;
  str.Format("%d",m_error);
  GetDlgItem(IDC_ERROR)->SetWindowText(str);
}

// 显示错误率
void CKeyIIIDlg::ShowErrorLv(int m_error)
{
  CString str;
  float m_charright=0;
  if(m_error==0)//如果错误数等于0
  {
    m_charright=100;
    str.Format("%.2f",m_charright);
    GetDlgItem(IDC_RIGHT)->SetWindowText(str);
  }
  if(m_error>0)//如果错误数大于0
  {
    m_charright=((float)m_strtest.GetLength()/m_iError);
    if(m_charright==1)
      m_charright=0;
    str.Format("%.2f",m_charright);
    GetDlgItem(IDC_RIGHT)->SetWindowText(str);
  }
  if(m_error<0)//如果错误数小于0
  {
    str="计算错误率错误!";
    GetDlgItem(IDC_RIGHT)->SetWindowText(str);
  }
}


以下是判断按下的键盘是否正确
// 判断按下的键盘是否正确
int CKeyIIIDlg::IsKeyRight(CString m_szcurchar)
{
  if(m_szcurchar.GetLength()>0)
  {
    if(m_szcurchar==m_AsIIToChar)
      return 1;//字符比较正确
    else
      return 2;//字符比较错误
  }
  /*
  else
  {
    MessageBox("没有测试字符!","错误",MB_ICONERROR | MB_OK);
    return 0;//程序错误
  }
  */
  return 1;
}


下面是关闭按钮的处理函数
void CKeyIIIDlg::OnBnClickedClose()
{
  // TODO: 在此添加控件通知处理程序代码
  //如果还设置了钩子函数(就是说还没有结束练习)就按下了关闭按钮则要卸载钩子把状态
改为没有//开始测试
  if(hHook)
    UnhookWindowsHookEx(hHook);
  if(m_bBegin)
    m_bBegin=FALSE;
//关闭对话框即关闭程序
  SendMessage(WM_CLOSE);
}


最后来说一下这个程序和核心部分两个时钟的处理,代码如下:
void CKeyIIIDlg::OnTimer(UINT nIDEvent)
{
  // TODO: 在此添加消息处理程序代码和/或调用默认值
  switch(nIDEvent)
  {
   //这个时钟的作用是为了显示文字
  case 1:
    if(m_charlen<m_strtest.GetLength())
    {
      m_curtest=m_strtest.Mid(m_charlen,1);
      GetDlgItem(IDC_WORD)->SetWindowText(m_curtest);
      m_charlen++;
      if(!m_bin)//如果在开始测试以后用户没有按下任何键盘则也认为是错误
      {
        Sleep(1000);
        m_iError++;
        ShowError(m_iError);
        ShowErrorLv(m_iError);
      }
      m_bin=false;
    }
    else//如果显示完毕后作一些收尾工作
    {
      KillTimer(1);  
      ReColor();
MessageBox("测试结束!\r\n确定后测试结果将被擦除!","恭喜",MB_ICONWARNING | MB_O
K);
      GetDlgItem(IDC_WORD)->SetWindowText("测试区");
      GetDlgItem(IDC_RIGHT)->SetWindowText("???");
      GetDlgItem(IDC_COUNTCHAR)->SetWindowText("???");
      GetDlgItem(IDC_ERROR)->SetWindowText("???");
      m_bBegin=FALSE;
    }
    ReColor();//每次擦除按下键盘后按钮变色的色彩
    break;
  //第二个时钟的作用是判断输入是否正确,并更改测试结果
  case 2:
    //判断输入是否正确,并更改测试结果
    if(m_bin)//是否已经按下的键盘
    {
      if(m_bBegin)//是否已经开始了练习
      {
        m_icharright=IsKeyRight(m_curtest);
        switch(m_icharright)
        {
        case 1://字符比较正确
          m_bin=true;
          break;
        case 2://字符比较错误
          m_iError++;
          break;
        case 0://程序错误
          MessageBox("程序错误,请通知我!","错误",MB_ICONERROR | MB_OK);
          KillTimer(2);
          KillTimer(1);
          OnBnClickedClose();//关闭程序
          break;
        }
        ShowError(m_iError);
        ShowErrorLv(m_iError);
      }
      else
      {
        KillTimer(2);
        ReColor();
        GetDlgItem(IDC_BUTTON2)->EnableWindow();
        UnhookWindowsHookEx(hHook);
        m_charlen=0;
      }

    }

    break;
    CDialog::OnTimer(nIDEvent);
  }
}
其实这个程序也可以使用多线程来实现的,但由于本人比较懒一些所以就用了两个时钟来完
成的。为什么本人写了两个时钟是因为当用户看到文字后要有一个反应的过程。而两个时钟一
个长一个短也是着原因下面加了一幅图来帮助大家理解一下.

原文转自:http://www.ltesting.net