VB日历课程设计报告.docx
- 文档编号:22898861
- 上传时间:2023-04-28
- 格式:DOCX
- 页数:39
- 大小:25.96KB
VB日历课程设计报告.docx
《VB日历课程设计报告.docx》由会员分享,可在线阅读,更多相关《VB日历课程设计报告.docx(39页珍藏版)》请在冰豆网上搜索。
VB日历课程设计报告
课程设计题目电子台历
所选题目:
电子台历
难度:
两星级**
知识点:
(1)非矩形窗口;
(2)动态数组;(3)配置文件的读写;(4)图片的应用;(5)控件数组;(6)弹出式菜单的使用;(7)公共对话框控件;(8)多模块程序设计;(9)日期函数的使用
前言
“台历”是人们办公、学习的好帮手,人们把它置于案头用来查看日期、星期并可以方便地记事。
本题目便编制一个“电子台历”程序,实现台历的一般功能。
一、功能
1、启动程序,显示一个圆角矩形窗口,并自动显示当前月的月历。
星期从星期一开始排列,星期六和星期天以不同的颜色显示。
2、鼠标单击可以查看不同的年份和月份(左键增大,右键减小)。
单击某个日期会在窗口右半边显示是否有记事。
双击左下角的当前日期,可以使台历立即显示当月月历。
3、在窗体的空白处右击,可以弹出一个菜单,可以对显示的日历日期的颜色、字体,窗体的背影图片加以修改。
所有颜色、字体和背影图片的设置会自动保存,下次启动时会自动应用上一次的设置。
4、从快捷菜单中选择“添加节日”或“添加记事”,可以分别实现对节日和记事的添加。
在弹出的对话框中,能同时添加多个节日或记事。
二、课程设计的详细设计
1、程序的界面要求是圆角矩形窗口,该功能的实现用到了SetWindowRgn函数。
SetWindowRgn函数是属于API函数,在使用时要先声明。
其代码如下:
PrivateDeclareFunctionCreateRoundRectRgnLib"gdi32"(ByValX1AsLong,_
ByValY1AsLong,ByValX2AsLong,ByValY2AsLong,_
ByValX3AsLong,ByValY3AsLong)AsLong
PrivateDeclareFunctionSetWindowRgnLib"user32"(ByValhWndAsLong,_
ByValhRgnAsLong,ByValbRedrawAsBoolean)AsLong
hRgn=CreateRoundRectRgn(0,0,570,400,80,100)'创建圆角矩形区域
CallSetWindowRgn(Me.hWnd,hRgn,True)
2、年份、月份、日期和记事的显示依靠标签的Caption属性。
其中,星期和日期的显示使用了控件数组,星期的显示使用了14个控件,日期的显示使用了74个控件。
又把各个标签的背影设为透明,这样,便实现了日历界面的显示。
3、为了使文字有浮于图片之上的立体感,使用了内容相同但颜色伸浅不同且位置错开一点的两个控件来实现。
功能的实现依靠以下代码:
PublicSubGetCaption()'产生标签的文字,达到字体有悬浮的效果
DimjAsInteger
lblYear1.Caption=lblYear.Caption
lblYear1.FontName=lblYear.FontName
lblMonth1.Caption=lblMonth.Caption
lblMonth1.FontName=lblMonth.FontName
lblNow1.Caption=lblNow.Caption
lblNow1.FontName=lblNow.FontName
Forj=37To73
lblDay(j).Caption=lblDay(73-j).Caption
Next
lblShowNote1.Caption=lblShowNote.Caption
lblShowNote1.FontName=lblShowNote.FontName
Forj=0To6
lblWeek(13-j).FontName=lblWeek(j).FontName
Next
EndSub
4、本程序的主窗口使用了漂亮的图片作背影,样例共提供了4个.bmp格式的图片的加载使用以下代码来实现:
PrivateSubPic1_Click()'日历背影图象变化
frmCalMain.Picture=Nothing
frmCalMain.Picture=LoadPicture(App.Path&"\pics\p1.bmp")
frmMenu.Pic1.Checked=True
frmMenu.Pic2.Checked=False
frmMenu.Pic3.Checked=False
frmMenu.Pic4.Checked=False
strPicName="p1"
EndSub
PrivateSubPic2_Click()
frmCalMain.Picture=Nothing
frmCalMain.Picture=LoadPicture(App.Path&"\pics\p2.bmp")
frmMenu.Pic2.Checked=True
frmMenu.Pic1.Checked=False
frmMenu.Pic3.Checked=False
frmMenu.Pic4.Checked=False
strPicName="p2"
EndSub
PrivateSubPic3_Click()
frmCalMain.Picture=Nothing
frmCalMain.Picture=LoadPicture(App.Path&"\pics\p3.bmp")
frmMenu.Pic3.Checked=True
frmMenu.Pic1.Checked=False
frmMenu.Pic2.Checked=False
frmMenu.Pic4.Checked=False
strPicName="p3"
EndSub
PrivateSubPic4_Click()
frmCalMain.Picture=Nothing
frmCalMain.Picture=LoadPicture(App.Path&"\pics\p4.bmp")
frmMenu.Pic4.Checked=True
frmMenu.Pic1.Checked=False
frmMenu.Pic2.Checked=False
frmMenu.Pic3.Checked=False
strPicName="p4"
EndSub
5、启动程序和左下角的当前日期要求显示当前月历,该功能的实现应用了两个过程和一个函数来实现:
PrivateSubDisplayNow()'该过程显示当前日期
DimdtmNowAsDate
dtmNow=Date
lblYear.Caption=Format(dtmNow,"yyyy年")
lblMonth.Caption=Format(dtmNow,"M月")
lblNow.Caption=Format(dtmNow,"今天是:
dddddd")
strNow=Format(dtmNow,"dddddd")'用于存储当前年、月、日字符串
intYear=Val(Format(dtmNow,"yyyy"))'用三个变量存储当前年、月、日
intMonth=Val(Format(dtmNow,"M"))
intDay=Val(Format(dtmNow,"d"))
dtmOne=DateAdd("d",(1-intDay),dtmNow)'当前月的第一天
intNum=Days(intYear,intMonth)
CallSort(dtmOne,intNum)'调用过程生成每月的各个日期
'使当前日期颜色正确显示
IffrmCalMain.lblYear.Caption&frmCalMain.lblMonth.Caption&_
frmCalMain.lblDay(intNowDayIndex).Caption&"日"=strNowThen
frmCalMain.lblDay(intNowDayIndex).ForeColor=frmCalMain.lblNow.ForeColor
EndIf
EndSub
PrivateSubSort(dtm1AsDate,int1AsInteger)'该过程生成每月的各个日期
DimintweekAsInteger,iAsInteger,jAsInteger
DimhAsInteger
Forh=0To36'各个日期标签标题清空
lblDay(h).Caption=""
Nexth
intweek=Val(Format(dtm1,"w"))'计算每月的第一天为星期几
Ifintweek-1>0Then
i=intweek-2
Else
i=6
EndIf
j=0
DoWhilej lblDay(i).Caption=j+1 lblDay(i).MousePointer=99 '使指针变成手的图形 lblDay(i).MouseIcon=LoadPicture(App.Path&"\Resource\hand.cur") j=j+1 i=i+1 Loop Forj=0To36 IflblDay(j).Caption=""Then lblDay(j).MousePointer=99 '使指针边成移动的图形 lblDay(j).MouseIcon=LoadPicture(App.Path&"\Resource\move.cur")EndIf Next EndSub PrivateFunctionDays(intYAsInteger,intMAsInteger)'该函数计算每月天数 DimkAsInteger SelectCaseintM Case1,3,5,7,8,10,12 k=31 Case2 IfintYMod4=0Then k=29 Else k=28 EndIf CaseElse k=30 EndSelect Days=k EndFunction 6、本程序使用了配置文件格式来保存关于颜色、字体和图片的设置以及节日和记事内容。 配置文件是一种特殊的文本文件,一般以.ini为扩展名,它可以使用记事本打开。 因为配置文件的特殊格式,Windows提供了专门的API函数来对起进行读写。 该功能的实现用到了以下语句: PrivateDeclareFunctionWritePrivateProfileStringLib"kernel32"Alias_ "WritePrivateProfileStringA"(ByVallpApplicationNameAsString,_ ByVallpKeyNameAsAny,ByVallpStringAsAny,ByVallpFileNameAsString)AsLong PrivateDeclareFunctionGetPrivateProfileStringLib"kernel32"Alias_ "GetPrivateProfileStringA"(ByVallpApplicationNameAsString,_ ByVallpKeyNameAsAny,ByVallpDefaultAsString,ByVal_ lpReturnedStringAsString,ByValnSizeAsLong,ByVallpFileNameAsString)AsLong DimsAsString*100 '获得星期一至星期五的颜色参量 CallWritePrivateProfileString("SetColor","颜色1,strColor1App.Path&"\cal.set") CallGetPrivateProfileString("SetColor","颜色1,"0",s,100,App.Path&"\cal.set") '获得星期的字体参量 DimsAsString*100,strFont1AsString CallWritePrivateProfileString("SetFont","字体1,strFont2,App.Path&"\cal.set") CallGetPrivateProfileString("SetFont","字体1,"0",s,100,App.Path&"\cal.set") 7、以上的六个过程不是很难,对我来说花是时间最长的是节日和记事的读出。 因为节日和记事在记事本中的保存位置不同,一个在节名为Festival中,一个在节名为Note中,而它们要在同一个标签中显示,而且以序号排列。 我用了很长时间进行调试来实现了该要求。 其代码如下: PrivateSublblDay_Click(IndexAsInteger) DimstrCaptionAsString,s1AsString,strFestAsString Dims2AsString*100,strNoteAsString,strFest1AsString DimstrMidAsString,strDate1AsString,strFest2AsString DimstrDate2AsString,strNoteAndDateAsString,strFestAndDateAsString DimiAsInteger,jAsInteger,kAsInteger 'strDate1保存被选择的日期 strDate1=Left(lblYear.Caption,4)&"-"&Left(lblMonth.Caption,_ InStr(lblMonth.Caption,"月")-1)&"-"&lblDay(Index).Caption strMid=strDate1+Chr(32)+Chr(32)+Chr(32)+Chr(32)+Chr(32)+_ Chr(32)+Chr(32)+Chr(32)+Chr(32)+Chr(32)+Chr(32)+Chr(32)+Chr(32) lblShowNote.Caption=""'显示记事标签标题清空 strCaption=lblDay(Index).Caption IfstrCaption=""ThenExitSub strFest1=Left(lblMonth.Caption,_ InStr(lblMonth.Caption,"月")-1)&"-"&lblDay(Index).Caption Do'此循环用于显示被选择的日期有无记事 i=i+1 s1="节日"&i s2="" CallGetPrivateProfileString("Festival",s1,"0",s2,100,App.Path&"\cal.set") IfTrim(Left(s2,InStr(s2,Chr(0))-1))="0"ThenExitDo strFestAndDate=Trim(Left(s2,InStr(s2,Chr(0))-1)) strFest2=Left(strFestAndDate,InStr(strFestAndDate,": ")-1)'strFest2保存记事本中已有的日期 strFest=Right(strFestAndDate,Len(strFestAndDate)-InStr(strFestAndDate,": "))'strFest保存记事本中存储的记事 IfstrFest2=strFest1Then'若条件成立,则被选择的日期有记事 k=k+1 strMid=strMid+Chr(13)+Chr(10)+CStr(k)+": "+strFest lblShowNote.Caption=strMid strFest2="" EndIf Loop i=0 IflblShowNote.Caption=""Then '此循环用于显示被选择的日期有无记事 DoWhilestrDate2<>strDate1 i=i+1 s1="记事"&i s2="" CallGetPrivateProfileString("Note",s1,"0",s2,100,App.Path&"\cal.set") IfTrim(Left(s2,InStr(s2,Chr(0))-1))="0"Then lblShowNote.Caption=strMid+"无记事" ExitDo EndIf strNoteAndDate=Trim(Left(s2,InStr(s2,Chr(0))-1)) strDate2=Left(strNoteAndDate,InStr(strNoteAndDate,": ")-1)'strDate2保存记事本中已有的日期 strNote=Right(strNoteAndDate,Len(strNoteAndDate)-InStr(strNoteAndDate,": "))'strNote保存记事本中存储的记事 Loop EndIf i=0: j=k Do'此循环用于显示被选择的日期有无记事 i=i+1 s1="记事"&i s2="" CallGetPrivateProfileString("Note",s1,"0",s2,100,App.Path&"\cal.set") IfTrim(Left(s2,InStr(s2,Chr(0))-1))="0"ThenExitDo strNoteAndDate=Trim(Left(s2,InStr(s2,Chr(0))-1)) strDate2=Left(strNoteAndDate,InStr(strNoteAndDate,": ")-1)'strDate2保存记事本中已有的日期 strNote=Right(strNoteAndDate,Len(strNoteAndDate)-InStr(strNoteAndDate,": "))'strNote保存记事本中存储的记事 IfstrDate2=strDate1Then'若条件成立,则被选择的日期有记事 j=j+1 strMid=strMid+Chr(13)+Chr(10)+CStr(j)+": "+strNote lblShowNote.Caption=strMid strDate2="" EndIf Loop GetCaption EndSub 自己认为上述代码还不够简洁,还可以进行修改和简化,由于时间仓促,来不及再进行修改。 三、调试程序的过程 1、在显示当前月的日期时,曾一度发生错误,不容易找到实现该过程的方法。 曾经想过运用当前日期所在的标签的Index号然后进行加或减生成各个日期,可是这样调试了好久,不但代码很多,而且该过程不容易实现。 最后自己终于找到了一种简便的算法: 先运用Format函数得到当前日期,然后生成当前月的第一天,接着计算该天所在标签,得到标签的Index号,最后计算输出当前月的各个日期。 这样,整个过程很简洁快速的实现了。 2、在生成矩形窗口时,自己遇到了问题: 一个窗口一旦有了菜单,运用SetWindowRgn函数便不好实现对其的剪切,其最后效果因为存在着标题栏(最上部存在一个绿色的长条)而变的难看,不符合要求。 自己调试了好久依然不成功。 最后自己又增加了一个窗体frmMenu,在该窗体放置了菜单和公共对话框控件。 这样之后,当右击主窗体frmCalMain时便弹出frmMenu窗体的菜单。 这样,原来可能集中在窗体frmCalMain中的代码便部分转移到了frmMenu窗体中,有利于程序的调试。 3、在编写颜色对话框时不能实现对上一次操作的记忆,自己调试了好久,首先想把在显示当前日期时要求其颜色要保持和lblNow标签的颜色一样,这样增加了设计的难度,因为不知道该日期是星期几,而且,在单击lblYear和lblMonth时要注意颜色的一致性,即月份或年份一旦改变,原来用来显示当前日期的标签的颜色就要可能改变,保持所在星期颜色的一致性。 自己调试了好久,运用一个全局变量intNowDayIndex满足了该要求。 其具体过程可看附件的代码。 4、当然还有许多问题,像运用CommonDialog的ShowFont属性无用(只要把CommonDialog的Flags属性值设为2),节日和记事不能正确保存(设计时ComboBox的List属性值输入时存在大量的空格)等等小问题,这里就不一一说了。 四、输入输出数据 此电子台历几乎没有涉及数据的输入输出,这里也就不在列出。 五、课程设计总结 虽然说此电子台历只有两颗星,但我花的时间并不短,算起来,大约有三个星期,这其中有暑假的一个多星期的时间。 整体说来,自己还是蛮有成就感的,毕竟自己仅仅是刚学了VB一年。 在设计时,许多自己在课堂或考试中没有遇到或接触的东西都是自己看书解决的,这样使得自己感到在VB上的知识又掌握了许多。 正如老师说的,VB课程设计关键是训练学生把所学知识运用到实践当中去,自己在课堂上学到了什么,就真正掌握了什么。 自己本来就梦想要自己编制属于自己的程序,可以说,自己的梦想已经实现,自己确实感到很高兴。 六、附件 电子台历源代码: frmCalMain窗体: OptionExplicit OptionBase1 PrivatedtmOneAsDate,lngMidColorAsLong,strNowAsString,LocalMousePlaceXAsSingle PrivatestrSatColorAsString,strSun
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- VB 日历 课程设计 报告