2024年1月3日发(作者:)
实验三.备忘录
实验要求:
用VC++实现备忘录小程序,能够设定事件通知信息,并按照设定的时间进行事件通知,具体要求如下:
1.界面友好,美观大方;
2.支持事件的录入,包括时间、事件、备注信息等;
3.支持在设定的时间进行事件提醒;
4.支持对已录入事件大的查看、修改和删除;
5. 其他更多功能,可根据情况自行添加。
题目分析:由题意可知,建立备忘录小程序需要操作的对象是“事件”和“事件列表”。因此,我们建立了事件类(class Event)和事件链表类(class EventList)。以下是对类的具体分析:
事件类的成员变量中应当包含以下信息:
◆内容(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的具体实现代码:
void setIDAuto()
{
COleDateTime cur_time;
cur_rentTime();
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;/////;/;;//////////;//////=[-[-[-[--[-[[-[-[-[-[--[-[7uyujjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
}
int minute = cur_ute();
int hour = cur_r();
int second = cur_ond();
(_T("%.4d-%.2d-%.2d %.2d:%.2d:%.2d"),year,month,day,hour,minute,second);
int day =cur_();
int month = cur_th();
int year = cur_r();
//根据当前时间设定ID
下面是对事件链表类EventList的分析:
首先引入STL中的vector类,为事件构造一个向量(动态数组)。语句为:
std::vector
而该类的所有操作都是围绕着这个事件向量进行的。
以下是对成员变量的解说:
Event left_event:标记即将发生事件,在后面的【事件提醒】有详细介绍。
int size:记录当前的事件数量
成员函数:
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:保存一个事件指针,而该类的所有操作均是对该指针所指向的对象进行操作
Bool ifEdit:判断是否为编辑窗口,默认是添加事件窗口
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函数的实现代码:(相关注释已在代码间表明)
}
return _T("OK");
std::vector
CString temp;
while (it!=event_())//无限循环,直至迭代器走到向量尾端
{
}
tring(it->getTime());//写入时间
tring(_T("n"));//换行
tring(it->getTitle());//写入标题
tring(_T("n"));//换行
if (it->getReminder() == TRUE)
{
}
else
{
}
tring(_T("n"));//换行
tring(it->getContent());//写入事件内容
tring(_T("nr"));//换行
tring(it->getID());//写入ID
tring(_T("n"));//换行
it++;//迭代器向前进一
tring(_T("FALSE"));//写入是否提醒
tring(_T("TRUE"));//写入是否提醒
if(!(path,
{
}
return _T("File could not be opened n");
CFile::modeWrite|CFile::modeCreate|CFile::typeText|CFile::typeBinary, &e))
CString Save(const CString& path)
{
CStdioFile f;
CFileException e;
Save的实现方式是将每个事件都有次序地保存进一个文本文件里,这样有条不紊的写入文件确保了文件读入时稳定性。
以下是Read函数是具体实现代码:
CString Read(const CString& path)
temp_str = (14,2);
minute = _wtoi(temp_str);
temp_str = (8,2);
day = _wtoi(temp_str);
temp_str = (11,2);
hour = _wtoi(temp_str);
temp_str = (5,2);
month = _wtoi(temp_str);
temp_str = (0,4);
year = _wtoi(temp_str);
CString str,temp_str;
Event cur_event;
COleDateTime event_time;
CString strii;
int count = 1;
while (ring(str))
{
if (str == "n" || str == "r")
{
}
switch (count)
{
case 1://第一行,读入时间
int year,month,day,hour,minute,second;
continue;
if(!(path, CFile::modeRead|CFile::typeBinary, &e))
{
}
return _T("File could not be opened n");
{
CStdioFile f;
CFileException e;
}
}
}
temp_str = (17,2);
second = _wtoi(temp_str);
event_eTime(year,month,day,hour,minute,second);
cur_e(event_time);
break;
cur_le(str);
break;
if (str == _T("TRUE"))
{
}
else
{
}
break;
cur_tent(str);
break;
cur_(str);
break;
cur_inder(FALSE);
cur_inder(TRUE);
case 2://第二行,读入标题
case 3://第三行,读入是否提醒
case 4://读入事件内容
case 5://读入ID
if (count == 5)//若count==5,表示一个事件已经读入完成,则使count变回,并向{
}
else
{
}
count++;//否则使count自增
count =1;
this->addEvent(cur_event);
列表中添加
return _T("OK");
Read操作即为Save的逆向操作,根据Save的保存次序依次读入各个事件,将原字符串
格式的信息转化为需要的类型添加进事件中,最后依次添加每一个事件进入事件链表中。
2. 事件添加
事件的添加,即为当单击新建事件按钮时调出添加事件对话框。但我们需要在主对话框和添加事件对话框建立信息桥梁,因此我们让添加事件对话框的成员变量*cur_event指向主窗口的成员变量cur_event,具体实现代码如下:
if (cur_le() != _T(""))//如果标题未设置则认为未确认添加
{
}
event_nt(cur_event);
RefreshList();//刷新显示列表
Event cur_event;
CNewEventDlg dlg;
nt(&cur_event);//设置指针指向cur_event
int dd=l();//对话框弹出
以下是添加事件对话框的具体实现代码,如OnBnClickedOk函数上进行响应:
void CNewEventDlg::OnBnClickedOk()
{
}
// TODO: 在此添加控件通知处理程序代码
UpdateData(TRUE); // 获得各变量的值
int year = r();
int month = th();
int day = ();
int hour = time_of_r();
int minute = time_of_ute();
int second = time_of_ond();
eTime(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);
COleDateTime cur_time = COleDateTime::GetCurrentTime();
cur_event->setID(cur_time);
OnOK();
至此,便完成了对事件的添加。
3. 事件删除
事件删除的具体实现是:
1. 获得选中事件
2. 通过获得下标对事件进行删除
具体实现代码为:
void CbeiwangluDlg::OnBnClickedButton3()
{
}
}
}
Event cur_event = event_nt(nItem);
event_Event(nItem);
RefreshList();
MessageBox(_T("删除成功!"));
{
while (pos)
{
int nItem = m_tSelectedItem(pos);
TRACE0("No items were selected!n");
else
if (pos == NULL)
POSITION pos = m_stSelectedItemPosition();
// TODO: 在此添加控件通知处理程序代码
CString str;
4.事件编辑
对事件进行编辑,需要得到当前列表的选中项,并要调出事件编辑窗口。
以下是主窗口对事件编辑的代码:
TRACE0("No items were selected!n");
if (pos == NULL)
POSITION pos = m_stSelectedItemPosition();
CString str;
else
{
}
while (pos)
{
}
int nItem = m_tSelectedItem(pos);//将pos转化为下标
Event cur_event = event_nt(nItem);//由下标获得事件,并赋值给临时event_Event(nItem);//删除事件
//等同于添加事件
CNewEventDlg dlg;
nt(&cur_event);
dit(true);
int dd=l();
event_nt(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函数中写了如下代码:
void CbeiwangluDlg::OnTimer(UINT_PTR nIDEvent)
{
if (nIDEvent == 32)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
COleDateTime cur_time = COleDateTime::GetCurrentTime();
}
}
if (event_() == 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();
HWND hCurWnd =NULL;
DWORD lMyID;
DWORD lCurID;
hCurWnd = :: GetForegroundWindow();
lMyID = ::GetCurrentThreadId();
lCurID = ::GetWindowThreadProcessId(hCurWnd,NULL);
::AttachThreadInput(lMyID,lCurID,TRUE);
SetForegroundWindow();
::AttachThreadInput(lMyID,lCurID,FALSE);
MessageBox(left_le());
CDialog::OnTimer(nIDEvent);
3. 以下是event_()的具体实现代码:
bool check()
{
COleDateTime cur_time = COleDateTime::GetCurrentTime();
//判断年月日是否与当前时间吻合
if (left_Time().GetYear() == cur_r() &&
{
}
return false;
//获得当前时间与即将发生事件的时间跨度
COleDateTimeSpan span = left_Time() - cur_time;
//如果时间跨度小于秒,则判定为时间已到
if (left_ == false && alSeconds()<=2)
{
}
//将事件设定为已提醒
left_ = true;
getLeftEvent();//获得即将发生的事件
return true;
left_Time().GetMonth() == cur_th()&&
left_Time().GetDay() == cur_())
}
实验结果截图:


发布评论