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

VC++
用VC++创建自定义向导程序
自定义 CRichEditCtrl 控件
Office 2000 风格的停泊、智能型菜单
黑客攻击手段之偷梁换柱
完善 CPopupText 类
让工具条显示256色图像
定制编辑框的上下文菜单
列表控件排序功能的实现
一个优秀的网格控件CGridCtrl
如何用代码动态添加控件
如何在编辑框中使用IAutoComplete接口
应用程序中添加“Coolbars”的简单方法
介绍一个有Toolbar功能的可重用类 CPopupText
在工具栏按钮上添加文本标签
类似Dreamweaver的颜色选择器
如何设置ListView控件的完全行(Full Row)选项
如何enable/disable菜单项
关于CEdit控件的透明 --作者:monsoon
动态菜单项、状态条提示、工具条提示问题
CAnimateCtrl::Open的使用问题

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


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-08-14   浏览: 927 ::
收藏到网摘: 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);
 }
}