📄 notedlg.cpp
字号:
// NoteDlg.cpp : implementation file
//
#include "stdafx.h"
#include "Note.h"
#include "NoteDlg.h"
#include "zip.h"
#include "unzip.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CNoteDlg dialog
CNoteDlg::CNoteDlg(CWnd* pParent /*=NULL*/)
: CDialog(CNoteDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CNoteDlg)
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CNoteDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CNoteDlg)
DDX_Control(pDX, IDC_TREE, m_wndTree);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CNoteDlg, CDialog)
//{{AFX_MSG_MAP(CNoteDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_ADDNEW, OnAddnew)
ON_COMMAND(ID_OPEN, OnOpenFile)
ON_COMMAND(ID_SAVEAS, OnSaveAs)
ON_COMMAND(ID_ABOUT, OnAbout)
ON_COMMAND(ID_NEW, OnNew)
ON_NOTIFY(TVN_SELCHANGED, IDC_TREE, OnSelchangedTree)
ON_BN_CLICKED(IDOK, OnOk)
ON_WM_CLOSE()
ON_COMMAND(ID_EXIT, OnExit)
ON_COMMAND(ID_SAVE, OnSave)
ON_BN_CLICKED(IDC_DEL, OnDel)
ON_BN_CLICKED(IDC_RENAME, OnRename)
ON_WM_DESTROY()
ON_NOTIFY(TVN_ITEMEXPANDED, IDC_TREE, OnItemexpandedTree)
ON_COMMAND(ID_FONT, OnFont)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CNoteDlg message handlers
BOOL CNoteDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
CRect treeRect;
GetDlgItem(IDC_TREE)->GetWindowRect(&treeRect);
ScreenToClient(&treeRect);
CRect wndRect;
GetClientRect(&wndRect);
CRect editRect;
editRect.left=treeRect.right+10;
editRect.top=treeRect.top;
editRect.right=wndRect.right-10;
editRect.bottom=wndRect.bottom-10;
DWORD style=0;
//创建编辑控件,设置字体
m_wndOwnEdit.Create(WS_CHILDWINDOW|WS_VISIBLE|WS_VSCROLL|WS_BORDER|ES_MULTILINE|ES_LEFT,editRect,this,IDC_EDIT);
m_wndOwnEdit.SetMargins(5,5); //设置显示边界
m_pEditFont=new CFont();
LOGFONT lf;
GetFont()->GetLogFont(&lf);
m_pEditFont->CreateFontIndirect(&lf);
m_wndOwnEdit.SetFont(m_pEditFont);
//初始化变量
m_dwDocCount=-1;
m_dwItemCount=0;
m_strCurOpenFile.Empty();
m_bIsModified=FALSE;
GetWindowText(m_strTitle); //获得程序刚启动时的窗口标题
//创建树控件的图像列表
m_pImgList=new CImageList();
m_pImgList->Create(16,16,ILC_COLOR8,3,5);
HICON hIcon;
hIcon=AfxGetApp()->LoadIcon(IDI_CLASS_CLOSE);
m_pImgList->Add(hIcon);
hIcon=AfxGetApp()->LoadIcon(IDI_CLASS_OPEN);
m_pImgList->Add(hIcon);
hIcon=AfxGetApp()->LoadIcon(IDI_DOC);
m_pImgList->Add(hIcon);
m_wndTree.SetImageList(m_pImgList,TVSIL_NORMAL);
m_wndTree.SetTextColor(RGB(0,0,255));
//如果m_strShellFileName(由InitInstance()传递)非空,则说明程序时Shell打开的.
if(!m_strShellFileName.IsEmpty())
{
if(!CheckFileFormat(m_strShellFileName))
return FALSE;
return OpenTree(m_strShellFileName);
}
return TRUE; // return TRUE unless you set the focus to a control
}
void CNoteDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CNoteDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CNoteDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
//按钮"新增"的响应函数,向树控件中添加新项
void CNoteDlg::OnAddnew()
{
// TODO: Add your control notification handler code here
CNewClassDlg dlg;
HTREEITEM hParentItem=m_wndTree.GetSelectedItem();
if(!hParentItem)
{
hParentItem=TVI_ROOT;
dlg.m_bIsRaDocEnabled=FALSE;
}
CString strName,strText;
strName.Empty();
strText.Empty();
if(dlg.DoModal()==IDOK)
{
strName=dlg.m_strNewClassName;
strText=dlg.m_strInfo;
}
if(!strName.IsEmpty())
{
HTREEITEM hItem=m_wndTree.InsertItem(strName,hParentItem);
m_dwItemCount++;
m_bIsModified=TRUE; //置文件更改标志
if(dlg.m_bIsDoc) //添加的是否是文档项
{
m_dwDocCount++;
m_wndTree.SetItemData(hItem,m_dwDocCount);
m_wndTree.SetItemImage(hItem,2,2);
if(!strText.IsEmpty())
{
//把该文档项的内容写到一临时文件中
CString strTmpFileName=CreateTempFileName();
CFile file;
file.Open(strTmpFileName,CFile::modeCreate|CFile::modeReadWrite);
file.Write(strText,strText.GetLength());
file.Close();
DOC_INFO docInfo;
docInfo.bIsNew=TRUE;
docInfo.dwLength=strText.GetLength();
docInfo.dwOffset=0;
//把该文档项对应的文件名定向到该临时文件
strcpy(docInfo.szFileName,strTmpFileName);
m_arDoc.SetAtGrow(m_dwDocCount,docInfo);//向文档队列添加该文档信息
}
else
{
DOC_INFO docInfo;
docInfo.bIsNew=TRUE;
docInfo.dwLength=0;
docInfo.dwOffset=0;
strcpy(docInfo.szFileName," ");
m_arDoc.SetAtGrow(m_dwDocCount,docInfo);
}
}
else
m_wndTree.SetItemData(hItem,-1);
m_wndTree.Expand(hParentItem,TVE_EXPAND);
m_wndTree.SelectItem(hItem);
}
}
//保存树控件中的内容到文件
// 该函数具体功能见所附的<<说明.txt>>
BOOL CNoteDlg::SaveTree(CString strFileName)
{
HTREEITEM hWriteItem=m_wndTree.GetRootItem();
if(!hWriteItem)
return FALSE;
CString strTmpDocFileName=CreateTempFileName();
CString strTmpItemFileName=CreateTempFileName();
CFile tmpDocFile;
CFile tmpItemFile;
tmpDocFile.Open(strTmpDocFileName,CFile::modeCreate|CFile::modeReadWrite|CFile::shareDenyWrite);
tmpItemFile.Open(strTmpItemFileName,CFile::modeCreate|CFile::modeReadWrite|CFile::shareDenyWrite);
ITEM_INFO *pItemInfo;
HGLOBAL hMemItemInfo=GlobalAlloc(GHND,sizeof(ITEM_INFO));
pItemInfo=(ITEM_INFO*)GlobalLock(hMemItemInfo);
GlobalUnlock(hMemItemInfo);
DOC_INFO *pDocInfo;
HGLOBAL hMemDocInfo=GlobalAlloc(GHND,sizeof(DOC_INFO));
pDocInfo=(DOC_INFO*)GlobalLock(hMemDocInfo);
GlobalUnlock(hMemDocInfo);
DWORD dwItemData=-1;
int flag=1;
do{
CString str=m_wndTree.GetItemText(hWriteItem);
strcpy(pItemInfo->szName,(LPCTSTR)str);
pItemInfo->nFlag=flag;
pItemInfo->dwOffset=0;
pItemInfo->dwLength=0;
pItemInfo->bIsDoc=FALSE;
dwItemData=m_wndTree.GetItemData(hWriteItem);
if(dwItemData!=-1) //说明是文档项
{
pItemInfo->bIsDoc=TRUE;
pDocInfo=&(m_arDoc.GetAt((int)dwItemData)); //获取该文档项的信息
if(pDocInfo->dwLength>0)
{
if(pDocInfo->bIsNew==FALSE) //如不是新插入的项,则不需压缩数据
{
CFile dataFile;
dataFile.Open(pDocInfo->szFileName,CFile::modeRead);
pItemInfo->dwLength=pDocInfo->dwLength;
pItemInfo->dwOffset=tmpDocFile.GetPosition();
dataFile.Seek(pDocInfo->dwOffset,CFile::begin);
LPVOID lpBuffer;
HGLOBAL hMem=GlobalAlloc(GHND,pDocInfo->dwLength+1);
lpBuffer=GlobalLock(hMem);
dataFile.Read(lpBuffer,pDocInfo->dwLength); //直接从源文件(应该是m_strCurOpenFile)中读取压缩数据
dataFile.Close();
tmpDocFile.Write(lpBuffer,pDocInfo->dwLength);
GlobalUnlock(hMem);
GlobalFree(hMem);
}
else //是新插入的文档项,则要压缩数据
{
CString tpf; //压缩到临时文件tpf中
tpf=CreateTempFileName();
CZip zip(pDocInfo->szFileName);
zip.SwapSize(tpf);
CFile fl;
fl.Open(tpf,CFile::modeRead|CFile::shareDenyWrite);
DWORD length=fl.GetLength();
pItemInfo->dwLength=length;
pItemInfo->dwOffset=tmpDocFile.GetPosition();
LPVOID lpBuffer;
HGLOBAL hMem=GlobalAlloc(GHND,length);
lpBuffer=GlobalLock(hMem);
fl.Read(lpBuffer,length);
fl.Close();
tmpDocFile.Write(lpBuffer,length); //再从文件tpf中转移到tmpFile中
DeleteFile(tpf); //删除临时文件
GlobalUnlock(hMem);
GlobalFree(hMem);
}
tmpDocFile.Flush();
}
}
tmpItemFile.Write(pItemInfo,sizeof(ITEM_INFO)); //向主文件写入项信息
}while(hWriteItem=GetNextWriteItem(hWriteItem,flag));
GlobalFree(hMemItemInfo);
GlobalFree(hMemDocInfo);
tmpItemFile.Flush();
tmpItemFile.SeekToBegin();
tmpItemFile.Close();
tmpDocFile.Flush();
tmpDocFile.SeekToBegin();
//把项信息原文件压缩为名为strTpf的文件
CString strTpf;
strTpf=CreateTempFileName();
CZip zip(strTmpItemFileName);
zip.SwapSize(strTpf);
DeleteFile(strTmpItemFileName); //删除项信息原文件
CFile tpf;
tpf.Open(strTpf,CFile::modeRead|CFile::shareDenyWrite);
//写入文件头
CFile file;
file.Open(strFileName,CFile::modeCreate|CFile::modeWrite|CFile::shareDenyWrite);
FILE_HEADER *pFHeader;
HGLOBAL hMemFHeader=GlobalAlloc(GHND,sizeof(FILE_HEADER)+1);
pFHeader=(FILE_HEADER*)GlobalLock(hMemFHeader);
GlobalUnlock(hMemFHeader);
pFHeader->dwItemCount=m_dwItemCount;
pFHeader->dwDocOffset=sizeof(FILE_HEADER)+tpf.GetLength();
pFHeader->dwItemInfoCompressedSize=tpf.GetLength();
strcpy(pFHeader->szFlag,"鲍浩波"); //置文件标志
file.Write(pFHeader,sizeof(FILE_HEADER)); //先写入文件头
GlobalFree(hMemFHeader);
//写入已压缩的项信息
LPVOID lpBuffer;
HGLOBAL hMemFile=GlobalAlloc(GHND,tpf.GetLength());
lpBuffer=GlobalLock(hMemFile);
GlobalUnlock(hMemFile);
tpf.Read(lpBuffer,tpf.GetLength());
file.Write(lpBuffer,tpf.GetLength());
tpf.Close();
DeleteFile(strTpf); //删除信息临时压缩文件
GlobalFree(hMemFile);
//转移tmpDocFile中的内容到主文件中
hMemFile=GlobalAlloc(GHND,tmpDocFile.GetLength());
lpBuffer=GlobalLock(hMemFile);
GlobalUnlock(hMemFile);
tmpDocFile.Read(lpBuffer,tmpDocFile.GetLength());
file.Write(lpBuffer,tmpDocFile.GetLength());
GlobalFree(hMemFile);
tmpDocFile.Close();
file.Close();
DeleteFile(strTmpDocFileName); //删除临时文件
return TRUE;
}
//辅助函数,用于保存文件时获取下一个要保存的项,采用深度优先遍历
HTREEITEM CNoteDlg::GetNextWriteItem(HTREEITEM hItem, int &flag)
{
if(m_wndTree.ItemHasChildren(hItem)) //有子节点
{
flag=-1;
return m_wndTree.GetChildItem(hItem);
}
HTREEITEM hSibItem=m_wndTree.GetNextSiblingItem(hItem);
if(hSibItem)// 无子节点,但有兄弟节点,则返回兄弟节点
{
flag=0;
return hSibItem;
}
else //既无子节点,也无兄弟节点,则寻找上级节点的兄弟节点
{ //flag表示上溯的级数
flag=0;
hSibItem=NULL;
do{
flag++;
hItem=m_wndTree.GetParentItem(hItem);
hSibItem=m_wndTree.GetNextSiblingItem(hItem);
}while(hSibItem==NULL&&hItem);
if(!hItem)
return NULL;
else
return hSibItem;
}
}
//菜单项"打开"的响应函数
void CNoteDlg::OnOpenFile()
{
// TODO: Add your command handler code here
CFileDialog dlgFile(TRUE,"not",NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,"笔记本文件(*.not)|*.not|所有文件(*.*)|*.*|");
if(dlgFile.DoModal()==IDOK)
{
CString strFileName=dlgFile.GetPathName();
if(!CheckFileFormat(strFileName))
return;
//格式正确,则提示保存以前更改
if(m_bIsModified)
{
int res=AfxMessageBox(IDS_SAVE_MODIFY,MB_YESNOCANCEL|MB_ICONQUESTION);
if(res==IDCANCEL)
return;
else if(res==IDYES)
SaveModified();
else
m_bIsModified=FALSE;
}
OpenTree(strFileName); //构造树
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -