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_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::iterator it = event_();

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_())

}

实验结果截图: