备忘录实验报告.docx
- 文档编号:26012909
- 上传时间:2023-06-17
- 格式:DOCX
- 页数:17
- 大小:344.83KB
备忘录实验报告.docx
《备忘录实验报告.docx》由会员分享,可在线阅读,更多相关《备忘录实验报告.docx(17页珍藏版)》请在冰豆网上搜索。
备忘录实验报告
实验三.备忘录
实验要求:
用VC++实现备忘录小程序,能够设定事件通知信息,并按照设定的时间进行事件通知,具体要求如下:
1.界面友好,美观大方;
2.支持事件的录入,包括时间、事件、备注信息等;
3.支持在设定的时间进行事件提醒;
4.支持对已录入事件大的查看、修改和删除;
5.其他更多功能,可根据情况自行添加。
题目分析:
由题意可知,建立备忘录小程序需要操作的对象是“事件”和“事件列表”。
因此,我们建立了事件类(classEvent)和事件链表类(classEventList)。
以下是对类的具体分析:
事件类的成员变量中应当包含以下信息:
◆内容(content)
◆标识符用以唯一标识(id)
◆是否设置提醒(reminder)
◆事件提醒时间(time)
◆标题(title)
对应成员变量的成员函数有:
Event():
构造一个空事件
getContent():
获得事件内容
getOleTime():
获得COleDateTime对象的时间
getReminder():
获得是否提醒
getTime():
获得字符串格式时间
getTitle():
获得标题
setContent(..),setID(..),setReminder(..),setTime(..),setTitle(..)分别设置内容,ID,提醒,时间,和标题。
创建一个事件的具体过程:
1.声明一个事件Event对象,调用默认构造函数。
2.根据用户输入调用相应的set函数给事件成员变量赋值。
需要注意的是:
content,id,tiltle都是CString类对象,而time是COleDateTime对象。
3.调用setIDAuto()函数,给该事件自动加上ID,ID对应着当前时间点。
以下是setIDAuto的具体实现代码:
voidsetIDAuto()
{
COleDateTimecur_time;
cur_time.GetCurrentTime();
intday=cur_time.GetDay();
intmonth=cur_time.GetMonth();
intyear=cur_time.GetYear();
intminute=cur_time.GetMinute();
inthour=cur_time.GetHour();
intsecond=cur_time.GetSecond();
//根据当前时间设定ID
id.Format(_T("%.4d-%.2d-%.2d%.2d:
%.2d:
%.2d"),year,month,day,hour,minute,second);
}
下面是对事件链表类EventList的分析:
首先引入STL中的vector类,为事件构造一个向量(动态数组)。
语句为:
std:
:
vector
而该类的所有操作都是围绕着这个事件向量进行的。
以下是对成员变量的解说:
Eventleft_event:
标记即将发生事件,在后面的【事件提醒】有详细介绍。
intsize:
记录当前的事件数量
成员函数:
addEvent:
添加事件
check():
检查left_event是否到达提醒时间
deleteEvent:
从id或下标删除事件
GetEvent:
从下标获取事件
getLeftEvent:
设置left_event,并返回它
getSize:
或取当前事件数
Read:
从传入路径读取文件,获取已保存事件数据
Save:
从传入路径写入文件
以下是添加一个事件的流程:
1.创建事件
2.调用EventList的成员函数addEvent添加事件
程序共含两个窗体:
即主窗体和事件添加编辑窗体。
以下是窗体截图:
两个窗体分别为两个类,其中主窗体类名为CbeiwangluDlg,包含以下私有成员。
Cur_event:
一个事件对象,新建和编辑对象时用的临时变量
event_list:
事件链表,伴随着窗体的生命周期
left_event:
保存即将发生的事件
事件添加编辑窗体类为CNewEventDlg,类关系图为:
以下是对该类的成员变量进行说明:
Event*cur_event:
保存一个事件指针,而该类的所有操作均是对该指针所指向的对象进行操作
BoolifEdit:
判断是否为编辑窗口,默认是添加事件窗口
EventContext:
事件内容,和一个EditBox绑定
EventID:
事件ID,自动设置
EventReminder:
事件是否提醒,和一个CheckBox绑定
EventTitle:
事件标题,与一个EditBox绑定
SelectedTime:
和一个CDateTimeCtrl控件绑定,用以获得选择的年月日
Time_of_hms:
和一个CDateTimeCtrl控件绑定,用以获得具体的时分秒
SetEvent:
根据EventID,EventReminder,EventTitle,SelectedTime为cur_event所指向的事件赋值。
1.文件读写
1.程序运行,创建事件链表,然后调用EventList的Read函数从文件中读入事件列表。
在了争读取文件时,我们不妨先看一看保存的格式,即Save函数的实现,以下是Save函数的实现代码:
(相关注释已在代码间表明)
CStringSave(constCString&path)
{
CStdioFilef;
CFileExceptione;
if(!
f.Open(path,CFile:
:
modeWrite|CFile:
:
modeCreate|CFile:
:
typeText|CFile:
:
typeBinary,&e))
{
return_T("Filecouldnotbeopened\n");
}
std:
:
vector
:
iteratorit=event_vector.begin();
CStringtemp;
while(it!
=event_vector.end())//无限循环,直至迭代器走到向量尾端
{
f.WriteString(it->getTime());//写入时间
f.WriteString(_T("\n"));//换行
f.WriteString(it->getTitle());//写入标题
f.WriteString(_T("\n"));//换行
if(it->getReminder()==TRUE)
{
f.WriteString(_T("TRUE"));//写入是否提醒
}
else
{
f.WriteString(_T("FALSE"));//写入是否提醒
}
f.WriteString(_T("\n"));//换行
f.WriteString(it->getContent());//写入事件内容
f.WriteString(_T("\n\r"));//换行
f.WriteString(it->getID());//写入ID
f.WriteString(_T("\n"));//换行
it++;//迭代器向前进一
}
return_T("OK");
}
Save的实现方式是将每个事件都有次序地保存进一个文本文件里,这样有条不紊的写入文件确保了文件读入时稳定性。
以下是Read函数是具体实现代码:
CStringRead(constCString&path)
{
CStdioFilef;
CFileExceptione;
if(!
f.Open(path,CFile:
:
modeRead|CFile:
:
typeBinary,&e))
{
return_T("Filecouldnotbeopened\n");
}
CStringstr,temp_str;
Eventcur_event;
COleDateTimeevent_time;
CStringstrii;
intcount=1;
while(f.ReadString(str))
{
if(str=="\n"||str=="\r")
{
continue;
}
switch(count)
{
case1:
//第一行,读入时间
intyear,month,day,hour,minute,second;
temp_str=str.Mid(0,4);
year=_wtoi(temp_str);
temp_str=str.Mid(5,2);
month=_wtoi(temp_str);
temp_str=str.Mid(8,2);
day=_wtoi(temp_str);
temp_str=str.Mid(11,2);
hour=_wtoi(temp_str);
temp_str=str.Mid(14,2);
minute=_wtoi(temp_str);
temp_str=str.Mid(17,2);
second=_wtoi(temp_str);
event_time.SetDateTime(year,month,day,hour,minute,second);
cur_event.setTime(event_time);
break;
case2:
//第二行,读入标题
cur_event.setTitle(str);
break;
case3:
//第三行,读入是否提醒
if(str==_T("TRUE"))
{
cur_event.setReminder(TRUE);
}
else
{
cur_event.setReminder(FALSE);
}
break;
case4:
//读入事件内容
cur_event.setContent(str);
break;
case5:
//读入ID
cur_event.setID(str);
break;
}
if(count==5)//若count==5,表示一个事件已经读入完成,则使count变回,并向列表中添加
{
count=1;
this->addEvent(cur_event);
}
else
{
count++;//否则使count自增
}
}
return_T("OK");
}
Read操作即为Save的逆向操作,根据Save的保存次序依次读入各个事件,将原字符串格式的信息转化为需要的类型添加进事件中,最后依次添加每一个事件进入事件链表中。
2.事件添加
事件的添加,即为当单击新建事件按钮时调出添加事件对话框。
但我们需要在主对话框和添加事件对话框建立信息桥梁,因此我们让添加事件对话框的成员变量*cur_event指向主窗口的成员变量cur_event,具体实现代码如下:
Eventcur_event;
CNewEventDlgdlg;
dlg.setEvent(&cur_event);//设置指针指向cur_event
intdd=dlg.DoModal();//对话框弹出
if(cur_event.getTitle()!
=_T(""))//如果标题未设置则认为未确认添加
{
event_list.addEvent(cur_event);
RefreshList();//刷新显示列表
}
以下是添加事件对话框的具体实现代码,如OnBnClickedOk函数上进行响应:
voidCNewEventDlg:
:
OnBnClickedOk()
{
//TODO:
在此添加控件通知处理程序代码
UpdateData(TRUE);//获得各变量的值
intyear=SelectedTime.GetYear();
intmonth=SelectedTime.GetMonth();
intday=SelectedTime.GetDay();
inthour=time_of_hms.GetHour();
intminute=time_of_hms.GetMinute();
intsecond=time_of_hms.GetSecond();
SelectedTime.SetDateTime(year,month,day,hour,minute,second);
//为事件的各成员变量赋值
cur_event->setTime(this->SelectedTime);
cur_event->setTitle(this->EventTitle);
cur_event->setReminder(this->EventReminder);
cur_event->setContent(this->EventContext);
COleDateTimecur_time=COleDateTime:
:
GetCurrentTime();
cur_event->setID(cur_time);
OnOK();
}
至此,便完成了对事件的添加。
3.事件删除
事件删除的具体实现是:
1.获得选中事件
2.通过获得下标对事件进行删除
具体实现代码为:
voidCbeiwangluDlg:
:
OnBnClickedButton3()
{
//TODO:
在此添加控件通知处理程序代码
CStringstr;
POSITIONpos=m_list.GetFirstSelectedItemPosition();
if(pos==NULL)
TRACE0("Noitemswereselected!
\n");
else
{
while(pos)
{
intnItem=m_list.GetNextSelectedItem(pos);
Eventcur_event=event_list.GetEvent(nItem);
event_list.deleteEvent(nItem);
RefreshList();
MessageBox(_T("删除成功!
"));
}
}
}
4.事件编辑
对事件进行编辑,需要得到当前列表的选中项,并要调出事件编辑窗口。
以下是主窗口对事件编辑的代码:
CStringstr;
POSITIONpos=m_list.GetFirstSelectedItemPosition();
if(pos==NULL)
TRACE0("Noitemswereselected!
\n");
else
{
while(pos)
{
intnItem=m_list.GetNextSelectedItem(pos);//将pos转化为下标
Eventcur_event=event_list.GetEvent(nItem);//由下标获得事件,并赋值给临时事件
event_list.deleteEvent(nItem);//删除事件
//等同于添加事件
CNewEventDlgdlg;
dlg.setEvent(&cur_event);
dlg.setIfEdit(true);
intdd=dlg.DoModal();
event_list.addEvent(cur_event);
RefreshList();
}
}
编辑事件的流程是:
1.获取要编辑事件,并将其赋值给临时变量cur_event
2.删除该事件
3.调用事件添加模块,但使事件添加窗口在窗口创建时加载cur_event的各项参数。
4.不论用户确定还是取消编辑,均无条件添加cur_event进入事件链表中
5.刷新显示列表
5.事件提醒
事件的提醒处理思想如下:
1.设置一个Timer,每1秒响应一次
因此,我们在主窗口的OnInitDlg函数里添加了下面这一句代码:
SetTimer(32,1000,NULL);
2.设置Timer响应函数,为了使窗口跳到最前,并弹出对话框,因此我们在OnTimer函数中写了如下代码:
voidCbeiwangluDlg:
:
OnTimer(UINT_PTRnIDEvent)
{
//TODO:
在此添加消息处理程序代码和/或调用默认值
COleDateTimecur_time=COleDateTime:
:
GetCurrentTime();
if(nIDEvent==32)
{
if(event_list.check()==true)//当检查返回true时,执行提醒
{
//使窗口跳到最前,并弹出对话框
ShowWindow(SW_SHOW);
SetWindowPos(&wndTopMost,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE);
SetWindowPos(&wndNoTopMost,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE);
SetForegroundWindow();
HWNDhCurWnd=NULL;
DWORDlMyID;
DWORDlCurID;
hCurWnd=:
:
GetForegroundWindow();
lMyID=:
:
GetCurrentThreadId();
lCurID=:
:
GetWindowThreadProcessId(hCurWnd,NULL);
:
:
AttachThreadInput(lMyID,lCurID,TRUE);
SetForegroundWindow();
:
:
AttachThreadInput(lMyID,lCurID,FALSE);
MessageBox(left_event.getTitle());
}
}
CDialog:
:
OnTimer(nIDEvent);
}
3.以下是event_list.check()的具体实现代码:
boolcheck()
{
COleDateTimecur_time=COleDateTime:
:
GetCurrentTime();
//判断年月日是否与当前时间吻合
if(left_event.getOleTime().GetYear()==cur_time.GetYear()&&
left_event.getOleTime().GetMonth()==cur_time.GetMonth()&&
left_event.getOleTime().GetDay()==cur_time.GetDay())
{
//获得当前时间与即将发生事件的时间跨度
COleDateTimeSpanspan=left_event.getOleTime()-cur_time;
//如果时间跨度小于秒,则判定为时间已到
if(left_event.isOk==false&&span.GetTotalSeconds()<=2)
{
//将事件设定为已提醒
left_event.isOk=true;
getLeftEvent();//获得即将发生的事件
returntrue;
}
}
returnfalse;
}
实验结果截图:
(注:
可编辑下载,若有不当之处,请指正,谢谢!
)
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 备忘录 实验 报告