上一篇博客《MFC单文档框架建立》https://blog.youkuaiyun.com/qq_38834877/article/details/109096617
已经介绍了怎么创建mfc单文档的框架,这一篇就直接附上代码做一个记事本软件。
效果图:
因为单文档框架没有拖拽文本框的功能,所以我一开始是在打开文件的时候弹出一个对话框,在对话框里面放入文本框,把读取的文件内容放在文本框里面,但是这样非常的奇怪。后来查阅资料发现,可以直接定义一个文本框,然后使用它,这部分的代码我也是网上找的,有的也并不是很明白用处,所以只是做一个总结搬运。
环境:vs2019
步骤:
一、在自动生成的CMFCTXTDoc.h文件中添加变量m_strContent。
CStringArray m_strContent;
二、在Serialize函数中添加下面的代码
void CMFCTXTDoc::Serialize(CArchive& ar)
{
CString str;
if (ar.IsStoring())
{
// TODO: add storing code here
int nLines = (int)m_strContent.GetSize();
for (int i = 0; i < nLines; i++)
{
str = m_strContent.GetAt(i);
ar.WriteString(str); // 将字符串集合类对象中文本保存到硬盘
}
}
else
{
// TODO: add loading code here
while (ar.ReadString(str))
{
m_strContent.Add(str); // 将行文本添加到字符串集合类对象中
}
}
}
三、在资源视图里面点开类向导,为CMFCTXTDoc类添加函数DeleteContents,并添加代码。
void CMFCTXTDoc::DeleteContents()
{
// TODO: 在此添加专用代码和/或调用基类
m_strContent.RemoveAll();
CDocument::DeleteContents();
}
四、在CMFCTXTView类中添加文本框变量,并在构造函数中初始化
CEdit* m_ctrlEdit;
CMFCTXTView::CMFCTXTView() noexcept
: m_ctrlEdit(NULL)
{
// TODO: 在此处添加构造代码
}
五、使用类向导给CMFCTXTView类添加DeleteContents虚函数和消息WM_SIZE的处理函数,并添加下面代码
void CMFCTXTView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
CRect rcClient;
GetClientRect(rcClient);
if (m_ctrlEdit)
m_ctrlEdit->MoveWindow(rcClient); // 改变编辑控件窗口大小
}
void CMFCTXTView::OnInitialUpdate()
{
CView::OnInitialUpdate();
// TODO: Add your specialized code here and/or call the base class
CRect rcClient;
GetClientRect(rcClient); // 获取当前视图的客户区大小
// if ( m_ctrlEdit ) delete m_ctrlEdit;
m_ctrlEdit = new CEdit();
m_ctrlEdit->Create(ES_MULTILINE | WS_CHILD | WS_VISIBLE
| WS_HSCROLL | ES_AUTOHSCROLL // 自动水平滚动
| WS_VSCROLL | ES_AUTOVSCROLL, // 自动垂直滚动
rcClient, this, 201); // 创建多行编辑控件
CMFCTXTDoc* pDoc = GetDocument(); // 获取与视图相关联的文档指针
// 以下是将文档中的m_strContent内容全部赋给str
CString str;
int nLines = (int)pDoc->m_strContent.GetSize();
for (int i = 0; i < nLines; i++)
{
str = str + pDoc->m_strContent.GetAt(i);
str = str + "\r\n"; // 换行
}
m_ctrlEdit->SetTabStops(16); // 设置Tab符大小
m_ctrlEdit->SetWindowText(str); // 将文档内容传给控件
// TODO: 在此添加专用代码和/或调用基类
}
六、在资源视图-Menu-添加打开和保存的处理函数,注意添加在CMFCTXTView类中。
添加完函数之后,在编辑函数OnFileOpen
void CMFCTXTView::OnFileOpen()
{
CString strTemp, result;
CString temp;
int row = 0;
TCHAR szFilter[] = _T("文本文件(*.txt)||DAT文件(*.dat)||所有文件(*.*)||");
CFileDialog fileDlg(TRUE, _T("txt"), NULL, 0, szFilter, this);
if (IDOK == fileDlg.DoModal())
{
CStdioFile file;
file.Open(fileDlg.GetPathName(), CFile::modeReadWrite);
while (file.ReadString(temp))
{
char* str = (char*)temp.GetBufferSetLength(temp.GetLength());
if (temp != "")
{
result += "\r\n" + temp;
row++;
}
}
m_ctrlEdit->SetWindowTextA(result);
m_ctrlEdit->UpdateWindow();
m_ctrlEdit->SendMessage(WM_VSCROLL, SB_BOTTOM, 0);
file.Close();
}
}
编辑函数OnFileSave
void CMFCTXTView::OnFileSave()
{
CString FileName;
CFileDialog dlgFile(FALSE, _T("*.txt"), NULL, OFN_HIDEREADONLY, _T("Describe File(*.txt)|*.txt|*.dat|All Files(*.*)|*.*||"), NULL);
if (IDOK == dlgFile.DoModal())
{
FileName = dlgFile.GetPathName();
}
else
{
return;
}
CStdioFile FileWrite;
if (!FileWrite.Open(FileName, CFile::modeWrite | CFile::modeCreate | CFile::typeText))
{
AfxMessageBox(_T("打开文件失败!"));
return;
}
CString result;
UpdateData(TRUE);
m_ctrlEdit->GetWindowTextA(result);
result.Replace("\r", "");
FileWrite.WriteString(result);
FileWrite.Close();
}
七、运行一下,发现会报错,在调试-属性中把字符集改为多字节字符集。
八、测试
运行代码
打开一个文件,显示正常。
保存一个文件,正常。
现在记事本已经可以实现打开和保存了,细心的可以发现,复制粘贴还不能使用,下一篇博客《window记事本-利用MFC单文档实现(后续一添加复制粘贴功能)》https://blog.youkuaiyun.com/qq_38834877/article/details/109099713
介绍怎么添加复制粘贴功能。
源码:https://download.youkuaiyun.com/download/qq_38834877/12928421