📄 bcgpdatetimectrl.cpp
字号:
}
CClientDC dc (this);
CFont* pPrevFont = m_hFont == NULL ?
(CFont*) dc.SelectStockObject (DEFAULT_GUI_FONT) :
dc.SelectObject (CFont::FromHandle (m_hFont));
ASSERT (pPrevFont != NULL);
if (m_WidestDate == COleDateTime ())
{
BuidWidestDate (&dc);
}
SetPartsOrder ();
m_iPartNum = m_bCheckBoxIsAvailable ? 1 : 0;
m_CurrPartType = m_arPartsOrder [m_iPartNum];
m_rectText = rectClient;
m_rectText.InflateRect (0, -2);
if (m_bAutoResize)
{
// Calculate text size:
TEXTMETRIC tm;
dc.GetTextMetrics (&tm);
m_iControlHeight = tm.tmHeight + 6;
}
else
{
m_iControlHeight = rectClient.Height ();
}
if (m_bCheckBoxIsAvailable)
{
m_rectCheck = CRect (rectClient.left + 1, rectClient.top + 1,
rectClient.left + m_iControlHeight - 1, rectClient.top + m_iControlHeight - 1);
m_rectText.left = m_rectCheck.right + 2;
}
m_rectText.top = rectClient.top;
m_rectText.bottom = rectClient.top + m_iControlHeight;
// Calculate parts:
CalcPartRects (&dc);
// Adjust control size:
m_rectText.right = m_arPartRects [m_iPartsNumber - 1].right + 2;
m_iControlWidth = m_rectText.right;
if (m_spinButton)
{
m_iControlWidth += iSpinWidth;
}
if (!m_bAutoResize)
{
m_iControlWidth = rectClient.Width ();
m_iControlHeight = rectClient.Height ();
}
if (m_dropCalendar && m_showDate)
{
if (m_bAutoResize)
{
m_iControlWidth += iDropButtonWidth;
}
int iDropStart = rectClient.left + m_iControlWidth - iDropButtonWidth;
if (m_spinButton)
{
iDropStart -= iSpinWidth - 1;
}
m_rectDropButton = CRect ( iDropStart,
rectClient.top,
iDropStart + iDropButtonWidth,
rectClient.top + m_iControlHeight);
}
if (m_bAutoResize)
{
SetWindowPos (NULL, -1, -1, m_iControlWidth + 2, m_iControlHeight + 2,
SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE);
}
// Adjust spin button:
if (m_spinButton)
{
if (m_wndSpin.GetSafeHwnd () == NULL)
{
m_wndSpin.Create (WS_CHILD | WS_VISIBLE | UDS_ALIGNRIGHT | UDS_AUTOBUDDY,
CRect (0, 0, 0, 0), this, iSpinID);
}
m_wndSpin.SetWindowPos (NULL,
rectClient.left + m_iControlWidth - iSpinWidth, rectClient.top,
iSpinWidth, m_iControlHeight,
SWP_NOZORDER);
m_wndSpin.ShowWindow (SW_SHOW);
m_wndSpin.EnableWindow (IsWindowEnabled () && m_bIsChecked);
}
else
{
m_wndSpin.SetWindowPos (NULL,
0, 0,
0, 0,
SWP_NOZORDER);
m_wndSpin.ShowWindow (SW_HIDE);
}
dc.SelectObject (pPrevFont);
//-----------------------------
// Adjust min./max date values:
//-----------------------------
COleDateTime minAllowedDate (iFirstAllowedYear, 1, 1, 0, 0, 0);
COleDateTime maxAllowedDate (iLastAllowedYear, 12, 31, 23, 59, 59);
COleDateTime emptyDate;
m_MinDate = max (m_MinDate, minAllowedDate);
if (m_MaxDate != emptyDate)
{
m_MaxDate = min (m_MaxDate, maxAllowedDate);
}
else
{
m_MaxDate = maxAllowedDate;
}
RedrawWindow ();
}
//*****************************************************************************************
void CBCGPDateTimeCtrl::DrawCheckBox (CDC* pDC, UINT uiState)
{
if (!m_bCheckBoxIsAvailable)
{
return;
}
ASSERT_VALID (pDC);
CBCGPVisualManager::GetInstance ()->OnDrawCheckBox (pDC, m_rectCheck,
m_bShowSelection && m_CurrPartType == CHECK_BOX,
m_bIsChecked, !(uiState & ODS_DISABLED));
}
//*****************************************************************************************
void CBCGPDateTimeCtrl::DrawDateDropButton (CDC* pDC, UINT uiState)
{
if (!m_dropCalendar || !m_showDate)
{
return;
}
CBCGPToolbarComboBoxButton buttonDummy;
CBCGPVisualManager::GetInstance ()->OnDrawComboDropButton (pDC, m_rectDropButton,
(uiState & ODS_DISABLED) || !m_bIsChecked,
m_bDropButtonIsPressed,
m_bMouseOnDropButton,
&buttonDummy);
}
//*****************************************************************************************
void CBCGPDateTimeCtrl::SelectNext ()
{
if (m_iPartNum == -1 || !m_bIsChecked)
{
return;
}
int iPrevPart = m_iPartNum;
if (m_iPartNum == m_iPartsNumber - 1) // Last
{
m_iPartNum = 0;
}
else
{
m_iPartNum ++;
}
m_CurrPartType = m_arPartsOrder [m_iPartNum];
CRect rectPrevPart = m_arPartRects [iPrevPart];
rectPrevPart.InflateRect (1, 1);
RedrawWindow (rectPrevPart);
CRect rectPart = m_arPartRects [m_iPartNum];
rectPart.InflateRect (1, 1);
RedrawWindow (rectPart);
}
//*****************************************************************************************
void CBCGPDateTimeCtrl::SelectPrev ()
{
if (m_iPartNum == -1 || !m_bIsChecked)
{
return;
}
int iPrevPart = m_iPartNum;
if (m_iPartNum == 0) // First
{
m_iPartNum = m_iPartsNumber - 1;
}
else
{
m_iPartNum --;
}
m_CurrPartType = m_arPartsOrder [m_iPartNum];
CRect rectPrevPart = m_arPartRects [iPrevPart];
rectPrevPart.InflateRect (1, 1);
RedrawWindow (rectPrevPart);
CRect rectPart = m_arPartRects [m_iPartNum];
rectPart.InflateRect (1, 1);
RedrawWindow (rectPart);
}
//*****************************************************************************************
void CBCGPDateTimeCtrl::SetPartsOrder ()
{
int i = 0;
if (m_checkButton)
{
m_arPartsOrder [i ++] = CHECK_BOX;
m_bCheckBoxIsAvailable = TRUE;
}
else
{
m_bCheckBoxIsAvailable = FALSE;
}
TCHAR szLocaleData [100];
GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_SDATE, szLocaleData, 100);
m_strDateSeparator = szLocaleData [0] == 0 ? _T ("") : szLocaleData;
GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_STIME, szLocaleData, 100);
m_strTimeSeparator = szLocaleData [0] == 0 ? _T ("") : szLocaleData;
if (m_showDate)
{
GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_IDATE, szLocaleData, 100);
switch (szLocaleData [0])
{
case '0': // Month-Day-Year
default:
m_arPartsOrder [i ++] = MONTH;
m_arPartsOrder [i ++] = DAY;
m_arPartsOrder [i ++] = YEAR;
break;
case '1': // Day-Month-Year
m_arPartsOrder [i ++] = DAY;
m_arPartsOrder [i ++] = MONTH;
m_arPartsOrder [i ++] = YEAR;
break;
case '2': // Year-Month-Day
m_arPartsOrder [i ++] = YEAR;
m_arPartsOrder [i ++] = MONTH;
m_arPartsOrder [i ++] = DAY;
break;
}
}
if (m_showTime)
{
m_arPartsOrder [i ++] = HOUR;
m_arPartsOrder [i ++] = MIN;
if (m_b24HoursByLocale)
{
GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_ITIME, szLocaleData, 100);
switch (szLocaleData [0])
{
case '0': // AM/PM
default:
m_b24HoursFormat = FALSE;
break;
case '1':
m_b24HoursFormat = TRUE;
break;
}
}
if (!m_b24HoursFormat)
{
m_arPartsOrder [i ++] = AMPM;
}
}
m_iPartsNumber = i;
GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_S1159, szLocaleData, 100);
m_strAM = szLocaleData;
m_strAM.MakeUpper ();
GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_S2359, szLocaleData, 100);
m_strPM = szLocaleData;
m_strPM.MakeUpper ();
}
//*****************************************************************************************
LPCTSTR CBCGPDateTimeCtrl::GetPartFormat (int iPart) const
{
switch (m_arPartsOrder [iPart])
{
case NO:
case CHECK_BOX:
return _T ("");
case DAY:
return _T ("%d");
case MONTH:
switch (m_monthFormat)
{
case 0: // Short:
return _T ("%b");
case 1: // Long:
return _T ("%B");
case 2: // Numeric:
return _T ("%m");
default:
ASSERT (FALSE);
return _T ("%b");
}
case YEAR:
return _T ("%Y");
case HOUR:
return m_b24HoursFormat ? _T ("%H") : _T ("%I");
case MIN:
return _T ("%M");
case AMPM:
return _T ("%p");
}
return _T ("");
}
//*****************************************************************************************
int CBCGPDateTimeCtrl::GetPartFromPoint (POINT point)
{
for (int i = 0; i < m_iPartsNumber; i ++)
{
if (m_arPartRects [i].PtInRect (point))
{
return i;
}
}
return -1;
}
//*****************************************************************************************
void CBCGPDateTimeCtrl::CalcPartRects (CDC* pDC)
{
ASSERT_VALID (pDC);
CBCGPDefaultLocale dl;
int iStart = 0;
if (m_arPartsOrder [0] == CHECK_BOX)
{
m_arPartRects [0] = m_rectCheck;
iStart = 1;
}
int x = m_rectText.left;
for (int i = iStart; i < m_iPartsNumber; i ++)
{
CString strPart = m_WidestDate.Format (GetPartFormat (i));
m_arPartRects [i] = m_rectText;
m_arPartRects [i].left = x;
m_arPartRects [i].right = x + pDC->GetTextExtent (strPart).cx;
//-----------------------
// Calc. separator width:
//-----------------------
CString strSeparator = _T(" ");
if (i < m_iPartsNumber - 1)
{
if (IsDatePart (i) && IsDatePart (i + 1))
{
strSeparator = m_strDateSeparator;
}
if (IsTimePart (i) && IsTimePart (i + 1))
{
strSeparator = m_strTimeSeparator;
}
}
x = m_arPartRects [i].right + pDC->GetTextExtent (strSeparator).cx;
}
// Clean rest:
while (i < MAX_PARTS)
{
m_arPartRects [i ++].SetRectEmpty ();
}
}
//*****************************************************************************************
void CBCGPDateTimeCtrl::ScrollCurrPart (int iDir)
{
int iDay = m_Date.GetDay ();
int iMonth = m_Date.GetMonth ();
int iYear = m_Date.GetYear ();
int iHour = m_Date.GetHour ();
int iMin = m_Date.GetMinute ();
BOOL bLastDayInMonth = (iDay == GetDaysInMonth (iMonth, iYear));
switch (m_CurrPartType)
{
case NO:
case CHECK_BOX:
return;
case DAY:
iDay += iDir;
if (iDay <= 0)
{
iDay = GetDaysInMonth (iMonth, iYear);
}
if (iDay > GetDaysInMonth (iMonth, iYear))
{
iDay = 1;
}
break;
case MONTH:
iMonth += iDir;
if (iMonth <= 0)
{
iMonth = 12;
}
if (iMonth > 12)
{
iMonth = 1;
}
if (bLastDayInMonth ||
iDay > GetDaysInMonth (iMonth, iYear))
{
iDay = GetDaysInMonth (iMonth, iYear);
}
break;
case YEAR:
iYear += iDir;
if (iDay > GetDaysInMonth (iMonth, iYear))
{
iDay = GetDaysInMonth (iMonth, iYear);
}
break;
case HOUR:
iHour += iDir;
if (iHour < 0)
{
iHour = 23;
}
if (iHour > 23)
{
iHour = 0;
}
break;
case MIN:
iMin += iDir;
if (iMin < 0)
{
iMin = 59;
}
if (iMin > 59)
{
iMin = 0;
}
break;
case AMPM:
if (iHour < 12)
{
iHour += 12;
}
else
{
iHour -= 12;
}
}
COleDateTime date (iYear, iMonth, iDay, iHour, iMin, 0);
COleDateTime dateEmpty;
if (iDir > 0 && date > m_MaxDate && m_MaxDate != dateEmpty)
{
date = m_MaxDate;
}
if (iDir < 0 && date < m_MinDate)
{
date = m_MinDate;
}
if (m_Date != date && IsDateValid (date))
{
m_Date = date;
RedrawWindow (m_rectText);
OnDateChanged ();
}
}
//*****************************************************************************************
void CBCGPDateTimeCtrl::ScrollCurrPartToLimit (BOOL bTop)
{
int iDay = m_Date.GetDay ();
int iMonth = m_Date.GetMonth ();
int iYear = m_Date.GetYear ();
int iHour = m_Date.GetHour ();
int iMin = m_Date.GetMinute ();
switch (m_CurrPartType)
{
case NO:
case CHECK_BOX:
case AMPM:
case YEAR:
return;
case DAY:
if (bTop)
{
iDay = 1;
}
else
{
iDay = GetDaysInMonth (iMonth, iYear);
}
break;
case MONTH:
if (bTop)
{
iMonth = 1;
}
else
{
iMonth = 12;
}
break;
case HOUR:
if (bTop)
{
iHour = 0;
}
else
{
iHour = 23;
}
break;
case MIN:
if (bTop)
{
iMin = 0;
}
else
{
iMin = 59;
}
break;
}
COleDateTime date (iYear, iMonth, iDay, iHour, iMin, 0);
if (IsDateValid (date) && m_Date != date)
{
m_Date = date;
RedrawWindow (m_rectText);
OnDateChanged ();
}
}
//*****************************************************************************************
void CBCGPDateTimeCtrl::PushDigit (int iDigit)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -