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

📄 calendar1.cpp

📁 公历及阴历算法(Calendar)
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// Calendar1.cpp : implementation file
//
/***************************************************************************
   致看到这些源代码的兄弟:
       你好!
       这本来是我为一个商业PDA产品开发的日历程序,最近移植于PC机上, 所以算法
   和数据部分是用纯C++写的,不涉及MFC,所有的代码都是以短节省存储空间为主要目
   的.
	   很高兴你对这些代码有兴趣,你可以随意复制和使用些代码,唯一有一点小小的
   愿望:在你使用和复制给别人时,别忘注明这些代码作者:-)。程序代码也就罢了,后
   面的数据可是我辛辛苦苦从万年历上找出来输进去的。
	   如果你有什么好的意见不妨Mail给我。

       wangfei@hanwang.com.cn
	   wangfei@engineer.com.cn
                                                                 2000年3月
****************************************************************************/
#include "stdafx.h"
#include "Calendar.h"
#include "Calendar1.h"
#include "Calendarfrm.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CCalendar


extern WORD gLunarMonthDay[];
extern BYTE gLunarMonth[];
extern BYTE gLunarHolDay[];

const WORD START_YEAR =1901;
const WORD END_YEAR   =2050;

void CCalendar::l_InitData()
{
	SYSTEMTIME systime;
	::GetSystemTime(&systime);

	m_iYear  = systime.wYear;
	m_iMonth = systime.wMonth;
	m_iDay   = systime.wDay;

	m_dwBackColor      = RGB(255,255,255);
	m_dwForeColor      = RGB(0,0,0);
	m_dwSelColor       = RGB(150,150,230);
	m_dwSelForeColor   = RGB(255,255,255);
	m_dwTitleBkColor     = RGB(190,70,70);
	m_dwTitleColor = RGB(255,255,0);

}

CCalendar::CCalendar(WORD iYear, WORD iMonth, WORD iDay)
{
   if(!SetDate(iYear, iMonth, iDay))
	   l_InitData();
}

CCalendar::CCalendar()
{
   l_InitData();	
}

CCalendar::~CCalendar()
{
  DestroyWindow(); 
}


BEGIN_MESSAGE_MAP(CCalendar, CWnd)
	//{{AFX_MSG_MAP(CCalendar)
	ON_WM_PAINT()
	ON_WM_LBUTTONDOWN()
	ON_WM_CONTEXTMENU()
	ON_WM_CREATE()
	//}}AFX_MSG_MAP
	ON_COMMAND(ID_TITLEBKCOLOR, OnTitleBkColor)
	ON_COMMAND(ID_TITLECOLOR,   OnTitleColor)
	ON_COMMAND(ID_SELCOLOR,     OnSelColor)
	ON_COMMAND(ID_FORECOLOR,    OnForeColor)
END_MESSAGE_MAP()

#define COL_WIDTH    32
#define ROW_HEIGHT   20
#define TITLE_HEIGHT 20

BOOL CCalendar::Create(RECT &rect, CWnd *pParentWnd, UINT nID)
{
    CString szClassName = AfxRegisterWndClass(CS_CLASSDC|CS_SAVEBITS|
		                                      CS_HREDRAW|CS_VREDRAW,
                                              0, (HBRUSH)CBrush(RGB(255,255,255)), 0);
    rect.right = rect.left + COL_WIDTH*7 +4;
    rect.bottom = rect.top + TITLE_HEIGHT+ROW_HEIGHT*6 +10 ;
	if(!CWnd::CreateEx(WS_EX_CLIENTEDGE, szClassName, _T(""),
		                WS_CHILD|WS_VISIBLE|WS_TABSTOP, rect, 
						pParentWnd, nID, NULL)) 

		   return FALSE;

    UpdateWindow();
    for(int i=0; i<42; i++)
		m_oBitMapList[i].LoadBitmap(IDB_BITMAP1+i); 

	m_oPopMenu.CreatePopupMenu();
	m_oPopMenu.AppendMenu(MF_STRING, ID_TITLEBKCOLOR, _T("标题背景色..."));
	m_oPopMenu.AppendMenu(MF_STRING, ID_TITLECOLOR,   _T("标题前景色...")); 
	m_oPopMenu.AppendMenu(MF_STRING, ID_FORECOLOR ,   _T("日期前景色..."));
 	m_oPopMenu.AppendMenu(MF_STRING, ID_SELCOLOR,     _T("选中区颜色..."));
		
	return TRUE;
}

/////////////////////////////////////////////////////////////////////////////
// CCalendar message handlers
void CCalendar::l_PaintTitle(CPaintDC &dc)
{
   CRect rect ;
   GetClientRect(&rect);

   rect.left ++;   rect.top ++;
   rect.right --;  rect.bottom = rect.top + TITLE_HEIGHT;
   dc.FillRect(&rect, &CBrush(m_dwTitleBkColor));

   dc.SetBkColor(m_dwTitleBkColor); 
   dc.SetTextColor(m_dwTitleColor); 

   int startx = rect.left +8;
   char sztext[][3]={"日","一","二","三","四","五","六"};
   for(int i=0; i <7; i++)
   {
      dc.TextOut(startx, rect.top +2, sztext[i]);
      startx += COL_WIDTH;
   }
}

void CCalendar:: l_PaintOneDay(CPaintDC &dc, CDC &imgdc, WORD &iDay, 
							   WORD &iLunarYear, WORD &iLunarMonth, 
							   WORD &iLunarDay, 
							   LONG startx, LONG starty, BYTE bSecondLeapMonth)
{
	 char text[3];
     sprintf(text, "%2d", iDay);

     // select icon
	 if(iLunarDay!=1)
	      imgdc.SelectObject(&m_oBitMapList[iLunarDay-1]);
	 else
	      imgdc.SelectObject(&m_oBitMapList[29+iLunarMonth]);

     // if day == current day
	 if(iDay++ == m_iDay)
	 {
		SetRect(&m_sSelRect, startx-1, starty, startx +COL_WIDTH-3,starty + ROW_HEIGHT);
		dc.FillRect(m_sSelRect, &CBrush(m_dwSelColor)); 
		dc.SetTextColor(m_dwSelForeColor);
		dc.SetBkColor(m_dwSelColor);
		dc.TextOut(startx, starty +2, text);
		dc.SetBkColor(m_dwBackColor);
		dc.SetTextColor(m_dwForeColor); 
		dc.BitBlt(startx+17, starty +2, 8,16,&imgdc,0,0,MERGEPAINT);  		
	 }
	 else
	 {
		dc.TextOut(startx, starty+2, text);
		dc.BitBlt(startx+17, starty +2, 8,16,&imgdc,0,0,SRCCOPY);  
	 }
     if(iLunarYear <START_YEAR && iLunarDay == 29)
		 iLunarDay = 1, iLunarMonth++;
	 else if(iLunarDay<29)
		  iLunarDay++;
	 else
	 {
		 LONG days = LunarMonthDays(iLunarYear, iLunarMonth);
		 if(!HIWORD(days) && iLunarDay == LOWORD(days) 
			             || bSecondLeapMonth && iLunarDay == HIWORD(days))
			 iLunarMonth = (iLunarMonth)%12+1;
		 if(iLunarDay < LOBYTE(days))
			 iLunarDay++;
		 else
			 iLunarDay =1;
	 }
}

void CCalendar::l_PaintDate(CPaintDC &dc)
{
   CDC imgdc;
   imgdc.CreateCompatibleDC(&dc);

   RECT rect;
   GetClientRect(&rect);
   rect.top  +=TITLE_HEIGHT+6;

   dc.SetBkColor(m_dwBackColor);
   dc.SetTextColor(m_dwForeColor);

   WORD day =1;
   WORD iLunarYear, iLunarMonth, iLunarDay;
   BYTE bSecondLeapMonth = l_CalcLunarDate(iLunarYear, iLunarMonth, iLunarDay, 
	                              CalcDateDiff(m_iYear, m_iMonth, 1));
   //GetLunarDate(m_iYear, m_iMonth, 1, iLunarYear, iLunarMonth, iLunarDay); 

   for(int i=0; i<6; i++, rect.top += ROW_HEIGHT)
   {
	   long startx = rect.left +2;
	   for(int j=0; j<7; j++,startx += COL_WIDTH)
	   {
		   if(j < WeekDay(m_iYear, m_iMonth, 1) && i==0)
		 	   continue;

		   if(day > MonthDays(m_iYear, m_iMonth))
			   break;
		   
           l_PaintOneDay(dc, imgdc, day, iLunarYear, iLunarMonth,
			   iLunarDay, startx, rect.top, bSecondLeapMonth);
	   }
   }
}

void CCalendar::OnPaint() 
{
    CPaintDC dc(this); // device context for painting
    
    CFont *font = ((CCalendarFrm *)GetParent())->GetDispFont();
    dc.SelectObject(font);
    dc.SetMapMode(0); 
    l_PaintTitle(dc);
    l_PaintDate(dc);
    
}

LONG CCalendar::CalcDateDiff(WORD iEndYear, WORD iEndMonth, WORD iEndDay,
		                    WORD  iStartYear, WORD iStartMonth, WORD iStartDay)
{
	WORD monthday[]={0, 31, 59 ,90, 120, 151, 181, 212, 243, 273, 304, 334}; 

	//计算两个年份1月1日之间相差的天数
	LONG iDiffDays =(iEndYear - iStartYear)*365;
	iDiffDays += (iEndYear-1)/4 - (iStartYear-1)/4;
	iDiffDays -= ((iEndYear-1)/100 - (iStartYear-1)/100);
	iDiffDays += (iEndYear-1)/400 - (iStartYear-1)/400;

    //加上iEndYear年1月1日到iEndMonth月iEndDay日之间的天数
    iDiffDays += monthday[iEndMonth-1] +
		                           (IsLeapYear(iEndYear)&&iEndMonth>2? 1: 0);
    iDiffDays += iEndDay;

	//减去iStartYear年1月1日到iStartMonth月iStartDay日之间的天数
	iDiffDays -= (monthday[iStartMonth-1] + 
		                  (IsLeapYear(iStartYear)&&iStartMonth>2 ? 1: 0));
    iDiffDays -= iStartDay;	
	return iDiffDays;
}

BYTE  CCalendar::l_CalcLunarDate(WORD &iYear, WORD &iMonth ,WORD &iDay, LONG iSpanDays)
{
	//阳历1901年2月19日为阴历1901年正月初一
	//阳历1901年1月1日到2月19日共有49天
	BYTE rcode =0;
   	if(iSpanDays <49)
	{
		iYear  = START_YEAR-1;
		if(iSpanDays <19)
		{ 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -