📄 amsedit.cpp
字号:
{
case '0': //只能是数字
if (nChar == 0 || isdigit(nChar)) return 1;
return -1;
case '9': //数字或者空格
if(nChar == 0 || isdigit(nChar)) return 1;
if(nChar!=VK_SPACE) return 1;
return -1;
case '#': //数字、空格或者'+'、'-'
if(nChar == 0||isdigit(nChar)) return 1;
if(nChar==VK_SPACE||nChar==VK_ADD||nChar==VK_SUBTRACT)
return 0;
return -1;
case 'L': //只能输入字母表中的字母
if(nChar == 0||isalpha(nChar)) return 1;
return -1;
case '?': //字母或者空格
if(nChar == 0||isalpha(nChar)) return 1;
if(nChar==VK_SPACE) return 1;
return -1;
case 'A': //只能是字母表中的数字
if(nChar == 0||isalnum(nChar)) return 1;
return -1;
case 'a': //字母表中的数字或者空格
if(nChar == 0||isalnum(nChar)) return 1;
if(nChar==VK_SPACE) return 1;
return -1;
case '&': //全部可打印字符
if(nChar == 0||isprint(nChar)) return 1;
return -1;
}
return 100;
}
CString CAMSEdit::MaskedBehavior::_GetValidText() const
{
CString strText = m_pEdit->GetText();
CString strNewText;
int nMaskLen = m_strMask.GetLength();
// If the mask is empty, allow anything
if (!nMaskLen)
strNewText = strText;
else
{
// Remove any characters not in the mask
for (int iPos = 0, iMaskPos = 0, nLen = strText.GetLength(); iPos < nLen; iPos++, iMaskPos++)
{
TCHAR c = strText[iPos];
TCHAR cMask = (iMaskPos < nMaskLen ? m_strMask[iMaskPos] : 0);
// If we've reached the end of the mask, break
if (!cMask) break;
switch(CheckCode(c, cMask))
{
case 1: strNewText += c;
break;
case 100:
strNewText += cMask;
iPos--;
break;
}
// If it's a digit, look for the next digit placeholder (#) in the mask
//if (CheckCode(c, cMask))
//{
// strNewText += c;
// iMaskPos++;
//}
}//end for
}//end if
return strNewText;
}
//////////////////////////////////////////////////
//bak
/*
CString CAMSEdit::MaskedBehavior::_GetValidText() const
{
CString strText = m_pEdit->GetText();
CString strNewText;
int nMaskLen = m_strMask.GetLength();
// If the mask is empty, allow anything
if (!nMaskLen)
strNewText = strText;
else
{
// Remove any characters not in the mask
for (int iPos = 0, iMaskPos = 0, nLen = strText.GetLength(); iPos < nLen; iPos++, iMaskPos++)
{
TCHAR c = strText[iPos];
TCHAR cMask = (iMaskPos < nMaskLen ? m_strMask[iMaskPos] : 0);
// If we've reached the end of the mask, break
if (!cMask)
break;
// If it's a digit, look for the next digit placeholder (#) in the mask
else if (_istdigit(c))
{
for (; iMaskPos < nMaskLen; iMaskPos++)
{
cMask = m_strMask[iMaskPos];
if (cMask == '#')
{
strNewText += c;
break;
}
strNewText += cMask;
}
}
// If it's the same character as the mask's allow it.
else if (c == cMask)
strNewText += c;
else
break;
}
}
return strNewText;
}
*/
void CAMSEdit::MaskedBehavior::_OnChar(UINT uChar, UINT nRepCnt, UINT nFlags)
{
TCHAR c = (TCHAR)uChar;
// If the mask is empty, allow anything
int nMaskLen = m_strMask.GetLength();
if (!nMaskLen) //如果MASK是空则全通
{
if (_ShouldEnter(c))
Behavior::_OnChar(uChar, nRepCnt, nFlags);
return;
}
// Check that we haven't gone past the mask's length
int nStart, nEnd;
int iRet;
TCHAR cMask;
m_pEdit->GetSel(nStart, nEnd);
CString strText = m_pEdit->GetText();
int nLen = strText.GetLength();
if (!_istprint(c)) //控制符
{
if (c == VK_BACK && !IsEnd(nStart, strText))
{//不是末尾,则只移动
m_pEdit->SendMessage(WM_KEYDOWN, VK_LEFT); // move the cursor left
return;
}
if(c == VK_BACK)
{//移到下一个有效位
if (nStart==0) return ; //首位
iRet = MovePrevious(0, nStart);
if(iRet < 0)
{//移到首位
m_pEdit->SetSel(0, 0);
return ;
}
else if(iRet != nStart-1)
{//前位是掩码
m_pEdit->SendMessage(WM_KEYDOWN, VK_LEFT); // move the cursor left
return;
}
m_pEdit->SetSel(iRet, iRet+1); //有效位后面
m_pEdit->ReplaceSel(CString(VK_SPACE), TRUE);
m_pEdit->SetSel(iRet, iRet); //有效位后面
return;
}
// Allow backspace only if the cursor is all the way to the right
if (_ShouldEnter(c)) //执行
Behavior::_OnChar(uChar, nRepCnt, nFlags);
return;
}
// Check if we're currently on a number mask
if (nStart >= m_strMask.GetLength())return;
cMask = m_strMask[nStart];
iRet = CheckCode(c, cMask);
if (iRet == 1) //有效位
{
if (_ShouldEnter(c))
{
if (nLen > nStart)
{
m_pEdit->SetSel(nStart, nStart+1);
m_pEdit->ReplaceSel(CString(c), TRUE);
}
else
Behavior::_OnChar(uChar, nRepCnt, nFlags);
}
}
// else if(iRet == -1) //无效位
// return;
// Check if it's the same character as the mask.
else if(iRet == 100)//掩码
{
if (cMask == c && _ShouldEnter(c))
{//等于MASK,则输入
if (nLen > nStart)
{
m_pEdit->SetSel(nStart, nStart + 1);
m_pEdit->ReplaceSel(CString(c), TRUE);
}
else
{
Behavior::_OnChar(uChar, nRepCnt, nFlags);
}
}
else
{
iRet = MoveNext(c,nStart);
if(iRet < 0)
return ;
else
{
m_pEdit->SetSel(nStart, iRet+1);
m_pEdit->ReplaceSel(m_strMask.Mid(nStart,iRet-1)+c,
TRUE);
//Behavior::_OnChar(uChar, nRepCnt, nFlags);
}
}//end if
}//end if
}
void CAMSEdit::MaskedBehavior::_OnKeyDown(UINT uChar, UINT nRepCnt, UINT nFlags)
{
BYTE cLShift = VK_LSHIFT;
BYTE cRShift = VK_RSHIFT;
switch (uChar)
{
case VK_DELETE:
{
// If deleting make sure it's the last character or that
// the selection goes all the way to the end of the text
int nStart, nEnd;
m_pEdit->GetSel(nStart, nEnd);
CString strText = m_pEdit->GetText();
int nLen = strText.GetLength();
if (nEnd != nLen)
{
if (!(nEnd == nStart && nEnd == nLen - 1))
return;
}
break;
}
}
Behavior::_OnKeyDown(uChar, nRepCnt, nFlags);
}
/////////////////////////////////////////////////////////////////////////////
// CAMSEdit::NumericBehavior
// Constructs the object using the given nMaxWholeDigits and nMaxDecimalPlaces.
//原默认设置
//CAMSEdit::NumericBehavior::NumericBehavior(CAMSEdit* pEdit, int nMaxWholeDigits /*= 9*/, int nMaxDecimalPlaces /*= 4*/) :
// Behavior(pEdit),
// m_nMaxWholeDigits(nMaxWholeDigits >= 0 ? nMaxWholeDigits : -nMaxWholeDigits),
// m_nMaxDecimalPlaces(nMaxDecimalPlaces),
// m_bAllowNegative(nMaxWholeDigits >= 0),
// m_cNegativeSign('-'),
// m_cDecimalPoint('.'),
// m_cGroupSeparator(','),
// m_nDigitsInGroup(0)
CAMSEdit::NumericBehavior::NumericBehavior(CAMSEdit* pEdit, int nMaxWholeDigits /*= 9*/, int nMaxDecimalPlaces /*= 4*/) :
Behavior(pEdit),
m_nMaxWholeDigits(nMaxWholeDigits >= 0 ? nMaxWholeDigits : -nMaxWholeDigits),
m_nMaxDecimalPlaces(nMaxDecimalPlaces),
m_bAllowNegative(nMaxWholeDigits >= 0),
m_cNegativeSign(' '),
m_cDecimalPoint('.'),
m_cGroupSeparator(','),
m_nDigitsInGroup(0)
{
ASSERT(m_nMaxWholeDigits); // must have at least 1 digit to the left of the decimal
ASSERT(m_nMaxDecimalPlaces >= 0); // decimal places must be positive
// Get the system's decimal point
if (::GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SNEGATIVESIGN, &m_cNegativeSign, 0))
::GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SNEGATIVESIGN, &m_cNegativeSign, sizeof(m_cNegativeSign));
if (::GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, &m_cDecimalPoint, 0))
::GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, &m_cDecimalPoint, sizeof(m_cDecimalPoint));
if (::GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, &m_cGroupSeparator, 0))
::GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, &m_cGroupSeparator, sizeof(m_cGroupSeparator));
}
void CAMSEdit::NumericBehavior::SetMaxWholeDigits(int nMaxWholeDigits)
{
ASSERT(nMaxWholeDigits);
// If nMaxWholeDigits is negative, don't allow negatives
bool bAllowNegative = (nMaxWholeDigits >= 0);
if (nMaxWholeDigits < 0)
nMaxWholeDigits = -nMaxWholeDigits;
if (m_nMaxWholeDigits == nMaxWholeDigits && m_bAllowNegative == bAllowNegative)
return;
m_nMaxWholeDigits = nMaxWholeDigits;
m_bAllowNegative = bAllowNegative;
_Redraw();
}
int CAMSEdit::NumericBehavior::GetMaxWholeDigits() const
{
return m_nMaxWholeDigits;
}
void CAMSEdit::NumericBehavior::SetMaxDecimalPlaces(int nMaxDecimalPlaces)
{
ASSERT(nMaxDecimalPlaces >= 0);
if (m_nMaxDecimalPlaces == nMaxDecimalPlaces)
return;
m_nMaxDecimalPlaces = nMaxDecimalPlaces;
_Redraw();
}
int CAMSEdit::NumericBehavior::GetMaxDecimalPlaces() const
{
return m_nMaxDecimalPlaces;
}
// Sets whether the negative sign is allowed in the number or not.
void CAMSEdit::NumericBehavior::AllowNegative(bool bAllowNegative /*= true*/)
{
if (m_bAllowNegative == bAllowNegative)
return;
m_bAllowNegative = bAllowNegative;
_Redraw();
}
// Returns true if the negative sign is allowed in the number.
bool CAMSEdit::NumericBehavior::IsNegativeAllowed() const
{
return m_bAllowNegative;
}
// Sets the number of digits to be grouped together (if any).
void CAMSEdit::NumericBehavior::SetDigitsInGroup(int nDigitsInGroup)
{
ASSERT(nDigitsInGroup >= 0);
if (m_nDigitsInGroup == nDigitsInGroup)
return;
m_nDigitsInGroup = nDigitsInGroup;
_Redraw();
}
// Returns the number of digits to be grouped together (if any).
int CAMSEdit::NumericBehavior::GetDigitsInGroup() const
{
return m_nDigitsInGroup;
}
void CAMSEdit::NumericBehavior::SetPrefix(const CString& strPrefix)
{
if (m_strPrefix == strPrefix)
return;
m_strPrefix = strPrefix;
_Redraw();
}
const CString& CAMSEdit::NumericBehavior::GetPrefix() const
{
return m_strPrefix;
}
// Parses the given strMask to set the control's configuration.
void CAMSEdit::NumericBehavior::SetMask(const CString& strMask)
{
int nDecimalPos = -1;
int nGroupingPos = -1;
int nLen = strMask.GetLength();
m_nMaxWholeDigits = 0;
m_nMaxDecimalPlaces = 0;
m_nDigitsInGroup = 0;
m_bAllowNegative = true;
m_strPrefix = _T("");
for (int iPos = nLen - 1; iPos >= 0; iPos--)
{
TCHAR c = strMask[iPos];
if (c == '#')
{
if (nDecimalPos >= 0)
m_nMaxWholeDigits++;
else
m_nMaxDecimalPlaces++;
}
else if ((c == '.' || c == m_cDecimalPoint) && nDecimalPos < 0)
{
nDecimalPos = iPos;
m_cDecimalPoint = c;
}
else if (c == ',' || c == m_cGroupSeparator)
{
if (!m_nDigitsInGroup)
{
m_nDigitsInGroup = (((nDecimalPos >= 0) ? nDecimalPos : nLen) - iPos) - 1;
m_cGroupSeparator = c;
}
}
else
{
m_strPrefix = strMask.Left(iPos + 1);
break;
}
}
if (nDecimalPos < 0)
{
m_nMaxWholeDigits = m_nMaxDecimalPlaces;
m_nMaxDecimalPlaces = 0;
}
ASSERT(m_nMaxWholeDigits > 0); // must have at least one digit on left side of decimal point
_Redraw();
}
// Gets the mask corresponding to the maximum number than can be entered into the control
CString CAMSEdit::NumericBehavior::GetMask() const
{
CString strMask;
for (int iDigit = 0; iDigit < m_nMaxWholeDigits; iDigit++)
strMask += '0';
if (m_nMaxDecimalPlaces)
strMask += m_cDecimalPoint;
for (iDigit = 0; iDigit < m_nMaxDecimalPlaces; iDigit++)
strMask += '0';
strMask = GetSeparatedText(strMask);
for (int iPos = 0, nLen = strMask.GetLength(); iPos < nLen; iPos++)
{
if (strMask[iPos] == '0')
strMask.SetAt(iPos, '#');
}
return strMask;
}
// Returns the number of group separator characters in the given strText.
int CAMSEdit::NumericBehavior::GetGroupSeparatorCount(const CString& strText) const
{
for (int iPos = 0, nSepCount = 0, nLen = strText.GetLength(); iPos < nLen; iPos++)
{
if (strText[iPos] == m_cGroupSeparator)
nSepCount++;
}
return nSepCount;
}
// Returns the given strText as a numeric string.
CString CAMSEdit::NumericBehavior::GetNumericText(const CString& strText) const
{
CString strNewText;
for (int iPos = 0, nLen = strText.GetLength(); iPos < nLen; iPos++)
{
TCHAR c = strText[iPos];
if (_istdigit(c) || c == m_cNegativeSign || c == m_cDecimalPoint)
strNewText += c;
}
return strNewText;
}
// Returns the current text as a double value.
double CAMSEdit::NumericBehavior::GetTextAsDouble() const
{
return _tcstod(GetNumericText(m_pEdit->GetText()), NULL);
}
// Adjusts the location of separators based on the nCurrentSeparatorCount.
void CAMSEdit::NumericBehavior::AdjustSeparators(int nCurrentSeparatorCount)
{
SelectionSaver selection = m_pEdit;
CString strText = _GetValidText();
if (strText.IsEmpty() && selection.GetStart() <= m_strPrefix.GetLength())
m_pEdit->SetWindowText(m_strPrefix.Mid(0, selection.GetStart()));
else
m_pEdit->SetWindowText(strText);
// Adjust the current selection if separators were added/removed
int nNewSeparatorCount = GetGroupSeparatorCount(strText);
if (nCurrentSeparatorCount != nNewSeparatorCount && selection.GetStart() > m_strPrefix.GetLength())
selection += (nNewSeparatorCount - nCurrentSeparatorCount);
}
// Returns the given text with the group separator characters inserted in the proper places.
CString CAMSEdit::NumericBehavior::GetSeparatedText(const CString& strText) const
{
CString strNumericText = GetNumericText(strText);
CString strNewText = strNumericText;
// Retrieve the number without the decimal point
int nDecimalPos = strNumericText.Find(m_cDecimalPoint);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -