📄 amsedit.cpp
字号:
else
Behavior::_OnChar(uChar, nRepCnt, nFlags);
}
}
else
{
if (IsValidDayDigit(c, 1) && _ShouldEnter(c))
{
if (nLen > nStart)
{
m_pEdit->SetSel(nStart, nStart + 1);
m_pEdit->ReplaceSel(CString(c), TRUE);
}
else
Behavior::_OnChar(uChar, nRepCnt, nFlags);
}
}
break;
}
case 5: // SECOND SLASH (year's first digit)
{
int nSlash = 0;
if (c == m_cSep)
nSlash = 1;
else
nSlash = (IsValidYearDigit(c, 0) ? 2 : 0);
// If we need the slash, enter it
if (nSlash && _ShouldEnter(c))
{
m_pEdit->SetSel(nStart, nStart + 1, FALSE);
m_pEdit->ReplaceSel(CString(m_cSep), TRUE);
}
// If the slash is to be preceded by a valid digit, "type" it in.
if (nSlash == 2)
keybd_event((BYTE)c, 0, 0, 0);
break;
}
case 6: // YEAR (all 4 digits)
case 7:
case 8:
case 9:
{
if (IsValidYearDigit(c, nStart - GetYearStartPosition()) && _ShouldEnter(c))
{
if (nLen > nStart)
{
m_pEdit->SetSel(nStart, nStart + 1, FALSE);
m_pEdit->ReplaceSel(CString(c), TRUE);
if (nLen > nStart + 1)
{
if (!IsValidYearDigit(strText[nStart + 1], nStart - (GetYearStartPosition() - 1)))
{
m_pEdit->SetSel(nStart + 1, 10, FALSE);
CString strPortion;
for (int iPos = nStart + 1; iPos < 10; iPos++)
strPortion += GetMinYearDigit(iPos - GetYearStartPosition(), true);
m_pEdit->ReplaceSel(strPortion, TRUE);
m_pEdit->SetSel(nStart + 1, 10, FALSE);
}
}
}
else
Behavior::_OnChar(uChar, nRepCnt, nFlags);
if (IsValidYear(GetYear()))
{
AdjustMaxDay(); // adjust the day first
AdjustMaxMonthAndDay(); // then adjust the month and the day, if necessary
}
}
break;
}
}
}
void CAMSEdit::DateBehavior::_OnKeyDown(UINT uChar, UINT nRepCnt, UINT nFlags)
{
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;
}
case VK_UP:
{
// If pressing the UP arrow, increment the corresponding value.
int nStart, nEnd;
m_pEdit->GetSel(nStart, nEnd);
if (nStart >= GetYearStartPosition() && nStart <= GetYearStartPosition() + 4)
{
int nYear = GetYear();
if (nYear >= m_dateMin.GetYear() && nYear < m_dateMax.GetYear())
SetYear(++nYear);
}
else if (nStart >= GetMonthStartPosition() && nStart <= GetMonthStartPosition() + 2)
{
int nMonth = GetMonth();
if (nMonth >= GetMinMonth() && nMonth < GetMaxMonth())
SetMonth(++nMonth);
}
else if (nStart >= GetDayStartPosition() && nStart <= GetDayStartPosition() + 2)
{
int nDay = GetDay();
if (nDay >= GetMinDay() && nDay < GetMaxDay())
SetDay(++nDay);
}
return;
}
case VK_DOWN:
{
// If pressing the DOWN arrow, decrement the corresponding value.
int nStart, nEnd;
m_pEdit->GetSel(nStart, nEnd);
if (nStart >= GetYearStartPosition() && nStart <= GetYearStartPosition() + 4)
{
int nYear = GetYear();
if (nYear > m_dateMin.GetYear())
SetYear(--nYear);
}
else if (nStart >= GetMonthStartPosition() && nStart <= GetMonthStartPosition() + 2)
{
int nMonth = GetMonth();
if (nMonth > GetMinMonth())
SetMonth(--nMonth);
}
else if (nStart >= GetDayStartPosition() && nStart <= GetDayStartPosition() + 2)
{
int nDay = GetDay();
if (nDay > GetMinDay())
SetDay(--nDay);
}
return;
}
}
Behavior::_OnKeyDown(uChar, nRepCnt, nFlags);
}
CString CAMSEdit::DateBehavior::GetString(int nValue, bool bTwoDigitWithLeadingZero /*= true*/)
{
CString strValue;
if (bTwoDigitWithLeadingZero)
strValue.Format(_T("%02d"), nValue);
else
strValue.Format(_T("%d"), nValue);
return strValue;
}
int CAMSEdit::DateBehavior::GetMonthStartPosition() const
{
return ((m_uFlags & DayBeforeMonth) ? 3 : 0);
}
int CAMSEdit::DateBehavior::GetDayStartPosition() const
{
return ((m_uFlags & DayBeforeMonth) ? 0 : 3);
}
int CAMSEdit::DateBehavior::GetYearStartPosition() const
{
return 6;
}
int CAMSEdit::DateBehavior::GetMaxMonth() const
{
if (GetValidYear() == m_dateMax.GetYear())
return m_dateMax.GetMonth();
return 12;
}
int CAMSEdit::DateBehavior::GetMinMonth() const
{
if (GetValidYear() == m_dateMin.GetYear())
return m_dateMin.GetMonth();
return 1;
}
int CAMSEdit::DateBehavior::GetMaxDay() const
{
int nYear = GetValidYear();
int nMonth = GetValidMonth();
if (nYear == m_dateMax.GetYear() && nMonth == m_dateMax.GetMonth())
return m_dateMax.GetDay();
return GetMaxDayOfMonth(nMonth, nYear);
}
int CAMSEdit::DateBehavior::GetMinDay() const
{
int nYear = GetValidYear();
int nMonth = GetValidMonth();
if (nYear == m_dateMin.GetYear() && nMonth == m_dateMin.GetMonth())
return m_dateMin.GetDay();
return 1;
}
int CAMSEdit::DateBehavior::GetMaxDayOfMonth(int nMonth, int nYear)
{
ASSERT(nMonth >= 1 && nMonth <= 12);
switch (nMonth)
{
case 4:
case 6:
case 9:
case 11:
return 30;
case 2:
return IsLeapYear(nYear) ? 29 : 28;
}
return 31;
}
TCHAR CAMSEdit::DateBehavior::GetMaxMonthDigit(int nPos) const
{
ASSERT(nPos >= 0 && nPos <= 1);
int nYear = GetValidYear();
int nMaxMonth = m_dateMax.GetMonth();
int nMaxYear = m_dateMax.GetYear();
// First digit
if (nPos == 0)
{
// If the year is at the max, then use the first digit of the max month
if (nYear == nMaxYear)
return GetString(nMaxMonth)[0];
// Otherwise, it's always '1'
return '1';
}
// Second digit
CString strWindowText = m_pEdit->GetText();
TCHAR cFirstDigit = (strWindowText.GetLength() > GetMonthStartPosition()) ? strWindowText[GetMonthStartPosition()] : 0;
ASSERT(cFirstDigit); // must have a valid first digit at this point
// If the year is at the max, then check if the first digits match
if (nYear == nMaxYear && IsValidYear(GetYear()))
{
// If the first digits match, then use the second digit of the max month
if (GetString(nMaxMonth)[0] == cFirstDigit)
return GetString(nMaxMonth)[1];
// Assuming the logic for the first digit is correct, then it must be '0'
ASSERT(cFirstDigit == '0');
return '9';
}
// Use the first digit to determine the second digit's max
return (cFirstDigit == '1' ? '2' : '9');
}
TCHAR CAMSEdit::DateBehavior::GetMinMonthDigit(int nPos) const
{
ASSERT(nPos >= 0 && nPos <= 1);
int nYear = GetValidYear();
int nMinMonth = m_dateMin.GetMonth();
int nMinYear = m_dateMin.GetYear();
// First digit
if (nPos == 0)
{
// If the year is at the min, then use the first digit of the min month
if (nYear == nMinYear)
return GetString(nMinMonth)[0];
// Otherwise, it's always '0'
return '0';
}
// Second digit
CString strWindowText = m_pEdit->GetText();
TCHAR cFirstDigit = (strWindowText.GetLength() > GetMonthStartPosition()) ? strWindowText[GetMonthStartPosition()] : 0;
if (!cFirstDigit)
return '1';
// If the year is at the max, then check if the first digits match
if (nYear == nMinYear && IsValidYear(GetYear()))
{
// If the first digits match, then use the second digit of the max month
if (GetString(nMinMonth)[0] == cFirstDigit)
return GetString(nMinMonth)[1];
return '0';
}
// Use the first digit to determine the second digit's min
return (cFirstDigit == '1' ? '0' : '1');
}
bool CAMSEdit::DateBehavior::IsValidMonthDigit(TCHAR c, int nPos) const
{
return (c >= GetMinMonthDigit(nPos) && c <= GetMaxMonthDigit(nPos));
}
bool CAMSEdit::DateBehavior::IsValid(const COleDateTime& date) const
{
return (date.GetStatus() == COleDateTime::valid && date >= m_dateMin && date <= m_dateMax);
}
bool CAMSEdit::DateBehavior::IsValidMonth(int nMonth) const
{
int nYear = GetValidYear();
return IsValid(COleDateTime(nYear, nMonth, 1, 0, 0, 0));
}
TCHAR CAMSEdit::DateBehavior::GetMaxDayDigit(int nPos) const
{
ASSERT(nPos >= 0 && nPos <= 1);
int nMonth = GetValidMonth();
int nYear = GetValidYear();
int nMaxDay = m_dateMax.GetDay();
int nMaxMonth = m_dateMax.GetMonth();
int nMaxYear = m_dateMax.GetYear();
// First digit
if (nPos == 0)
{
// If the year and month are at the max, then use the first digit of the max day
if (nYear == nMaxYear && nMonth == nMaxMonth)
return GetString(nMaxDay)[0];
return GetString(GetMaxDayOfMonth(nMonth, nYear))[0];
}
// Second digit
CString strWindowText = m_pEdit->GetText();
TCHAR cFirstDigit = (strWindowText.GetLength() > GetDayStartPosition()) ? strWindowText[GetDayStartPosition()] : 0;
ASSERT(cFirstDigit); // must have a valid first digit at this point
// If the year and month are at the max, then use the second digit of the max day
if (nYear == nMaxYear && nMonth == nMaxMonth && GetString(nMaxDay)[0] == cFirstDigit)
return GetString(nMaxDay)[1];
if (cFirstDigit == '0' ||
cFirstDigit == '1' ||
(cFirstDigit == '2' && nMonth != 2) ||
(nMonth == 2 && !IsValidYear(GetYear())))
return '9';
return GetString(GetMaxDayOfMonth(nMonth, nYear))[1];
}
TCHAR CAMSEdit::DateBehavior::GetMinDayDigit(int nPos) const
{
ASSERT(nPos >= 0 && nPos <= 1);
int nMonth = GetValidMonth();
int nYear = GetValidYear();
int nMinDay = m_dateMin.GetDay();
int nMinMonth = m_dateMin.GetMonth();
int nMinYear = m_dateMin.GetYear();
// First digit
if (nPos == 0)
{
// If the year and month are at the min, then use the first digit of the min day
if (nYear == nMinYear && nMonth == nMinMonth)
return GetString(nMinDay)[0];
return '0';
}
// Second digit
CString strWindowText = m_pEdit->GetText();
TCHAR cFirstDigit = (strWindowText.GetLength() > GetDayStartPosition()) ? strWindowText[GetDayStartPosition()] : 0;
if (!cFirstDigit) // must have a valid first digit at this point
return '1';
// If the year and month are at the max, then use the first second of the max day
if (nYear == nMinYear && nMonth == nMinMonth && GetString(nMinDay)[0] == cFirstDigit)
return GetString(nMinDay)[1];
// Use the first digit to determine the second digit's min
return (cFirstDigit == '0' ? '1' : '0');
}
bool CAMSEdit::DateBehavior::IsValidDayDigit(TCHAR c, int nPos) const
{
return (c >= GetMinDayDigit(nPos) && c <= GetMaxDayDigit(nPos));
}
bool CAMSEdit::DateBehavior::IsValidDay(int nDay) const
{
return IsValid(COleDateTime(GetValidYear(), GetValidMonth(), nDay, 0, 0, 0));
}
bool CAMSEdit::DateBehavior::IsValidYear(int nYear) const
{
return (nYear >= m_dateMin.GetYear() && nYear <= m_dateMax.GetYear());
}
bool CAMSEdit::DateBehavior::AdjustMaxMonthAndDay()
{
int nMonth = GetMonth();
if (nMonth && !IsValidMonth(nMonth))
{
SetMonth(GetMinMonth()); // this adjusts the day automatically
return true;
}
return AdjustMaxDay();
}
bool CAMSEdit::DateBehavior::AdjustMaxDay()
{
int nDay = GetDay();
if (nDay && !IsValidDay(nDay))
{
SetDay(GetMaxDay());
return true;
}
return false; // nothing had to be adjusted
}
TCHAR CAMSEdit::DateBehavior::GetMaxYearDigit(int nPos) const
{
ASSERT(nPos >= 0 && nPos <= 3);
CString strYear = GetString(GetYear(), false);
CString strMaxYear = GetString(m_dateMax.GetYear(), false);
if (nPos == 0 || strMaxYear.Left(nPos) == strYear.Left(nPos))
return strMaxYear[nPos];
return '9';
}
TCHAR CAMSEdit::DateBehavior::GetMinYearDigit(int nPos, bool bValidYear /*= false*/) const
{
ASSERT(nPos >= 0 && nPos <= 3);
int nYear = GetYear();
if (!IsValidYear(nYear) && bValidYear)
nYear = GetValidYear();
CString strYear = GetString(nYear, false);
CString strMinYear = GetString(m_dateMin.GetYear(), false);
if (nPos == 0 || strMinYear.Left(nPos) == strYear.Left(nPos))
return strMinYear[nPos];
return '0';
}
bool CAMSEdit::DateBehavior::IsValidYearDigit(TCHAR c, int nPos) const
{
return (c >= GetMinYearDigit(nPos) && c <= GetMaxYearDigit(nPos));
}
int CAMSEdit::DateBehavior::GetValidMonth() const
{
int nMonth = GetMonth();
// It it's outside the range, fix it
if (nMonth < GetMinMonth())
nMonth = GetMinMonth();
else if (nMonth > GetMaxMonth())
nMonth = GetMaxMonth();
return nMonth;
}
int CAMSEdit::DateBehavior::GetMonth() const
{
CString strText = m_pEdit->GetText();
if (strText.GetLength() >= 2)
return _ttoi(strText.Mid(0, 2));
return 0;
}
int CAMSEdit::DateBehavior::GetValidYear() const
{
int nYear = GetYear();
if (nYear < m_dateMin.GetYear())
nYear = m_dateMin.GetYear();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -