⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 daygridwnd.cpp

📁 串口调试助手的源代码
💻 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 + -