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

VC++
透明窗体的又一实现
橡皮区矩形 CRectTracker C# 实现
Visual Basic .NET 中多 Windows 窗体的同步
轻松实现类 MSDN 2002 界面(二)
轻松实现类 MSDN 2002 界面
数据库开发之窗体编程
一个打印报表的简单的类
SDK 程序使用SkinMagic工具包换皮肤
Windows SDK笔记(七):创建MDI窗口
Windows SDK笔记(六):使用对话框资源建立窗口
Windows SDK笔记(五):非模式对话框
Windows SDK笔记(四):模式对话框
也谈如何隐藏显示在任务栏中的对话框程序
一个托盘程序演示 -闹钟 Alert
think window procedure
再谈 CFileDialog 对话框的定制
获得 Win32 窗口句柄的更好的方法
个人考勤软件开发实例配套代码 2.1版(Update)
介绍一个操作DHTML表格的C++对象
Windows资源管理器Web视图界面

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


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