万年历实训报告Word文档格式.docx
《万年历实训报告Word文档格式.docx》由会员分享,可在线阅读,更多相关《万年历实训报告Word文档格式.docx(44页珍藏版)》请在冰豆网上搜索。
TextOut()
该函数用当前选择的字体、背景颜色和正文颜色将一个字符串写到指定位置。
CreatSolidBrush()
创建刷子
CreateFont()
该函数创建一种有特殊性的逻辑字体,此逻辑字体可以在后面被任何设备选择。
SelectObject()
该函数选择一对象到指定的设备上下文环境中,该新对象替换先前的相同类型的对象。
BitBlt()
该函数对指定的源设备环境区域中的像素进行位块(bit_block)转换,以传送到目标设备环境。
SetRect()
设置指定矩形的内容
函数用来设置要绘制的文体颜色。
可以将表格当中的文字设置为一些特殊的颜色。
wsprintf()
整数转换为字符串,宽字符,用Unicode码
LoadImage()
该函数装载图标,光标,或位图。
FillRect()
是指该函数用指定的画刷填充矩形
2.2Win32消息机制
Windows操作系统最大的特点就是其图形化的操作界面,其图形化界面是建立在其消息处理机制这个基础之上的。
如果不理解Windows消息处理机制,肯定无法深入的理解Windows编程。
Windows消息分为系统消息和用户自定义消息,可分为标准windows消息、命令消息和通知消息。
根据已给样本的提示,绘制了日历的圆角矩形背景,并且根据公历日期转换为农历日期的原理来计算出农历,并在日历上标注了一些重要节日,像“春节、元宵节、清明节、端午节、中秋节”等一些重要的农历节日,并且将节假日的字体颜色设置为紫红色;
以及“元旦、劳动节、儿童节、教师节、国庆节等阳历节日,并且将节假日的字体颜色也设置为紫红色,然后又写了获取当前系统本机时间的函数,成功的获得了当前本机的时间。
通过一些命令按钮的设置,实现了时钟皮肤,日历背景皮肤的选择改变,时间的查找等。
3.总体设计与详细设计
总体设计:
(1)调用判断是不是闰年的函数。
(2)根据公历日期获得农历日期。
(3)利用泰勒公式由公历日期计算星期。
(4)利用公历日期计算该年的天干地支及生肖等。
(5)在钟表上获得当前本地的系统时间与日期等的显示。
(6)在日历上获得每年每月的日期等的信息并显示。
详细设计:
1、首先绘制日历的圆角矩形背景,用CreateSolidBrush()函数做出矩形的背景颜色,还有CreateRoundRectRgn()函数实现圆角矩形,在日历的右上端和右下端分别输出阳历的当前年月份,及阴历的天干地支年等。
也输出了当年的生肖和生肖图片。
2、判断农历的每月有多少天,调用判断是否为闰年的函数,若为闰年,则定义二月为29天,通过一switch函数输出十二个月的天数。
3、利用SelectObject(),TextOut(),wsprintf()等函数写入标题(设置不同颜色),利用MoveToEx()和LineTo()函数画出日历表的标题框并填充颜色。
4、调用公历转为农历的函数并用for循环获得每日的农历日期,并调CreateSolidBrush(函数标出当天的日期,该日期显示框填充为不同的颜色。
还有节日的标注。
5、对日历上的几个按钮进行设置,使得当年月份发生改变时,日历表可以正常显示。
6、日历表背景的更换,运用了LoadImage(),SelectObject()等函数实现。
7、获得本地系统时间,在表盘上的正确位置输出当天的年月日(调用CreateFont函数按角度输出)及当地时间和星期,公历和阳历均显示,还输出了天干地支和生肖。
8、扩展功能增加了皮肤设置和整点报时功能。
3.1系统模块划分
主界面子系统负责程序主界面的显示、程序主逻辑的控制、以及其他子系统的调用。
分为以下模块:
程序入口模块、消息处理模块、时间处理模块、界面贴图模块。
下图是模块之间的关系图。
其中,程序入口模块,是Windows程序的入口函数,在该模块内创建主界面。
消息处理模块负责响应用户的鼠标和键盘操作。
时间处理模块负责时间运算和显示。
界面贴图模块负责主界面的图像显示。
以下是各模块的详细说明:
模块名称
模块功能
输入
输出
其他说明
程序入口模块
在该模块内创建主界面
Windows调用
主界面创建;
定时器安装
Windows程序的入口函数
消息处理模块
负责响应用户的鼠标和键盘操作
用户和键盘鼠标输,Windows其他事件
消息处理
Windows程序的窗口函数
时间处理模块
负责时间运算和显示
定时器间隔
时间
Windows程序的定时器回调函数
界面贴图模块
负责主界面的图像显示
位图
位图显示
无
3.2主要功能模块
4.编码实现
4.1Main.c
#include<
Windows.h>
string.h>
#include"
resource.h"
#pragmacomment(lib,"
WinLib.lib"
)
voidSetDlgMenuID(UINTnMainDlgID,UINTnCalendarDlgID,UINTnMenuID);
voidSetButtonID(UINTnCalendarID,UINTnExitID,UINTnblueID,UINTnyellowID,UINTngreenID,UINTnpurpleID);
INT_PTRShowMainDlg();
/*
*********************************************************
API函数参考:
GetLocalTime:
获得当前时间(公历:
年、月、日、周)
MoveToEx:
移动划线的起点
LineTo:
绘制到某一点
SetTextColor:
设置要绘制的文字颜色
TextOut:
绘制文字
SetBkMode:
设置背景显示模式
wsprintf:
整数转换为字符串,宽字符,用Unicode码
GetClientRect:
获取窗口大小
GetDC:
获取内存设备
SetTimer:
设置定时器
FillRect:
填充矩形
CreateSolidBrush:
创建刷子
RGB:
设置RGB颜色
CreateFont:
创建一种有特殊性的字体
结构体类型参考:
SYSTEMTIME:
描述时间类型,包括年月日、时分秒、周
*/
HINSTANCEg_hInst;
//保存操作系统传递进来的"
应用程序实例句柄"
全局变量
//Windows程序入口函数
intWINAPIWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,LPSTRlpCmdLine,intnShowCmd)
{
g_hInst=hInstance;
//应用程序实例句柄被赋值为一个应用程序的实例句柄
SetDlgMenuID(IDD_DLG_CLOCK,IDD_DLG_CALENDAR,IDR_MENU);
SetButtonID(ID_CALENDAR,ID_EXIT,ID_blue,ID_yellow,ID_green,ID_purple);
ShowMainDlg(IDD_DLG_CLOCK);
}
typedefstruct_stDateTime//定义日期结构体
intnYear;
intnMonth;
intnDay;
}stDateTime;
//定义日期结构体变量
//定义表格,存储年-2099年的农历信息:
每年的大小月、闰月信息、春节所在的公历日期,用十六进制存储的
unsignedintLunarCalendarTable[199]=
0x04AE53,0x0A5748,0x5526BD,0x0D2650,0x0D9544,0x46AAB9,0x056A4D,0x09AD42,0x24AEB6,0x04AE4A,/*1901-1910*/
0x6A4DBE,0x0A4D52,0x0D2546,0x5D52BA,0x0B544E,0x0D6A43,0x296D37,0x095B4B,0x749BC1,0x049754,/*1911-1920*/
0x0A4B48,0x5B25BC,0x06A550,0x06D445,0x4ADAB8,0x02B64D,0x095742,0x2497B7,0x04974A,0x664B3E,/*1921-1930*/
0x0D4A51,0x0EA546,0x56D4BA,0x05AD4E,0x02B644,0x393738,0x092E4B,0x7C96BF,0x0C9553,0x0D4A48,/*1931-1940*/
0x6DA53B,0x0B554F,0x056A45,0x4AADB9,0x025D4D,0x092D42,0x2C95B6,0x0A954A,0x7B4ABD,0x06CA51,/*1941-1950*/
0x0B5546,0x555ABB,0x04DA4E,0x0A5B43,0x352BB8,0x052B4C,0x8A953F,0x0E9552,0x06AA48,0x6AD53C,/*1951-1960*/
0x0AB54F,0x04B645,0x4A5739,0x0A574D,0x052642,0x3E9335,0x0D9549,0x75AABE,0x056A51,0x096D46,/*1961-1970*/
0x54AEBB,0x04AD4F,0x0A4D43,0x4D26B7,0x0D254B,0x8D52BF,0x0B5452,0x0B6A47,0x696D3C,0x095B50,/*1971-1980*/
0x049B45,0x4A4BB9,0x0A4B4D,0xAB25C2,0x06A554,0x06D449,0x6ADA3D,0x0AB651,0x093746,0x5497BB,/*1981-1990*/
0x04974F,0x064B44,0x36A537,0x0EA54A,0x86B2BF,0x05AC53,0x0AB647,0x5936BC,0x092E50,0x0C9645,/*1991-2000*/
0x4D4AB8,0x0D4A4C,0x0DA541,0x25AAB6,0x056A49,0x7AADBD,0x025D52,0x092D47,0x5C95BA,0x0A954E,/*2001-2010*/
0x0B4A43,0x4B5537,0x0AD54A,0x955ABF,0x04BA53,0x0A5B48,0x652BBC,0x052B50,0x0A9345,0x474AB9,/*2011-2020*/
0x06AA4C,0x0AD541,0x24DAB6,0x04B64A,0x69573D,0x0A4E51,0x0D2646,0x5E933A,0x0D534D,0x05AA43,/*2021-2030*/
0x36B537,0x096D4B,0xB4AEBF,0x04AD53,0x0A4D48,0x6D25BC,0x0D254F,0x0D5244,0x5DAA38,0x0B5A4C,/*2031-2040*/
0x056D41,0x24ADB6,0x049B4A,0x7A4BBE,0x0A4B51,0x0AA546,0x5B52BA,0x06D24E,0x0ADA42,0x355B37,/*2041-2050*/
0x09374B,0x8497C1,0x049753,0x064B48,0x66A53C,0x0EA54F,0x06B244,0x4AB638,0x0AAE4C,0x092E42,/*2051-2060*/
0x3C9735,0x0C9649,0x7D4ABD,0x0D4A51,0x0DA545,0x55AABA,0x056A4E,0x0A6D43,0x452EB7,0x052D4B,/*2061-2070*/
0x8A95BF,0x0A9553,0x0B4A47,0x6B553B,0x0AD54F,0x055A45,0x4A5D38,0x0A5B4C,0x052B42,0x3A93B6,/*2071-2080*/
0x069349,0x7729BD,0x06AA51,0x0AD546,0x54DABA,0x04B64E,0x0A5743,0x452738,0x0D264A,0x8E933E,/*2081-2090*/
0x0D5252,0x0DAA47,0x66B53B,0x056D4F,0x04AE45,0x4A4EB9,0x0A4D4C,0x0D1541,0x2D92B5/*2091-2099*/
};
//定义天干地支表,年的数据
char*TianGanDizhi[60]=
"
甲子"
"
乙丑"
"
丙寅"
丁卯"
戊辰"
已巳"
庚午"
辛未"
壬申"
癸酉"
甲戌"
乙亥"
丙子"
丁丑"
戊寅"
已卯"
庚辰"
辛巳"
壬午"
癸未"
甲申"
乙酉"
丙戌"
丁亥"
戊子"
已丑"
庚寅"
辛卯"
壬辰"
癸巳"
甲午"
乙未"
丙申"
丁酉"
戊戌"
已亥"
庚子"
辛丑"
壬寅"
癸卯"
甲辰"
乙巳"
丙午"
丁未"
戊申"
已酉"
庚戌"
辛亥"
壬子"
癸丑"
甲寅"
乙卯"
丙辰"
丁巳"
戊午"
已未"
庚申"
辛酉"
壬戌"
癸亥"
//定义一个月中的农历天数据
char*ChDayTable[]=
*"
初一"
初二"
初三"
初四"
初五"
初六"
初七"
初八"
初九"
初十"
十一"
十二"
十三"
十四"
十五"
十六"
十七"
十八"
十九"
二十"
廿一"
廿二"
廿三"
廿四"
廿五"
廿六"
廿七"
廿八"
廿九"
三十"
//定义一年中的农历月数据
char*ChMonthTable[]={"
正"
二"
三"
四"
五"
六"
七"
八"
九"
十"
腊"
char*shengxiao[]={"
鼠"
牛"
虎"
兔"
龙"
蛇"
马"
羊"
猴"
鸡"
狗"
猪"
//定义表格,存储阳历每月日离元旦的天数(不考虑闰年)
unsignedintMonthAdd[12]={0,31,59,90,120,151,181,212,243,273,304,334};
//定义用户要显示的年、月、日
unsignedintnCurrentYear=0;
unsignedintnCurrentMonth=0;
unsignedintnCurrentDay=0;
UINTSONG=0,ON=0;
//控制音乐
//————————判断某年是否为公历闰年————————//
intIsLeapYear(WORDYear){
if(Year%100==0)
{if(Year%400==0)
return1;
elseif(Year%4==0)
//————————公历日期转农历日期的函数————————//
voidSunToLunar(conststDateTime*pSunDay,stDateTime*pLunarDay)
inti=0;
intSunDiff=0;
intSpringDiff=0;
intnSpringYear=pSunDay->
nYear;
intnSpringMonth=1;
intnSpringDay=0;
//计算当前公历日离当年元旦的天数
SunDiff=MonthAdd[pSunDay->
nMonth-1]+pSunDay->
nDay-1;
if(IsLeapYear(pSunDay->
nYear)&
&
(pSunDay->
nMonth>
2))//若是闰年且大于月,天数再加
SunDiff++;
//计算春节所在公历日离元旦的天数:
通过查表,计算当年的春节所在的公历日期
if(((LunarCalendarTable[pSunDay->
nYear-1901]&
0x60)>
>
5)==1)//若春节在公历月
SpringDiff=(LunarCalendarTable[pSunDay->
nYear-1901]&
0x1F)-1;
else//若春节在公历月
0x1F)-1+31;
//SunDiff和SpringDiff的差就是当前公历日离春节的天数
if(SunDiff>
=SpringDiff)//公历日在春节后
{
intx=SunDiff-SpringDiff;
intbLunar=(LunarCalendarTable[nSpringYear-1901]&
0xF00000)>
20;
//闰月月份
i=0;
nSpringMonth=1;
for(;
;
{
inta=(LunarCalendarTable[pSunDay->
nYear-1901]&
(0x80000>
i));
//计算大小月
if(a==0)
a=29;
else
a=30;
if(x<
a)
break;
x=x-a;
i++;
nSpringMonth++;
}
nSpringDay=x+1;
//如果有闰月
if(nSpringMonth>
bLunar&
bLunar>
0)
nSpringMonth--;
}
else//公历日在春节前
intx=SpringDiff-SunDiff;
intnShift=0;
nSpringYear--;
//需要上一年的农历信息
nSpringMonth=12;
//从最后一个月开始计算
if(bLunar==0)//如果没有闰月
nShift=0x100;
else
nShift=0x80;
inta=(LunarCalendarTable[nSpringYear-1901]&
(nShift<
<
{
x=a-x;
}
if(nSpringMonth<
pLunarDay->
nYear=nSpringYear;
nMonth=nSpringMonth;
nDay=nSpringDay;
//————————根据公历日期获得星期————————//
intGetDayOfWeek(conststDateTime*pSunDay)
//根据泰勒公式
//nWeek