📄 daygridwnd.cpp
字号:
// Written by JHCC, 1997
// DayGridWnd.cpp : implementation file
//
#include "stdafx.h"
#include "DayGridWnd.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
CString CDayGridWnd::m_aStrDayOfWeekName[] =
{
_T("日"),
_T("一"),
_T("二"),
_T("三"),
_T("四"),
_T("五"),
_T("六"),
};
const int nDaysInWeek = sizeof(CDayGridWnd::m_aStrDayOfWeekName) / sizeof(CDayGridWnd::m_aStrDayOfWeekName[0]);
const int nMaxDayInMonth = 31;
const int nWeekInMonth = nMaxDayInMonth / nDaysInWeek + 2;
const int nMonthsInYear = 12;
/////////////////////////////////////////////////////////////////////////////
// CDayGridWnd
CDayGridWnd::CDayGridWnd()
{
m_pTime = NULL;
m_nCurMonth = 0;
m_pRectArray = NULL;
m_nStartDayIndex = 0;
m_nEndDayIndex = 0;
m_bShowOtherMonthDay = FALSE;
m_clrTextWeekName = RGB(0, 0, 255);
m_clrTextHoliday = RGB(255, 0, 0);
m_clrTextNormalDay = RGB(0, 0, 0);
m_clrTextCurDay = RGB(0, 255, 255);
m_clrTextNotCurMonthDay = RGB(128, 128, 128);
}
CDayGridWnd::~CDayGridWnd()
{
}
BOOL CDayGridWnd::InitDayGrid(COleDateTime* pTime)
{
ASSERT(pTime != NULL);
m_pTime = pTime;
CalcFirstDayOfMonth();
m_pRectArray = new CRect[nDaysInWeek * (nWeekInMonth + 1)];
if (!m_pRectArray)
{
TRACE0("Memory error !\n");
return FALSE;
}
CRect rtWindowBounds;
GetWindowRect(&rtWindowBounds);
CRect rtClientBounds;
GetWindowRect(&rtClientBounds);
int nStartX = (rtWindowBounds.right - rtClientBounds.right) / 2;
int nStartY = (rtWindowBounds.bottom - rtClientBounds.bottom) / 2;
int nUnitX = rtClientBounds.Width() / nDaysInWeek;
int nUnitY = rtClientBounds.Height() / (nWeekInMonth + 1);
for (int i = 0; i < nDaysInWeek; ++ i)
{
for (int j = 0; j < nWeekInMonth + 1; ++ j)
{
m_pRectArray[i + j * (nWeekInMonth + 1)].SetRect(
nUnitX * i + nStartX,
nUnitY * j + nStartY,
nUnitX * (i + 1) - 1 + nStartX,
nUnitY * (j + 1) - 1 + nStartY);
}
}
return TRUE;
}
void CDayGridWnd::SetTextWeekNameColor(COLORREF clrTextWeekName)
{
m_clrTextWeekName = clrTextWeekName;
}
void CDayGridWnd::SetTextHolidayColor(COLORREF clrTextHoliday)
{
m_clrTextHoliday = clrTextHoliday;
}
void CDayGridWnd::SetTextNormalDayColor(COLORREF clrTextNormalDay)
{
m_clrTextNormalDay = clrTextNormalDay;
}
void CDayGridWnd::SetTextCurDayColor(COLORREF clrTextCurDay)
{
m_clrTextCurDay = clrTextCurDay;
}
void CDayGridWnd::SetTextTextNotCurMonthDayColor(COLORREF clrTextNotCurMonthDay)
{
m_clrTextNotCurMonthDay = clrTextNotCurMonthDay;
}
BOOL CDayGridWnd::IsHoliday(COleDateTime* pTime)
{
int nDay = pTime->GetDayOfWeek();
if (nDay == 1 || nDay == 7)
return TRUE;
switch (pTime->GetDay())
{
case 1:
switch (m_nCurMonth)
{
case 1:
case 5:
case 6:
case 10:
return TRUE;
}
break;
case 2:
switch (m_nCurMonth)
{
case 10:
return TRUE;
}
}
return FALSE;
}
void CDayGridWnd::CalcFirstDayOfMonth(void)
{
TRACE0(" Calc !\n");
m_nCurMonth = m_pTime->GetMonth();
COleDateTimeSpan timeToFirstDaySpan(m_pTime->GetDay() - 1, 0, 0, 0);
COleDateTime firstDayOfMonth = *m_pTime - timeToFirstDaySpan;
int nFirstDayOfWeek = firstDayOfMonth.GetDayOfWeek();
if (-- nFirstDayOfWeek == 0) // sunday
nFirstDayOfWeek = nDaysInWeek;
if (m_bShowOtherMonthDay)
{
m_nStartDayIndex = nDaysInWeek;
m_nEndDayIndex = nDaysInWeek * (nWeekInMonth + 1);
}
else
{
m_nStartDayIndex = nDaysInWeek + nFirstDayOfWeek;
COleDateTime nextMonth;
if (m_nCurMonth + 1 <= nMonthsInYear)
{
nextMonth.SetDate(firstDayOfMonth.GetYear(),
m_nCurMonth + 1, 1);
}
else // second year
{
nextMonth.SetDate(firstDayOfMonth.GetYear() + 1,
1, 1);
}
COleDateTimeSpan timeMonthSpan = nextMonth - firstDayOfMonth;
m_nEndDayIndex = m_nStartDayIndex + timeMonthSpan.GetDays();
}
COleDateTimeSpan timeLastMonthSpan(nFirstDayOfWeek, 0, 0, 0);
firstDayOfMonth -= timeLastMonthSpan;
m_firstDayOfMonth = firstDayOfMonth;
}
void CDayGridWnd::SetShowOtherMonthDay(BOOL bShowOtherMonthDay)
{
m_bShowOtherMonthDay = bShowOtherMonthDay;
CalcFirstDayOfMonth();
}
BOOL CDayGridWnd::AdjustDate(int nNum, BOOL bPost, ADJUSTFLAG adjustFlag)
{
if (nNum == 0)
return FALSE;
BOOL bRetVal = TRUE;
int nCurYear = m_pTime->GetYear();
int nAdjustYear;
int nAdjustMonth;
COleDateTimeSpan timeOneDaySpan(1, 0, 0, 0);
switch (adjustFlag)
{
case ADJUST_YEAR_DELTA:
case ADJUST_YEAR_ABS:
if (adjustFlag == ADJUST_YEAR_DELTA)
{
nAdjustYear = nCurYear + nNum;
}
else
{
nAdjustYear = nNum;
}
{
int nDay = m_pTime->GetDay();
do
{
// only 02.29
m_pTime->SetDate(nAdjustYear,
m_nCurMonth, nDay);
-- nDay;
}
while (m_pTime->GetStatus() != COleDateTime::valid);
}
if (bPost)
{
GetParent()->PostMessage(WMDATE_CHANGEDATE,
CM_CHANGEYEAR, nAdjustYear);
bRetVal = FALSE;
}
break;
case ADJUST_MONTH_DELTA:
case ADJUST_MONTH_ABS:
if (adjustFlag == ADJUST_MONTH_DELTA)
{
nAdjustMonth = m_nCurMonth + nNum - 1;
nAdjustYear = nCurYear;
while (nAdjustMonth < 0)
{
-- nAdjustYear;
nAdjustMonth += nMonthsInYear;
}
nAdjustYear += nAdjustMonth / nMonthsInYear;
nAdjustMonth %= nMonthsInYear;
++ nAdjustMonth;
}
else // same year
{
ASSERT(nNum > 0 && nNum <= nMonthsInYear);
nAdjustMonth = nNum;
nAdjustYear = nCurYear;
}
{
int nDay = m_pTime->GetDay();
do
{
m_pTime->SetDate(nAdjustYear,
nAdjustMonth, nDay);
-- nDay;
}
while (m_pTime->GetStatus() != COleDateTime::valid);
}
if (bPost)
{
if (nAdjustYear != nCurYear)
{
GetParent()->PostMessage(WMDATE_CHANGEDATE,
CM_CHANGEYEAR, nAdjustYear);
bRetVal = FALSE;
}
if (nAdjustMonth != m_nCurMonth)
{
GetParent()->PostMessage(WMDATE_CHANGEDATE,
CM_CHANGEMONTH, nAdjustMonth);
bRetVal = FALSE;
}
}
break;
case ADJUST_DAY_DELTA:
{
COleDateTimeSpan timeSpan(nNum, 0, 0, 0);
*m_pTime += timeSpan;
nAdjustYear = m_pTime->GetYear();
nAdjustMonth = m_pTime->GetMonth();
if (m_bShowOtherMonthDay == FALSE)
{
if (nAdjustYear != nCurYear ||
nAdjustMonth != m_nCurMonth)
{
*m_pTime -= timeSpan;
// avoid PostMessage to Parent
nAdjustYear = nCurYear;
nAdjustMonth = m_nCurMonth;
bRetVal = FALSE;
}
}
if (bPost)
{
if (nAdjustYear != nCurYear)
{
GetParent()->PostMessage(WMDATE_CHANGEDATE,
CM_CHANGEYEAR, nAdjustYear);
bRetVal = FALSE;
}
if (nAdjustMonth != m_nCurMonth)
{
GetParent()->PostMessage(WMDATE_CHANGEDATE,
CM_CHANGEMONTH, nAdjustMonth);
bRetVal = FALSE;
}
}
break;
}
default:
ASSERT(FALSE);
}
return bRetVal;
}
void CDayGridWnd::DrawOneDay(CDC* pDC, COleDateTime* pTime)
{
int nEdge;
if (*pTime != *m_pTime)
{
nEdge = EDGE_SUNKEN;
if (pTime->GetMonth() != m_nCurMonth)
{
pDC->SetTextColor(m_clrTextNotCurMonthDay);
}
else
{
if (IsHoliday(pTime))
pDC->SetTextColor(m_clrTextHoliday);
else
pDC->SetTextColor(m_clrTextNormalDay);
}
}
else
{
nEdge = EDGE_RAISED;
pDC->SetTextColor(m_clrTextCurDay);
}
COleDateTimeSpan timeSpan = *pTime - m_firstDayOfMonth;
int nIndex = timeSpan.GetDays() + nDaysInWeek;
ASSERT(TRUE);
pDC->FillSolidRect(&(m_pRectArray[nIndex]), ::GetSysColor(COLOR_3DFACE));
pDC->DrawEdge(&(m_pRectArray[nIndex]), nEdge, BF_RECT);
TCHAR pBuffer[3];
pDC->ExtTextOut(
m_pRectArray[nIndex].left + m_pRectArray[nIndex].Width() / 2,
m_pRectArray[nIndex].top + 1,
ETO_CLIPPED,
&(m_pRectArray[nIndex]),
::itoa(pTime->GetDay(), pBuffer, 10),
NULL);
}
BEGIN_MESSAGE_MAP(CDayGridWnd, CWnd)
//{{AFX_MSG_MAP(CDayGridWnd)
ON_WM_PAINT()
ON_WM_DESTROY()
ON_WM_LBUTTONDOWN()
ON_WM_KEYDOWN()
ON_WM_GETDLGCODE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDayGridWnd message handlers
void CDayGridWnd::OnPaint()
{
CPaintDC dc(this); // device context for painting
if (m_bShowOtherMonthDay == FALSE)
{
CRect rtBounds; // clear the pane, because some month less then other month
GetClientRect(&rtBounds);
dc.FillSolidRect(&rtBounds, ::GetSysColor(COLOR_3DFACE));
}
dc.SetTextAlign(TA_TOP | TA_CENTER);
dc.SetBkMode(TRANSPARENT);
HFONT hFont = (HFONT)::GetCurrentObject(dc.GetSafeHdc(), OBJ_FONT);
CFont* pOldFont = CFont::FromHandle(hFont);
CFont font;
LOGFONT logFont;
pOldFont->GetLogFont(&logFont);
logFont.lfWeight = 800;
logFont.lfItalic = TRUE;
VERIFY(font.CreateFontIndirect(&logFont));
pOldFont = dc.SelectObject(&font);
dc.SetTextColor(m_clrTextWeekName);
for (int j = 0; j < nDaysInWeek; ++ j)
{
dc.DrawEdge(&(m_pRectArray[j]), EDGE_ETCHED, BF_RECT);
dc.ExtTextOut(
m_pRectArray[j].left + m_pRectArray[j].Width() / 2,
m_pRectArray[j].top + 1,
ETO_CLIPPED,
&(m_pRectArray[j]),
m_aStrDayOfWeekName[j],
NULL);
}
dc.SelectObject(pOldFont);
COleDateTimeSpan timeFirstDrawDaySpan(m_nStartDayIndex - nDaysInWeek, 0, 0, 0);
COleDateTime time = m_firstDayOfMonth + timeFirstDrawDaySpan;
COleDateTimeSpan timeOneDaySpan(1, 0, 0, 0);
for (int i = m_nStartDayIndex; i < m_nEndDayIndex; ++ i)
{
DrawOneDay(&dc, &time);
time += timeOneDaySpan;
}
// Do not call CWnd::OnPaint() for painting messages
}
void CDayGridWnd::OnDestroy()
{
CWnd::OnDestroy();
if (m_pRectArray != NULL)
{
delete m_pRectArray;
m_pRectArray = NULL;
}
}
void CDayGridWnd::OnLButtonDown(UINT nFlags, CPoint point)
{
SetFocus();
for (int i = m_nStartDayIndex; i < m_nEndDayIndex; ++ i)
{
if (m_pRectArray[i].PtInRect(point))
break;
}
if (i != m_nEndDayIndex) // founded !
{
COleDateTimeSpan timeCurToFirstSpan =
*m_pTime - m_firstDayOfMonth;
int nCurToFirstSpan = timeCurToFirstSpan.GetDays();
int nCurToNewSpan = i - nDaysInWeek - nCurToFirstSpan;
COleDateTime oldTime = *m_pTime;
if (AdjustDate(nCurToNewSpan, TRUE, ADJUST_DAY_DELTA))
{
CClientDC dc(this);
dc.SetTextAlign(TA_TOP | TA_CENTER);
dc.SetBkMode(TRANSPARENT);
DrawOneDay(&dc, &oldTime);
DrawOneDay(&dc, m_pTime);
}
}
CWnd::OnLButtonDown(nFlags, point);
}
void CDayGridWnd::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
int nDaySpan = 0;
int nMonthSpan = 0;
switch (nChar)
{
case VK_LEFT:
nDaySpan = -1;
break;
case VK_RIGHT:
nDaySpan = 1;
break;
case VK_UP:
nDaySpan = -7;
break;
case VK_DOWN:
nDaySpan = 7;
break;
case VK_NEXT:
nMonthSpan = 1;
break;
case VK_PRIOR:
nMonthSpan = -1;
break;
default:
CWnd::OnKeyDown(nChar, nRepCnt, nFlags);
return;
}
COleDateTime oldTime = *m_pTime;
BOOL bRedraw = FALSE;
if (nDaySpan != 0)
bRedraw = AdjustDate(nDaySpan, TRUE, ADJUST_DAY_DELTA);
else
bRedraw = AdjustDate(nMonthSpan, TRUE, ADJUST_MONTH_DELTA);
if (bRedraw)
{
CClientDC dc(this);
dc.SetTextAlign(TA_TOP | TA_CENTER);
dc.SetBkMode(TRANSPARENT);
DrawOneDay(&dc, &oldTime);
DrawOneDay(&dc, m_pTime);
}
}
UINT CDayGridWnd::OnGetDlgCode()
{
return DLGC_WANTARROWS;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -