📄 uicalendar.c
字号:
/*********************************************************************/
// 文 件 名: uiCalendar.cpp
// 程序说明: 日历控件
// 程序设计: 党德华
// 2001.11.04 设计完成 说明文档:R004-S214-0001
// 程序审查: 宋军霞
// 2002.06.01 审查完成 说明文档:R004-S214-0001
// 项目编号: R004-S214
// 版 本: V1.0
// 版 权: Reality Plus Technology (ShenZhen) Co.,Ltd.
/*********************************************************************/
#include <uiWnd.h>
#include <uiCalendar.h>
#include <stdio.h>
extern TGuiWindow *gpTopWindow;
extern int gLanguage;
const unsigned short DAY_TABLE[][13]={
{0,31,28,31,30,31,30,31,31,30,31,30,31},
{0,31,29,31,30,31,30,31,31,30,31,30,31} };
const WORD Nongli_Month[] =
{
/*1900*/0xd6d2,0x0752,0x5ea5,0xc64a,0x064b,0x4a9b,0xc556,0x056a,0x2b59,0xc752,
0x6752,0xcb25,0x0b25,0x5a4b,0xc4ab,0x02ad,0x256b,0x8b69,0x7da9,0xcd92,
0x0e92,0x5d25,0xca4d,0x0a56,0x42b6,0xc5b5,0x06d4,0x2ea9,0xce92,0x6e92,
0x8d26,0x052b,0x5a57,0xc2b6,0x0b5a,0x36d4,0x8ec9,0x7749,0xc693,0x0a93,
0x652b,0x8a5b,0x0aad,0x456a,0xcb55,0x0ba4,0x2b49,0xca93,0x7a95,0xc52d,
/*1950*/0x0536,0x5aad,0xc5aa,0x05b2,0x3da5,0xcd4a,0x0d4a,0x9a95,0x0a97,0x6556,
0x8ab5,0x0ad5,0x46d2,0x8ea5,0x0ea5,0x364a,0x8c97,0x7a9b,0xc55a,0x056a,
0x5b69,0xc752,0x0b52,0x4b25,0xc64b,0x0a4b,0xd4ab,0x02ad,0x656d,0x8b69,
0x0da9,0x4d92,0xcd25,0x2d25,0xda4d,0x0a56,0x62b6,0x85b5,0x06d5,0x5ea9,
0xce92,0x0e92,0x3d26,0x8a56,0x0a57,0xd4d6,0x035a,0x56d5,0xc6c9,0x0749,
/*2000*/0x4693,0xc52b,0x052b,0x2a5b,0xc55a,0x756a,0xcb55,0x0ba4,0x5b49,0xca93,
0x0a95,0x452d,0x8aad,0x1ab5,0xd5aa,0x05d2,0x6da5,0xcd4a,0x0d4a,0x4c95,
0xc52e,0x0556,0x2ab5,0xc5b2,0x66d2,0x8ea5,0x6725,0x564b,0x8c97,0x0cab,
0x355a,0x8ad6,0x7b69,0xc752,0x0b52,0x6b25,0xca4b,0x0a4b,0x54ab,0x855b,
0x05ad,0x2b6a,0xcb52,0x7d92,0xcd25,0x0d25,0x5a55,0xc4ad,0x04b6,0x35b5,
/*2050*/0x8daa,0x0ec9,0xde92,0x0e92,0x6d26,0x8a56,0x0a57,0x44d6,0x86d5,0x0755,
0x0749
};
const char *const NewYear_Date[] =
{
"131","219","208","129","216","204","125","213","202","122",
"210","130","218","206","126","214","203","123","211","201",
"220","208","128","216","205","124","213","202","123","210",
"130","217","206","126","214","204","124","211","131","219",
"208","127","215","205","125","213","202","122","210","129",
"217","206","127","214","203","124","212","131","218","208",
"128","215","205","125","213","202","121","209","130","217",
"206","127","215","203","123","211","131","218","207","128",
"216","205","125","213","202","220","209","129","217","206",
"127","215","204","123","210","131","219","207","128","216",
"205","124","212","201","122","209","129","218","207","126",
"214","203","123","210","131","219","208","128","216","205",
"125","212","201","122","210","129","217","206","126","213",
"203","123","211","131","219","208","128","215","204","124",
"212","201","122","210","130","217","206","126","214","202",
"123","211","201","219","208","128","215","204","124","212",
"202",
};
// 判断是否为闰年
// 闰年返回1,平年返回0
int _guiCalendar_IsLeap(WORD year)
{
if((year%4) || (!(year%100) && (year%400)))
return 0;
else return 1;
}
// 获取当月天数
WORD _guiCalendar_GetDaysofMonth(WORD year,WORD month)
{
return DAY_TABLE[_guiCalendar_IsLeap(year)][month];
}
int _guiCalendar_GetDays(WORD year,WORD month,WORD day)
{
int offsetDay;
unsigned short offsetYear,i;
int flag;
offsetYear=year-1601;
offsetDay=offsetYear*365+offsetYear/4-offsetYear/100+offsetYear/400;
flag=_guiCalendar_IsLeap(year);
for(i=1;i<month;i++)
offsetDay+=DAY_TABLE[flag][i];
offsetDay+=day;
return offsetDay;
}
void _guiCalendar_GetDate(WORD *year,WORD *month,WORD *day,int offsetDay)
{
unsigned short i,temp;
int flag;
temp=offsetDay/146097;
*year=temp*400;
offsetDay-=temp*146097;
temp=offsetDay/36524;
*year+=temp*100;
offsetDay-=temp*36524;
temp=offsetDay/1461;
*year+=temp*4;
offsetDay-=temp*1461;
temp=offsetDay/365;
*year+=temp;
offsetDay-=temp*365;
if(offsetDay==0)
{
*year+=1600;
*month=12;
*day=31;
}
else
{
*year+=1601;
flag=_guiCalendar_IsLeap(*year);
*month=1;
for(i=1;i<12;i++)
{
if(offsetDay<=DAY_TABLE[flag][i])
break;
(*month)++;
offsetDay-=DAY_TABLE[flag][i];
}
*day=offsetDay;
}
}
int guiCalendar_GetDate(WORD *year, WORD *month, WORD *day, int offsetDay)
{
WORD maxDay;
if( *year<CALENDAR_YEAR_MIN || *year>CALENDAR_YEAR_MAX )
return CALENDAR_ERR; // 年份错误
if( *month<1 || *month>12 )
return CALENDAR_ERR; // 月份错误
if( *day<1 )
return CALENDAR_ERR; // 日期错误
maxDay=DAY_TABLE[_guiCalendar_IsLeap(*year)][*month]; // 当月天数
if(*day>maxDay)
return CALENDAR_ERR; // 日期错误
offsetDay+=_guiCalendar_GetDays(*year,*month,*day);
_guiCalendar_GetDate(year,month,day,offsetDay);
return CALENDAR_OK;
}
// 计算某天是星期几
int guiCalendar_GetWeek(WORD year,WORD month,WORD day)
{
WORD maxDay;
if( year<CALENDAR_YEAR_MIN || year>CALENDAR_YEAR_MAX )
return CALENDAR_ERR; // 年份错误
if( month<1 || month>12 )
return CALENDAR_ERR; // 月份错误
if( day<1 )
return CALENDAR_ERR; // 日期错误
maxDay=DAY_TABLE[_guiCalendar_IsLeap(year)][month]; // 当月天数
if(day>maxDay)
return CALENDAR_ERR; // 日期错误
return _guiCalendar_GetDays(year,month,day)%7;
}
int guiCalendar_GetNongli(WORD year, WORD month,WORD day, WORD *nMonth,WORD *nDay)
{
WORD tYear,tMonth,tDay,count,leapMonth,maxDay;
int flag,days;
char *p;
if( year<CALENDAR_YEAR_MIN || year>CALENDAR_YEAR_MAX )
return CALENDAR_ERR; // 年份错误
if( month<1 || month>12 )
return CALENDAR_ERR; // 月份错误
if( day<1 )
return CALENDAR_ERR; // 日期错误
maxDay=DAY_TABLE[_guiCalendar_IsLeap(year)][month]; // 当月天数
if(day>maxDay)
return CALENDAR_ERR; // 日期错误
tYear=year-1900;
p=(char *)NewYear_Date[tYear];
tMonth=p[0]-'0';
tDay=(p[1]-'0')*10+(p[2]-'0');
if( month>tMonth || (month==tMonth && day>=tDay) )
{
days=_guiCalendar_GetDays(year,month,day)-_guiCalendar_GetDays(year,tMonth,tDay);
}
else
{
tYear--;
p=(char *)NewYear_Date[tYear];
tMonth=p[0]-'0';
tDay=(p[1]-'0')*10+(p[2]-'0');
days=_guiCalendar_GetDays(year,month,day)-_guiCalendar_GetDays(year-1,tMonth,tDay);
}
count=Nongli_Month[tYear];
if(count & 0x8000)
{
leapMonth=(Nongli_Month[tYear-1]&0xf000)>>12;
if(count & 0x3000)
leapMonth+=8;
}
else
leapMonth=0;
flag=0;
*nMonth=1;
days++;
while(1)
{
if(days<=( (count&1)+29))
break;
days=days-( (count&1)+29);
if(*nMonth==leapMonth)
{
leapMonth=0;
flag=1;
}
else
{
(*nMonth)++;
flag=0;
if(*nMonth==12)
break;
}
count=count>>1;
}
if(flag)
(*nMonth)+=16;
*nDay=days;
return CALENDAR_OK;
}
#define NONGLI_WIDTH 8
void _guiCalendar_ShowNongli(HNDL handle,short x,short y,WORD month,WORD day)
{
if(day==1)
{
if(month>12)
{
guiPutImage(handle,x,y,x+NONGLI_WIDTH,y+5,icon_Gui_Nongli[15]);
x+=NONGLI_WIDTH;
guiPutImage(handle,x,y,x+NONGLI_WIDTH,y+5,icon_Gui_Nongli[month-16]);
}
else
{
guiPutImage(handle,x,y,x+NONGLI_WIDTH,y+5,icon_Gui_Nongli[month]);
x+=NONGLI_WIDTH;
guiPutImage(handle,x,y,x+NONGLI_WIDTH,y+5,icon_Gui_Nongli[14]);
}
}
else
{
if(day<11)
{
guiPutImage(handle,x,y,x+NONGLI_WIDTH,y+5,icon_Gui_Nongli[0]);
x+=NONGLI_WIDTH;
guiPutImage(handle,x,y,x+NONGLI_WIDTH,y+5,icon_Gui_Nongli[day]);
}
else if(day<20)
{
guiPutImage(handle,x,y,x+NONGLI_WIDTH,y+5,icon_Gui_Nongli[10]);
x+=NONGLI_WIDTH;
guiPutImage(handle,x,y,x+NONGLI_WIDTH,y+5,icon_Gui_Nongli[day%10]);
}
else if(day==20)
{
guiPutImage(handle,x,y,x+NONGLI_WIDTH,y+5,icon_Gui_Nongli[2]);
x+=NONGLI_WIDTH;
guiPutImage(handle,x,y,x+NONGLI_WIDTH,y+5,icon_Gui_Nongli[10]);
}
else if(day<30)
{
guiPutImage(handle,x,y,x+NONGLI_WIDTH,y+5,icon_Gui_Nongli[13]);
x+=NONGLI_WIDTH;
guiPutImage(handle,x,y,x+NONGLI_WIDTH,y+5,icon_Gui_Nongli[day%10]);
}
else
{
guiPutImage(handle,x,y,x+NONGLI_WIDTH,y+5,icon_Gui_Nongli[3]);
x+=NONGLI_WIDTH;
guiPutImage(handle,x,y,x+NONGLI_WIDTH,y+5,icon_Gui_Nongli[10]);
}
}
}
// 计算笔点的位置
int _guiCalendar_SearchPos(HNDL handle,WORD x,WORD y)
{
TGuiCalendar *pCalendar;
int day,pos;
short dayWidth,dayHeight,dayHGap,dayVGap;
pCalendar=(TGuiCalendar *)handle;
if( x<pCalendar->base.left || y<pCalendar->base.top ||
x>=pCalendar->base.right || y>=pCalendar->base.bottom )
return -1; // 日历区域之外
dayWidth=pCalendar->dayWidth;
dayHeight=pCalendar->dayHeight;
dayHGap=pCalendar->dayHGap;
dayVGap=pCalendar->dayVGap;
x-=pCalendar->base.left;
y-=pCalendar->base.top;
pos=(y/(dayHeight+dayVGap))*7+(x/(dayWidth+dayHGap)); // 计算位置
// 是否在有效检测区域
if( y>=(pos/7)*(dayHeight+dayVGap)+dayHeight || x>=(pos%7)*(dayWidth+dayHGap)+dayWidth )
return -1;
if(pos<pCalendar->week)
{
if(pCalendar->base.style & CALENDAR_LINE6)
pos+=42;
else
pos+=35;
}
day=pos-pCalendar->week+1;
if(day>_guiCalendar_GetDaysofMonth(pCalendar->year,pCalendar->month))
return -1;
return day;
}
// 反显日历中的当前日期
void _guiCalendar_Invert(HNDL handle)
{
TGuiCalendar *pCalendar;
int pos,posNum;
short dayWidth,dayHeight,dayHGap,dayVGap;
short x,y;
pCalendar=(TGuiCalendar *)handle;
dayWidth=pCalendar->dayWidth;
dayHeight=pCalendar->dayHeight;
dayHGap=pCalendar->dayHGap;
dayVGap=pCalendar->dayVGap;
pos=pCalendar->day+pCalendar->week-1;
if(pCalendar->base.style & CALENDAR_LINE6)
posNum=42;
else
posNum=35;
if(pos>=posNum)
pos-=posNum;
x=(pos%7)*(dayWidth+dayHGap);
y=(pos/7)*(dayHeight+dayVGap);
guiInvertRect(handle,x,y,x+dayWidth-1,y+dayHeight-1);
}
// 日历控件对笔点消息的响应
void _guiCalendar_Action(HNDL handle, WORD message,WORD x,WORD y)
{
TGuiCalendar *pCalendar;
int day;
pCalendar=(TGuiCalendar *)handle;
if(pCalendar->base.checkFlag != GUI_CONTROL_CHECK_FLAG )
return; // 控件无效
if( pCalendar->base.status & CONTROL_NOT_ACTIVE )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -