// NumEdit.cpp : 实现文件 // #include "stdafx.h" #include "NumEdit.h" // CNumEdit IMPLEMENT_DYNAMIC(CNumEdit, CEdit) CNumEdit::CNumEdit() { m_bNegative = FALSE; m_bPoint = FALSE; m_bZero = FALSE; } CNumEdit::~CNumEdit() { } BEGIN_MESSAGE_MAP(CNumEdit, CEdit) ON_WM_CHAR() END_MESSAGE_MAP() // CNumEdit 消息处理程序 void CNumEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) { // 获取插入符在客户区的坐标值; POINT caret; ::GetCaretPos(&caret); // 根据插入符位置获取最近的字符索引(插入符的前一个字符位置); caret.x = LOWORD(CharFromPos(caret)); CString strEdit; GetWindowText(strEdit); if ( strEdit.IsEmpty() ) {// 如果文本框空,一键还原; m_bPoint = FALSE; m_bZero = FALSE; m_bNegative = FALSE; } if ( strEdit.Find(_T(".")) == -1 ) m_bPoint = FALSE; if ( strEdit.Find(_T("-")) == -1 ) m_bNegative = FALSE; // 退格键处理; if (nChar == VK_BACK && strEdit.GetLength()) //退格键; { // 是否删除了小数点; if ( caret.x && strEdit[caret.x-1] == _T('.') ) m_bPoint = FALSE; // 是否删除了负号; if ( caret.x && strEdit[caret.x-1] == _T('-') ) m_bNegative = FALSE; if ( m_bNegative ) { if ( m_bPoint ) { if ( m_bZero && caret.x == 2 ) { m_bZero = FALSE; } } else { if ( m_bZero && caret.x == 2 && ( strEdit.GetLength() < 2 || strEdit[2] != _T('0')) ) { m_bZero = FALSE; } } } else { if ( m_bPoint ) { if ( m_bZero && caret.x == 1 ) { m_bZero = FALSE; } } else { if ( m_bZero && caret.x == 1 && ( strEdit.GetLength() < 1 || strEdit[1] != _T('0')) ) { m_bZero = FALSE; } } } CEdit::OnChar(nChar, nRepCnt, nFlags); } // 数字键处理; if (isdigit(nChar)) { // 判断是否已有负号,若字符在负号前,退出; if ( m_bNegative && caret.x == 0 ) return; if ( m_bNegative ) { // 负号前不能有任何字符,或者再输入负号; if ( caret.x == 0 || nChar == _T('-')) return; if ( m_bZero ) { // 前置零前后都不能再有零; if ( (caret.x == 1 || caret.x == 2 ) && nChar == _T('0') ) return; } else { // 负号的前置0只能在负号后面; if (caret.x == 1 && nChar == _T('0')) { m_bZero = TRUE; } } } else { if ( m_bZero ) { // 已有前置0,不能再设置前置0; if ( (caret.x == 0 || caret.x == 1) && nChar == _T('0')) return; } else { if (caret.x == 0 && nChar == _T('0')) { m_bZero = TRUE; } } } CEdit::OnChar(nChar, nRepCnt, nFlags); } else if (nChar == '-' && !m_bNegative) {// 负号只能在第一位; if (0 != caret.x) return; m_bNegative = TRUE; CEdit::OnChar(nChar, nRepCnt, nFlags); } else if (nChar == '.' && !m_bPoint) {//小数点可以在第一位,但不能在负号后面; if ( m_bNegative && caret.x == 1) {// 小数点不能在负号后面,即第二个字符索引; return; } m_bPoint = TRUE; CEdit::OnChar(nChar, nRepCnt, nFlags); } } BOOL CNumEdit::PreTranslateMessage(MSG* pMsg) { // TODO: 在此添加专用代码和/或调用基类 if ( pMsg->message == WM_KEYDOWN ) { if ( pMsg->wParam == VK_DELETE ) { POINT caret; ::GetCaretPos(&caret); // 根据插入符位置获取最近的字符索引(插入符的前一个字符位置); LONG nPos = LOWORD(CharFromPos(caret)); printf("NumEdit,%d,%d\t 插入符最近的字符位置:%d\n", caret.x, caret.y, nPos); CString strEdit; GetWindowText(strEdit); if (strEdit.GetLength()) { // 是否删除了小数点或负号; if ( strEdit.GetAt(nPos) == _T('.') ) m_bPoint = FALSE; if ( strEdit.GetAt(nPos) == _T('-') ) m_bNegative = FALSE; if ( m_bNegative ) { if ( m_bPoint ) { if ( m_bZero && caret.x == 2 ) { m_bZero = FALSE; } } else { if ( m_bZero && caret.x == 2 && ( strEdit.GetLength() < 2 || strEdit[2] != _T('0')) ) { m_bZero = FALSE; } } } else { if ( m_bPoint ) { if ( m_bZero && caret.x == 1 ) { m_bZero = FALSE; } } else { if ( m_bZero && caret.x == 1 && ( strEdit.GetLength() < 1 || strEdit[1] != _T('0')) ) { m_bZero = FALSE; } } } } } } return CEdit::PreTranslateMessage(pMsg); }