📄 notedlg.cpp
字号:
}
}
//菜单项"保存为"的响应函数
void CNoteDlg::OnSaveAs()
{
// TODO: Add your command handler code here
if(m_wndTree.GetCount()<=0)
return;
CFileDialog fileDlg(FALSE,"not",NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,"笔记本文件(*.not)|*.not|所有文件(*.*)|*.*|");
if(fileDlg.DoModal()==IDOK)
{
SaveTree(fileDlg.GetPathName());
OpenTree(fileDlg.GetPathName());
}
m_bIsModified=FALSE;
}
//菜单项"关于"的响应函数
void CNoteDlg::OnAbout()
{
// TODO: Add your command handler code here
CAboutDlg dlg;
dlg.DoModal();
}
//菜单项"新建"的响应函数,建立新文件
void CNoteDlg::OnNew()
{
// TODO: Add your command handler code here
if(m_bIsModified)
{
int res=AfxMessageBox(IDS_SAVE_MODIFY,MB_YESNOCANCEL|MB_ICONQUESTION);
if(res==IDCANCEL)
return;
else if(res==IDYES)
SaveModified();
else if(res==IDNO)
m_bIsModified=FALSE;
}
Reset();
GetDlgItem(IDC_ADDNEW)->EnableWindow(TRUE);
OnAddnew();
}
//构造树
//请先参阅所附的<<说明.txt>>
BOOL CNoteDlg::OpenTree(CString strFileName)
{
//把原文件strFileName复制另一份用于填充树以及操作中的读写
Reset();
CString strNewTitle;
strNewTitle+=m_strTitle+" - "+strFileName;
SetWindowText(strNewTitle);
m_strOpenFileName=strFileName; //设置打开文件为strFileName
m_strCurOpenFile=CreateTempFileName();
CopyFile(m_strOpenFileName,m_strCurOpenFile,FALSE);//复制文件
//先读出文件头中包含的dwItemCount和dwItemInfoCompressedSize;
FILE_HEADER FHeader;
CFile file;
file.Open(m_strCurOpenFile,CFile::modeRead);
file.Read((LPVOID)(&FHeader),sizeof(FILE_HEADER));
CString strTpfName=CreateTempFileName();
CString strTempItemFileName=CreateTempFileName();
//把文件中的ItemInfo压缩信息读到临时文件strTpfName
CFile tpf;
tpf.Open(strTpfName,CFile::modeCreate|CFile::modeWrite|CFile::shareDenyWrite);
HGLOBAL hMem=GlobalAlloc(GHND,FHeader.dwItemInfoCompressedSize);
LPVOID lpBuffer;
lpBuffer=GlobalLock(hMem);
GlobalUnlock(hMem);
file.Read(lpBuffer,FHeader.dwItemInfoCompressedSize);
tpf.Write(lpBuffer,FHeader.dwItemInfoCompressedSize);
tpf.Flush();
file.Close();
tpf.Close();
//解压缩所文件strTpfName到文件strTempItemFileName
CUnZip unZip(strTpfName);
unZip.SwapSize(strTempItemFileName);
DeleteFile(strTpfName); //删除strTpfName
CFile itemFile;
itemFile.Open(strTempItemFileName,CFile::modeRead|CFile::shareDenyWrite);
DWORD dwItemCount=FHeader.dwItemCount;//总的节点项数
//开始读各个Item信息
ITEM_INFO *pItemInfo;
UINT size=sizeof(ITEM_INFO);
HGLOBAL hMemItemInfo=GlobalAlloc(GHND,size+1);
pItemInfo=(ITEM_INFO*)GlobalLock(hMemItemInfo);
GlobalUnlock(hMemItemInfo);
itemFile.Read(pItemInfo,size);
HTREEITEM hItem=TVI_ROOT;
hItem=m_wndTree.InsertItem(pItemInfo->szName,hItem);
m_wndTree.SetItemData(hItem,m_dwDocCount);
m_dwItemCount=1; //已插入了一个节点
while((itemFile.Read(pItemInfo,size)==size)&&m_dwItemCount<dwItemCount)
{
m_dwItemCount++;
if(pItemInfo->nFlag==-1) //表示要插入的节点时前一插入节点的子项
hItem=m_wndTree.InsertItem(pItemInfo->szName,hItem);
else if(pItemInfo->nFlag==0)//表示要插入的节点时前一插入节点的兄弟项
{
hItem=m_wndTree.GetParentItem(hItem);
hItem=m_wndTree.InsertItem(pItemInfo->szName,hItem);
}
else
{
for(int i=0;i<=pItemInfo->nFlag;i++)
hItem=m_wndTree.GetParentItem(hItem);
hItem=m_wndTree.InsertItem(pItemInfo->szName,hItem);
}
if(pItemInfo->bIsDoc) //如果该项是文档项,则把它的信息添加到队列m_arDoc中
{
m_dwDocCount++; //文档项数加1
m_wndTree.SetItemData(hItem,m_dwDocCount); //设置该项data为其在总的文档数中的序数
m_wndTree.SetItemImage(hItem,2,2);
DOC_INFO *pDocInfo;
HGLOBAL hMemDocInfo=GlobalAlloc(GHND,sizeof(DOC_INFO)+1);
pDocInfo=(DOC_INFO*)GlobalLock(hMemDocInfo);
GlobalUnlock(hMemDocInfo);
pDocInfo->bIsNew=FALSE;
strcpy(pDocInfo->szFileName,m_strCurOpenFile);//把其对应的文件名设置为m_strCurOpenFile,
pDocInfo->dwOffset=pItemInfo->dwOffset+FHeader.dwDocOffset;
pDocInfo->dwLength=pItemInfo->dwLength;
pDocInfo->bIsNew=FALSE;
m_arDoc.SetAtGrow(m_dwDocCount,*pDocInfo);
GlobalFree(hMemDocInfo);
}
else //不是文档项,则设置ItemData为-1
{
m_wndTree.SetItemData(hItem,-1);
m_wndTree.SetItemImage(hItem,0,0);
}
}
itemFile.Close();
DeleteFile(strTempItemFileName);
GlobalFree(hMemItemInfo);
m_wndTree.Expand(m_wndTree.GetRootItem(),TVE_TOGGLE);
return TRUE;
}
//辅助函数,创建临时文件名
CString CNoteDlg::CreateTempFileName()
{
char szPath[MAX_PATH];
CString strTmpFileName;
GetTempPath(MAX_PATH,szPath);
GetTempFileName(szPath,"bhb",0,strTmpFileName.GetBuffer(MAX_PATH+1));
strTmpFileName.ReleaseBuffer();
return strTmpFileName;
}
//树中的被选项发生了变化
void CNoteDlg::OnSelchangedTree(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
// TODO: Add your control notification handler code here
TVITEM tvItem;
tvItem=pNMTreeView->itemNew;
HTREEITEM hItem;
hItem=tvItem.hItem; //获得被选项
if(!hItem)
{
GetDlgItem(IDC_RENAME)->EnableWindow(FALSE);
return;
}
GetDlgItem(IDC_RENAME)->EnableWindow();
DWORD dwItemData=-1;
dwItemData=m_wndTree.GetItemData(hItem); //获得该项的Data
if(dwItemData!=-1) //如不是-1,则说明是文档节点
{
GetDlgItem(IDC_ADDNEW)->EnableWindow(FALSE); //文档节点下不可添加子节点
GetDlgItem(IDC_DEL)->EnableWindow(TRUE); //只有文档节点和无子节点的类节点可以被删除
DOC_INFO docInfo;
docInfo=m_arDoc.GetAt((int)dwItemData); //从队列中获取该文档节点的信息
if(docInfo.dwLength>0) //文档长度大于0
{
CFile dataFile;
dataFile.Open(docInfo.szFileName,CFile::modeRead);
LPVOID lpBuffer;
HGLOBAL hMem=GlobalAlloc(GHND,docInfo.dwLength);
lpBuffer=GlobalLock(hMem);
dataFile.Seek(docInfo.dwOffset,CFile::begin);
dataFile.Read(lpBuffer,docInfo.dwLength); //读出文档内容
GlobalUnlock(hMem);
dataFile.Close();
//如果节点信息中的文件名不是m_strCupOpenFile,则说明不是压缩数据,可以直接填充编辑控件
if(m_strCurOpenFile.CompareNoCase(docInfo.szFileName))
{
m_wndOwnEdit.SetWindowText((LPCTSTR)lpBuffer);
GlobalFree(hMem);
}
else //是压缩数据,则把压缩数据写到临时文件tmpFile1中
{
CString tmpFile1;
tmpFile1=CreateTempFileName();
CFile fl;
fl.Open(tmpFile1,CFile::modeCreate|CFile::modeWrite|CFile::shareDenyWrite);
fl.Write(lpBuffer,docInfo.dwLength);
fl.Flush();
fl.Close();
CString tmpFile2;
tmpFile2=CreateTempFileName();
CUnZip unZip(tmpFile1);
unZip.SwapSize(tmpFile2); //把压缩数据解压到tmpFile2中
DeleteFile(tmpFile1);
fl.Open(tmpFile2,CFile::modeRead|CFile::shareDenyWrite);
DWORD length;
length=fl.GetLength();
GlobalFree(hMem);
hMem=GlobalAlloc(GHND,length);
lpBuffer=GlobalLock(hMem);
fl.Read(lpBuffer,length); //读出解压缩后的数据
GlobalUnlock(hMem);
fl.Close();
m_wndOwnEdit.SetWindowText((LPCTSTR)lpBuffer); //填充编辑控件
GlobalFree(hMem);
//重新设置该文档节点的信息
docInfo.bIsNew=FALSE;
docInfo.dwLength=length;
docInfo.dwOffset=0;
strcpy(docInfo.szFileName,tmpFile2); //重定向文档节点的对应文件名,下次显示该节点内容时就不必再解压缩
m_arDoc.SetAt((int)dwItemData,docInfo);
}
}
}
else //如果不是文档节点,而是类节点
{
m_wndOwnEdit.SetWindowText("");
GetDlgItem(IDC_ADDNEW)->EnableWindow(); //可以添加子节点
if(m_wndTree.ItemHasChildren(hItem))
GetDlgItem(IDC_DEL)->EnableWindow(FALSE);
else
GetDlgItem(IDC_DEL)->EnableWindow(TRUE);
}
*pResult = 0;
}
//重载IDCANCEL的响应函数,防止用户按下ESC后窗口关闭
void CNoteDlg::OnCancel()
{
// TODO: Add extra cleanup here
return;
CDialog::OnCancel();
}
//重载IDOK的响应函数,防止用户按下回车后窗口关闭
void CNoteDlg::OnOk()
{
// TODO: Add your control notification handler code here
return;
}
//用户单击了窗口右上角的关闭按钮.
void CNoteDlg::OnClose()
{
// TODO: Add your message handler code here and/or call default
if(m_bIsModified)
{
int res=AfxMessageBox(IDS_SAVE_MODIFY,MB_YESNOCANCEL|MB_ICONQUESTION);
if(res==IDCANCEL)
return;
else if(res==IDYES)
SaveModified();
}
// 删除临时文件
CFileFind finder;
if(!m_strCurOpenFile.IsEmpty())
{
if(finder.FindFile(m_strCurOpenFile))
DeleteFile(m_strCurOpenFile);
finder.Close();
m_strCurOpenFile.Empty();
}
//删除各个文档节点对应的临时文件
int upper;
upper=m_arDoc.GetUpperBound();
if(upper>-1)
{
DOC_INFO docInfo;
for(int i=0;i<=upper;i++)
{
docInfo=m_arDoc.GetAt(i);
if(finder.FindFile(docInfo.szFileName))
{
DeleteFile(docInfo.szFileName);
finder.Close();
}
}
m_arDoc.RemoveAll(); //清除队列
}
CDialog::OnClose();
CDialog::OnOK();
}
//菜单项"退出"的响应函数
void CNoteDlg::OnExit()
{
// TODO: Add your command handler code here
OnClose();
}
//该函数处理用那种方式保存
void CNoteDlg::SaveModified()
{
if(m_wndTree.GetCount()>0)
{
if(m_strCurOpenFile.IsEmpty())
OnSaveAs();
else
OnSave();
}
}
//菜单项"保存"的响应函数
void CNoteDlg::OnSave()
{
// TODO: Add your command handler code here
if(m_bIsModified==FALSE)
return;
//如果当前打开文件名为空,说明是建的文件,则调用OnSaveAs()函数
if(m_strOpenFileName.IsEmpty())
{
OnSaveAs();
return;
}
else
{
SaveTree(m_strOpenFileName); //保存完后重新打开新文件,在OpenTree中调用了Reset()函数
OpenTree(m_strOpenFileName);
m_bIsModified=FALSE;
}
}
//按钮"删除"的响应函数,删除树中的节点
void CNoteDlg::OnDel()
{
// TODO: Add your control notification handler code here
HTREEITEM hItem;
hItem=m_wndTree.GetSelectedItem();
HTREEITEM hParentItem;
hParentItem=m_wndTree.GetParentItem(hItem);
if(hItem)
{
m_wndTree.DeleteItem(hItem);
m_dwItemCount--;
if(m_wndTree.GetCount()<=0)
if(m_strCurOpenFile.IsEmpty())
{
m_bIsModified=FALSE;
return;
}
if(hParentItem)
if(!m_wndTree.ItemHasChildren(hParentItem))
m_wndTree.SetItemImage(hParentItem,0,0);
m_bIsModified=TRUE;
}
}
//按钮"更名"的响应函数
void CNoteDlg::OnRename()
{
// TODO: Add your control notification handler code here
HTREEITEM hItem;
hItem=m_wndTree.GetSelectedItem();
if(hItem)
{
CString strOldName=m_wndTree.GetItemText(hItem);;
CChangeNameDlg dlg;
dlg.m_strNewName=dlg.m_strOldName=strOldName;
if(dlg.DoModal()==IDOK)
{
if(dlg.m_strNewName.CompareNoCase(strOldName))
m_wndTree.SetItemText(hItem,dlg.m_strNewName);
m_bIsModified=TRUE;
}
}
}
void CNoteDlg::Reset()
{
m_wndOwnEdit.SetWindowText("");
SetWindowText(m_strTitle); //恢复窗口标题
m_wndTree.DeleteAllItems(); //删除树中的所有项的
m_dwDocCount=-1;
m_dwItemCount=0;
m_strOpenFileName.Empty();
// 删除临时文件
CFileFind finder;
if(!m_strCurOpenFile.IsEmpty())
{
if(finder.FindFile(m_strCurOpenFile))
DeleteFile(m_strCurOpenFile);
finder.Close();
m_strCurOpenFile.Empty();
}
//删除各个文档节点对应的临时文件
int upper;
upper=m_arDoc.GetUpperBound();
if(upper>-1)
{
DOC_INFO docInfo;
for(int i=0;i<=upper;i++)
{
docInfo=m_arDoc.GetAt(i);
if(finder.FindFile(docInfo.szFileName))
{
DeleteFile(docInfo.szFileName);
finder.Close();
}
}
m_arDoc.RemoveAll(); //清除队列
}
}
void CNoteDlg::OnDestroy()
{
CDialog::OnDestroy();
// TODO: Add your message handler code here
m_wndOwnEdit.DestroyWindow(); //销毁创建的编辑控件
delete m_pImgList; //释放内存空间
delete m_pEditFont;
}
void CNoteDlg::OnItemexpandedTree(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
// TODO: Add your control notification handler code here
TVITEM tvItem;
tvItem=pNMTreeView->itemNew;
HTREEITEM hItem;
hItem=tvItem.hItem;
if(!hItem)
return;
if(pNMTreeView->action==2)
m_wndTree.SetItemImage(hItem,1,1);
else if(pNMTreeView->action==1)
m_wndTree.SetItemImage(hItem,0,0);
*pResult = 0;
}
//辅助函数,检查文件格式
BOOL CNoteDlg::CheckFileFormat(CString strFileName)
{
CFile file;
if(!file.Open(strFileName,CFile::modeRead))
{
AfxMessageBox(AFX_IDP_FAILED_TO_LAUNCH);
return FALSE;
}
FILE_HEADER fileHeader;
if(file.Read(&fileHeader,sizeof(FILE_HEADER))!=sizeof(FILE_HEADER))
{
AfxMessageBox(IDS_ERROR_FORMAT,MB_ICONEXCLAMATION|MB_OK);
file.Close();
return FALSE;
}
if(strcmp(fileHeader.szFlag,"鲍浩波")!=0)
{
AfxMessageBox(IDS_ERROR_FORMAT,MB_ICONEXCLAMATION|MB_OK);
file.Close();
return FALSE;
}
file.Close();
return TRUE;
}
//设置文档内容显示框的字体.
void CNoteDlg::OnFont()
{
// TODO: Add your command handler code here
LOGFONT lf;
m_wndOwnEdit.GetFont()->GetLogFont(&lf);
CFontDialog fontDlg(&lf, CF_SCREENFONTS);
if(fontDlg.DoModal()==IDOK)
{
fontDlg.GetCurrentFont(&lf);
m_pEditFont->Detach();
m_pEditFont->CreateFontIndirect(&lf);
m_wndOwnEdit.SetFont(m_pEditFont);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -