当前位置: 首页 > 图文教程 > 开发语言 > VC++ > VC-文本框只能输入数字和小数 源文件

VC++
关于内联汇编的几个技巧
const使用详解
为什么要在operator=中返回*this的引用
如何在派生类中的隐藏基类的虚拟重载函数?
C++指针使用方法解惑
如何用编程获取CD-ROM的驱动器盘符?
声明函数指针并实现回调
定义函数对象
在名字空间中声明类和成员函数
自制性能测试类
为什么operator=操作符返回引用
单实例设计模式的实现
初始化类对象
C++编程杂谈之三:面向对象(续)
C++编程杂谈之二:面向对象
C++编程杂谈之一:编译器
解析动态联编(上篇) - 作者:tingya
解析动态联编(下篇) - 作者:tingya
创建和访问环境变量
在预先定义的内存位置构造一个对象

VC++ 中的 VC-文本框只能输入数字和小数 源文件


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-08-14   浏览: 939 ::
收藏到网摘: n/a

#include "stdafx.h"
#include "NumberEdit.h"

CNumberEdit::CNumberEdit()
{
 m_iAfterDotLen = 2;
 m_str = _T("0");
}

CNumberEdit::~CNumberEdit()
{
}

BEGIN_MESSAGE_MAP(CNumberEdit, CEdit)
 //{{AFX_MSG_MAP(CNumberEdit)
 ON_WM_CHAR()
 ON_CONTROL_REFLECT(EN_KILLFOCUS, OnKillfocus)
 //}}AFX_MSG_MAP
END_MESSAGE_MAP()

void CNumberEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
 // 修改消息响应
 if(nChar == 8)
 {
  //退格
  CEdit::OnChar(nChar, nRepCnt, nFlags);
  return;
 }
 BOOL bChange = FALSE;
 GetWindowText(m_str);
 if(CheckNumber(nChar,nRepCnt,nFlags))
 {
  //检查输入为数字
  bChange = TRUE;
 }
 else if(CheckOneMinus(nChar,nRepCnt,nFlags))
 {
  //检查只有一个负号,且只能是第一个字符
  bChange = TRUE;
 }
 else if(CheckOneDot(nChar,nRepCnt,nFlags))
 {
  //检查只有一个小数点
  bChange = TRUE;
 }
 if(bChange)
 {
  CEdit::OnChar(nChar, nRepCnt, nFlags);
 }
}

void CNumberEdit::OnKillfocus()
{
 // 修改消息响应
 //失去焦点时,小数按设置的小数点后数据长度补齐
 GetWindowText(m_str);
 if(m_str.IsEmpty()) 
 {
  //未输入数据则设为0
  m_str = "0";
 }
 else if(m_str.GetLength() == 1 && m_str[0] == TCHAR('-'))
 {
  //只输入了一个负号
  m_str = "0";
 }
 else
 {
  int iDotPos = m_str.Find(TCHAR('.'));
  if(iDotPos <0)
  {
   //没有找到小数点
   SetWindowText(m_str);
   return;
  }
  if(iDotPos >0)
  {
   //小数点后已有位数
   int iLen = m_str.GetLength() - 1 - iDotPos;
   if(iLen >= m_iAfterDotLen)
   {
    //已有位数超过设定
    return;
   }
   if (iLen == 0)
   {
    //小数点后没有数据则用0补齐
    m_str+="0";
   }
  }
 }
 SetWindowText(m_str);
}

BOOL CNumberEdit::CheckNumber(UINT nChar,UINT nRepCnt,UINT nFlags)
{
 if(::isdigit(nChar)==0)
 {
  //是否数字
  return FALSE;
 }
 //小数点位置
 int iDotPos = m_str.Find(TCHAR('.'));
 if(iDotPos >= 0)
 {
  //小数据点后数据长度
  int iLen = m_str.GetLength() - 1 - iDotPos;
  if( (GetCaretXPos() >= iDotPos) && (iLen >= m_iAfterDotLen))
  {
   //超过设置的长度
   return FALSE;
  }
 }
 return TRUE;
}

BOOL CNumberEdit::CheckOneMinus(UINT nChar,UINT nRepCnt,UINT nFlags)
{
 if(nChar != '-')
 {
  //不是'-'
  return FALSE;
 }
 if(GetCaretXPos() != 0)
 {
  //不在第一个位置
  return FALSE;
 }
 if(!m_str.IsEmpty() && m_str.GetAt(0) == TCHAR('-'))
 {
  return FALSE;
 }
 return TRUE;
}

BOOL CNumberEdit::CheckOneDot(UINT nChar,UINT nRepCnt,UINT nFlags)
{
 if (m_iAfterDotLen == 0)
 {
  //小数点后不加数据(限制为整数)
  return FALSE;
 }
 if(nChar != '.')
 {
  //不是小数点
  return FALSE;
 }
 if(m_str.Find(TCHAR('.')) >=0)
 {
  //已有小数点
  return FALSE;
 }
 int iPos = GetCaretXPos();
 if(iPos == 0)
 {
  //第一个字符就是小数点!
  return FALSE;
 }
 else if(iPos==1 && m_str[0] == TCHAR('-'))
 {
  //第一个字符是'-',第二个是小数点
  return FALSE;
 }
 return TRUE;
}

int CNumberEdit::GetCaretXPos()
{
 CPoint p = GetCaretPos();
 return (p.x - p.y)/6;
}

double CNumberEdit::GetDouble()
{
 GetWindowText(m_str);
 return atof(m_str);
}

long CNumberEdit::GetLong()
{
 GetWindowText(m_str);
 return atol(m_str);
}

void CNumberEdit::SetWindowText( CString str )
{
 m_str = str;
 char nChar;
 UINT nRepCnt = 0;
 UINT nFlags = 0;
 BOOL bChange = FALSE;
 for (int nstr = 0;nstr < str.GetLength() - 1;++nstr)
 {
  //取得字符
  nChar = str.GetAt(nstr);
  if(!CheckNumber(nChar,nRepCnt,nFlags) && (!CheckOneMinus

(nChar,nRepCnt,nFlags))
   && (!CheckOneDot(nChar,nRepCnt,nFlags)))
  {
   //检查初始化文本数据
   bChange = TRUE;
  }
 }
 if(!bChange)
 {
  int iDotPos = m_str.Find(TCHAR('.'));
  if(iDotPos >0)
  {
   //小数点后已有位数
   int iLen = m_str.GetLength() - 1 - iDotPos;
   if (iLen == 0)
   {
    //小数点后没有数据则用0补齐
    m_str+="0";
   }
  }
  CEdit::SetWindowText(m_str);
 }
}