📄 familytreedlg.cpp
字号:
void CFamilytreeDlg::DisplayGenerationInfo(Person& pNode,bool& flag,int count,int generation)
{
if(!pNode)
return;
if(count==generation){
flag=true;
DisplayInListCtrl(pNode);
DisplayGenerationInfo(pNode->sibling,flag,count,generation);
return;
}
DisplayGenerationInfo(pNode->child,flag,count+1,generation);
DisplayGenerationInfo(pNode->sibling,flag,count,generation);
}
void CFamilytreeDlg::OnAdd()
{
// TODO: Add your command handler code here
CAddInfoDlg dlg;
HTREEITEM hItem;
hItem=m_peTree.GetSelectedItem();
if(operFamilytree.GetRoot()==0)
dlg.m_parentname="-1";
else
dlg.m_parentname=m_peTree.GetItemText(hItem);
if(dlg.DoModal()==IDCANCEL) //弹出对话框
return;
UpdateData(FALSE);
Person addnode;
addnode=new PersonNode; //新申请一结点
if(addnode==0){
AfxMessageBox("内存不足!");
return;
}
addnode->parent=0;
addnode->child=0;
addnode->sibling=0;
//把有关结点信息加入到结点中去
strcpy(addnode->info.name,dlg.m_name);
strcpy(addnode->info.addr,dlg.m_addr);
addnode->info.birthday.year=dlg.m_birthday_year;
addnode->info.birthday.month=dlg.m_birthday_month;
addnode->info.birthday.day=dlg.m_birthday_day;
addnode->info.marry=dlg.m_marry;
addnode->info.live=dlg.m_live;
//若此人已过世,则还应有死亡日期
if(!dlg.m_live){
addnode->info.deathday.year=dlg.m_deathday_year;
addnode->info.deathday.month=dlg.m_deathday_month;
addnode->info.deathday.day=dlg.m_deathday_day;
}
Person oneself=0;
operFamilytree.Find(operFamilytree.GetRoot(),oneself,addnode->info.name); //查找家谱中有没有此人
if(oneself!=0){
AfxMessageBox("家谱中已有此人!");
delete addnode;
return;
}
Person parent=0;
char parentname[MAX_CHARNUM];
strcpy(parentname,dlg.m_parentname);
if(strcmp(parentname,"-1")==0){ //试图加入一个新的根结点时给出警告
int reply;
reply=::MessageBox(this->m_hWnd,"确实要置此结点为根结点吗?",
"警告",MB_YESNO|MB_ICONWARNING);
if(reply==IDNO)
return;
}
else{ //加入的结点不是根结点
operFamilytree.Find(operFamilytree.GetRoot(),parent,parentname); //在家谱中找addnode的父结点
if(parent==0){
AfxMessageBox("父亲结点没找到!");
delete addnode;
return;
}
}
//日期合法性检查
if(!operFamilytree.IsDateValid(addnode->info.birthday)){
AfxMessageBox("个人信息中的出生日期不合实际!");
delete addnode;
return;
}
//比较孩子结点与其父亲结点的出生日期
if(strcmp(parentname,"-1")!=0){ //加入的结点不是根结点
if(operFamilytree.CompareDate(addnode->info.birthday,parent->info.birthday)<0){
AfxMessageBox("所加入孩子的出生日期比其父亲的出生日期早,不合实际!");
delete addnode;
return;
}
else if(operFamilytree.CompareDate(addnode->info.birthday,parent->info.birthday)==0){
AfxMessageBox("所加入孩子的出生日期与其父亲的出生日期相等,不合实际!");
delete addnode;
return;
}
}
if(!addnode->info.live){ //查看死亡日期的合法性
if(!operFamilytree.IsDateValid(addnode->info.deathday)){
AfxMessageBox("个人信息中的死亡日期不合实际!");
delete addnode;
return;
}
if(operFamilytree.CompareDate(addnode->info.birthday,addnode->info.deathday)>0){
AfxMessageBox("此人出生日期不可能比其死亡日期早!");
delete addnode;
return;
}
}
operFamilytree.Add(parent,addnode); //找到,把addnode加入家谱中
HTREEITEM hParentItem=0,hRootItem;
hRootItem=m_peTree.GetRootItem(); //得到树的根结点
if(strcmp(parentname,"-1")!=0) //加入的结点不是根结点
FindInTree(hRootItem,hParentItem,parentname); //在树中找到要加入结点addnode的父结点parentname
AddToTree(hParentItem,addnode); //把此结点加入到树中
RefreshTree(); //刷新该树
IsFamilytreeModified=true; //置家谱修改标记为真
}
void CFamilytreeDlg::OnDelete()
{
// TODO: Add your command handler code here
if(operFamilytree.GetRoot()==0)
return;
HTREEITEM hItem,hChildItem;
hItem=m_peTree.GetSelectedItem();
hChildItem=m_peTree.GetNextItem(hItem,TVGN_CHILD);
char name[MAX_CHARNUM];
strcpy(name,m_peTree.GetItemText(hItem));
int answer;
if(hChildItem==0)
answer=::MessageBox(this->m_hWnd,"你确实想删除"+CString(name)+"吗?","警告",MB_YESNO|MB_ICONWARNING);
else
answer=::MessageBox(this->m_hWnd,CString(name)+"还有孩子,如果你删除了他,其孩子也一并被删除。你确实想删除此人及其孩子吗?","警告",MB_YESNO|MB_ICONWARNING);
if(answer==IDNO)
return;
Person oneself=0;
operFamilytree.Find(operFamilytree.GetRoot(),oneself,name);
if(oneself)
operFamilytree.Delete(oneself);
m_peTree.DeleteItem(hItem);
RefreshTree();
RefreshList();
IsFamilytreeModified=true; //置家谱修改标记为真
}
void CFamilytreeDlg::OnModify()
{
// TODO: Add your command handler code here
if(operFamilytree.GetRoot()==0)
return;
CModifyInfoDlg dlg;
HTREEITEM hItem;
hItem=m_peTree.GetSelectedItem();
dlg.m_newname=m_peTree.GetItemText(hItem);
Person oneself=0;
char oldname[MAX_CHARNUM];
strcpy(oldname,dlg.m_newname);
operFamilytree.Find(operFamilytree.GetRoot(),oneself,oldname);
if(dlg.DoModal()==IDCANCEL)
return;
UpdateData(FALSE);
Person newValue=new PersonNode;
strcpy(newValue->info.name,dlg.m_newname); //判断家谱中是否已有用户给定的新名字
if(strcmp(newValue->info.name,oldname)==0) //用户不修改姓名
;
else{
Person p=0;
operFamilytree.Find(operFamilytree.GetRoot(),p,newValue->info.name); //查找家谱中有没有此人
if(p!=0){
AfxMessageBox("家谱中已有此人!");
delete newValue;
return;
}
}
strcpy(newValue->info.addr,dlg.m_newaddr);
newValue->info.marry=dlg.m_marry;
newValue->info.live=dlg.m_live;
newValue->info.birthday.day=dlg.m_birthday_day;
newValue->info.birthday.month=dlg.m_birthday_month;
newValue->info.birthday.year=dlg.m_birthday_year;
if(!newValue->info.live){ //如若过世,则应有死亡日期
newValue->info.deathday.day=dlg.m_deathday_day;
newValue->info.deathday.month=dlg.m_deathday_month;
newValue->info.deathday.year=dlg.m_deathday_year;
if(!operFamilytree.IsDateValid(newValue->info.deathday)){
AfxMessageBox("此人信息中死亡日期不合实际!");
delete newValue;
return;
}
if(operFamilytree.CompareDate(newValue->info.deathday,newValue->info.birthday)==-1){
AfxMessageBox("此人死亡日期不可能比其出生日期早!");
return;
}
}
operFamilytree.Modify(oneself,newValue);
RefreshTree();
RefreshList();
IsFamilytreeModified=true; //置家谱修改标记为真
delete newValue;
}
void CFamilytreeDlg::BirthdayTip()
{
CTime curdate;
int curmonth,curday;
curdate=CTime::GetCurrentTime();
curmonth=curdate.GetMonth();
curday=curdate.GetDay();
Person oneself[30];
for(int i=0;i<30;i++)
oneself[i]=0;
Person* start=oneself;
operFamilytree.Find(operFamilytree.GetRoot(),start,curmonth,curday);
if(oneself[0]!=0){
CString allnames("今天为以下家族成员的生日:");
for(i=0;oneself[i]!=0;i++){
allnames+=" ";
allnames+=oneself[i]->info.name;
allnames+=" ";
}
allnames+="\n详细信息请见以下列表.";
::MessageBox(this->m_hWnd,allnames,"注意:",MB_OK|MB_ICONINFORMATION);
RefreshList();
for(i=0;oneself[i]!=0;i++)
DisplayInListCtrl(oneself[i]);
}
}
void CFamilytreeDlg::OnFamilytreeSort()
{
// TODO: Add your command handler code here
RefreshList();
QuickSortNode* order;
int totalNums=0;
operFamilytree.GetPersonNums(operFamilytree.GetRoot(),totalNums);
order=new QuickSortNode[totalNums+1];
if(!order){
AfxMessageBox("内存不足!");
return;
}
operFamilytree.SortByBirthday(order);
for(int i=1;i<totalNums+1;i++)
DisplayInListCtrl(order[i].oneself);
AfxMessageBox("排序后结果请见下部列表。");
delete []order;
}
void CFamilytreeDlg::RefreshList()
{
m_peList.DeleteAllItems();
}
BOOL CFamilytreeDlg::DestroyWindow()
{
// TODO: Add your specialized code here and/or call the base class
if(IsFamilytreeModified){ //如家谱被修改,给出保存提示
SaveTip();
IsFamilytreeModified=false;
}
MessageBox("谢谢您使用本程序!由于作者对于MFC类的开发经验不足,BUG难免有之,还请多多包涵:)","靳国荣",MB_OK);
return CDialog::DestroyWindow();
}
void CFamilytreeDlg::SaveTip()
{
if(IsFamilytreeModified){
int reply;
reply=::MessageBox(this->m_hWnd,"该家谱已被修改,你想保存吗?","家谱管理系统",MB_YESNO|MB_ICONWARNING);
if(reply==IDNO)
return;
CFileOpenAndSaveDlg dlg(false); //保存文件对话框
if(dlg.DoModal()==IDCANCEL)
return;
UpdateData(false);
if(strcmp(dlg.m_filePath,"")==0){
AfxMessageBox("文件名不能为空!");
return;
}
operFamilytree.SaveFamilytree(dlg.m_filePath); //保存
}
}
void CFamilytreeDlg::OnFileNew()
{
// TODO: Add your command handler code here
SaveTip();
IsFamilytreeModified=false;
operFamilytree.NewFamilytree();
int reply;
reply=::MessageBox(this->m_hWnd,"在建立新家谱前,将关闭现有的家谱文件,您确定吗?","家谱管理系统",MB_YESNO|MB_ICONWARNING);
if(reply==IDNO)
return;
RefreshTree();
RefreshList();
AfxMessageBox("下面将增加家谱的根结点!");
GetDlgItem(IDC_ADD)->EnableWindow(TRUE); //家谱控制按钮可用
GetDlgItem(IDC_DELETE)->EnableWindow(TRUE);
GetDlgItem(IDC_MODIFY)->EnableWindow(TRUE);
GetDlgItem(IDC_PEDIGREE_IGENERATION_INFO)->EnableWindow(TRUE);
GetDlgItem(IDC_PEDIGREE_SORT)->EnableWindow(TRUE);
GetDlgItem(IDC_PEDIGREE_RELATIONS)->EnableWindow(TRUE);
GetDlgItem(IDC_PEDIGREE_PERSONAL_INFO)->EnableWindow(TRUE);
GetDlgItem(IDC_BIRTHDAY)->EnableWindow(TRUE);
OnAdd();
}
void CFamilytreeDlg::OnBirthday()
{
// TODO: Add your control notification handler code here
CBirthdayDlg dlg;
if(dlg.DoModal()==IDCANCEL)
return;
int curmonth,curday;
curday=dlg.m_birthday_day;
curmonth=dlg.m_birthday_month;
Person oneself[30];
for(int i=0;i<30;i++)
oneself[i]=0;
Person* start=oneself;
operFamilytree.Find(operFamilytree.GetRoot(),start,curmonth,curday);
if(oneself[0]!=0){
CString allnames("该天为以下家族成员的生日:");
for(i=0;oneself[i]!=0;i++){
allnames+=" ";
allnames+=oneself[i]->info.name;
allnames+=" ";
}
allnames+="\n详细信息请见以下列表.";
::MessageBox(this->m_hWnd,allnames,"查找结果:",MB_OK|MB_ICONINFORMATION);
RefreshList();
for(i=0;oneself[i]!=0;i++)
DisplayInListCtrl(oneself[i]);
}
else
{AfxMessageBox("没有找到生日为该天的家族成员!");
RefreshList();}
}
void CFamilytreeDlg::OnManager()
{
// TODO: Add your control notification handler code here
CUserDlg dlg(m_dwUser);
dlg.DoModal();
}
void CFamilytreeDlg::OnSendMessage()
{
// TODO: Add your control notification handler code here
CBookDialog dlg;
dlg.DoModal();
}
void CFamilytreeDlg::OnSetMusic()
{
// TODO: Add your control notification handler code here
CSettingDlg dlg(m_dwUser);
//dlg.DoModal();
if(dlg.DoModal()==IDOK)
{
musiconoff=dlg.m_bMusic;
musicfilename=dlg.m_strMusicFileName;
if(musiconoff==TRUE)
{
PlayMusic();
}
else
{
MCI_GENERIC_PARMS mciGP;
mciSendCommand(m_wID,MCI_STOP,MCI_NOTIFY,(DWORD)(LPVOID)&mciGP);
}
}
}
void CFamilytreeDlg::PlayMusic()
{
MCI_GENERIC_PARMS mciGP;
mciSendCommand(m_wID,MCI_CLOSE,MCI_NOTIFY,(DWORD)(LPVOID)&mciGP);
MCI_OPEN_PARMS mciOP;
DWORD dwReturn;
mciOP.lpstrDeviceType=NULL;
mciOP.lpstrElementName=musicfilename;
dwReturn=mciSendCommand(NULL,MCI_OPEN,MCI_OPEN_ELEMENT,(DWORD)(LPVOID)&mciOP);
if(dwReturn==0)
{
m_wID=mciOP.wDeviceID;
}
MCI_PLAY_PARMS mciPP;
mciSendCommand(m_wID,MCI_PLAY,MCI_NOTIFY,(DWORD)(LPVOID)&mciPP);
}
void CFamilytreeDlg::OnAbout()
{
// TODO: Add your command handler code here
CAboutDlalog dlg;
dlg.DoModal();
}
BOOL CAboutDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// TODO: Add extra initialization here
m_btnOk.SubclassDlgItem(IDOK, this);
m_btnOk.SetIcon(IDI_ICON22);
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -