MFC文本编辑器的设计与实现

一、程序界面设计

设计目标:

(1)允许输入多行文本;
(2)允许通过输入回车键来换行;
(3)当输入的文本满一行时,会自动插入软回车进行换行;
(4)当对话框尺寸发生变化时,会自动调整自己的尺寸来适应对话框尺寸的变化;
(5)可以对编辑框中的内容进行滚动。

实现过程:

根据以上要求,设计本程序界面如下图。

在这里插入图片描述
对话框中仅放置一个编辑控件,该控件属性设置如下:
a)“ID”设置为: IDC_EDIT_TXT
b)“Multiline”设置为: True
c)“Want Return”设置为: True
d)"Vertical Scroll”设置为: True
e)“Auto VScroll”设置为: True
在这里插入图片描述
对话框属性设置为:“Border”属性为“Resizing”。

二、菜单设计

设计目标:

进行菜单设计,并将设计好的菜单与对话框建立关联,使得在程序启动的过程中,自动为对话框建立起菜单。

实现过程:

在资源管理面板上单击右键,选择“添加资源”菜单项。在这里插入图片描述
在“添加资源”对话框中选择“Menu”项,然后单击新建按钮,在资源视图窗格中点开Menu项,在点中菜单资源后,通过属性窗口把菜单资源的属性设置为IDR_MY_MENU。在这里插入图片描述
在这里插入图片描述
编辑菜单内容
在这里插入图片描述
分割这一条线就是在键入处输入“-”,下划线则是在输入的字母前加入“&”。
菜单项的ID设置如下:

菜单项ID
新建(&N)ID_FILE_NEW
打开(&O)ID_FILE_OPEN
保存(&S)ID_FILE_SAVE
另存为(&A)ID_FILE_SAVE_AS
退出(&E)ID_FILE_EXIT
关于(&A)ID_HELP_ABOUT

把菜单附加到对话框。一种方法是通过修改对话框的Menu属性,将其属性值设置为菜单资源ID(即:本例中的 IDR_MY_MENU)。另外一种方法是通过在程序中调用对话框的成员函数来实现。以下采用的是第二种方法来实现把菜单添加到对话框中。
首先需要打开“类视图”窗口,点击对话框类,然后在下面的窗格中双击对话框初始化函数:“OnInitDialog()",打开OnInitDialog()代码编辑窗口,
在这里插入图片描述

在“TODO:在此添加额外的初始化代码”位置处添加如下代码,实现在对话框中装载菜单。
在该对话框实现文件的头部加入包含语句:

#include "resource.h"

以引入定义的菜单资源的标识符。

	m_bChanged = FALSE;
	m_sFileName.Empty();
	CMenu m_Menu;
	m_Menu.LoadMenu(IDR_MY_MENU);
	SetMenu(&m_Menu);

使用类向导为编辑控件添加两个控件变量:一个类别为Control,另一个的类别为Value。其中类别为 Value 的变量类型为CString。这两个变量的名字分别命令为: m_ctrlEditTxt和m_sEditTxt。(m_sFileName等是接下来要用到的)

使用类向导为对话框的WM_SIZE消息添加消息处理函数,该函数在对话框尺寸改变时将被调用。利用该函数,可以在对话框尺寸发生变化时,调整编辑控件尺寸和位置,使得两者的尺寸相适应。
在这里插入图片描述
WM_SIZE消息处理函数OnSize()的“TODO:在此处添加消息处理程序代码”位置处添加如下代码。

	int iMargin = 2;
	CRect r;
	GetClientRect(&r);
	int w = r.Width();
	int h = r.Height();
	if (m_ctrlEditTxt.m_hWnd)
		m_ctrlEditTxt.MoveWindow(iMargin, iMargin, w - 2 * iMargin, h - 2 * iMargin);

三、功能设计

程序逻辑设计

1.新建
在这里插入图片描述
2.打开

3.保存

在这里插入图片描述
4.另存为
在这里插入图片描述
5.退出
在这里插入图片描述
6.关于
以模态对话框方式将其屏幕上显示。

代码实现

添加一个bool类型变量:m_bChanged。用于记录编辑控件中的内容是否已经修改。
添加一个Cstring类型变量: m_sFileName。用于记录已打开的文件名。
(在实验过程中我发现无法在类向导中添加新的Cstring类型变量,所以我直接在代码中声明了该变量)
在这里插入图片描述

对话框初始化函数OnInitDialog()中,把这两个变量的内容分别设置为:FALSE和空。语句如下:

m_bChanged=FALSE;
m_sFileName.Empty ();

bool Cex2Dlg::SaveAs(void)
{
	// TODO: 在此处添加实现代码.
	CFile file;
	char szFilter[] = "文本文件(*.txt)|*.txt|所有文件(*.*)|*.*||";
	CFileDialog saveDlg(false,".txt", 0,
		OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
		szFilter);
	if (saveDlg.DoModal() == IDOK) {
		try
		{
			m_sFileName = saveDlg.GetPathName();
			file.Open(m_sFileName, CFile::modeCreate | CFile::modeWrite);
			UpdateData();
			file.Write(m_sEditTxt, m_sEditTxt.GetLength());
			file.Close();
			m_bChanged = FALSE;
			return true;
		}
		catch (CFileException *e)
		{
			CString str;
			str.Format("保存文件时出错。原因是:%s", e->m_cause);
			MessageBox(str);
			file.Abort();
			m_sFileName.Empty();
			return false;
		}
	}
	else{
		return false;
	}	
}


bool Cex2Dlg::Save()
{
	// TODO: 在此处添加实现代码.
	CFile file;
	if (m_sFileName.IsEmpty()) {
		char szFilter[] = "文本文件(*.txt)|*.txt|所有文件(*.*)|*.*||";
		CFileDialog saveDlg(false, ".txt", 0,
			OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,szFilter);
		if(saveDlg.DoModal()==IDOK)
			m_sFileName=saveDlg.GetPathName();
		else
			return false;
	}
	try
	{
		file.Open(m_sFileName, CFile::modeCreate | CFile::modeWrite);
		UpdateData();
		file.Write(m_sEditTxt, m_sEditTxt.GetLength());
		file.Close();
		m_bChanged = FALSE;
		return true;
	}
	catch (CFileException *e)
	{
		CString str;
		str.Format("保存文件时出错。原因是:%s", e->m_cause);
		MessageBox(str);
		file.Abort();
		m_sFileName.Empty();
		return false;
	}
	return false;
}


bool Cex2Dlg::SaveFile()
{
	// TODO: 在此处添加实现代码.
	if (!m_bChanged)
		return true;
	int iBtn;
	iBtn = MessageBox("文件的内容已经修改,需要保存吗?","保存文件",
		MB_YESNOCANCEL | MB_DEFBUTTON1 | MB_ICONINFORMATION);
	switch (iBtn)
	{
	case IDYES:
		if (Save())
			return true;
		else
			return false;
		break;
	case IDNO:
		return true;
		break;
	case IDCANCEL:
		return false;
		break;
	default:
		return false;
	}
}

为各类菜单项添加WM_COMMAND消息处理函数,添加的方法:
在这里插入图片描述
“添加事件处理程序”,在这里插入图片描述
点击确定即可。

参考代码如下:

void Cex2Dlg::OnFileNew()
{
	// TODO: 在此添加命令处理程序代码
	if (SaveFile()) {
		m_sEditTxt.Empty();
		UpdateData(FALSE);
		m_sFileName.Empty();
		m_bChanged = FALSE;
	}
}



void Cex2Dlg::OnFileOpen()
{
	// TODO: 在此添加命令处理程序代码
	if (SaveFile()) {
		CFile file;
		char szFilter[] = "文本文件(*.txt)|*.txt|所有文件(*.*)|*.*||";
		int iRead;
		char buf[BUFSIZ];
		CFileDialog openDlg(true, ".txt", 0,
			OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter);
		if (openDlg.DoModal() == IDOK)
		{
			m_sFileName = openDlg.GetPathName();
			file.Open(m_sFileName, CFile::modeRead);
			file.SeekToBegin();
			m_sEditTxt.Empty();
			do
			{
				memset(buf, 0, BUFSIZ);
				iRead = file.Read(buf, BUFSIZ - 1);
				m_sEditTxt.Append(buf);
			} while (iRead >= BUFSIZ - 1);
			file.Close();
			UpdateData(FALSE);
			m_bChanged = FALSE;
		}
	}

}


void Cex2Dlg::OnFileSave()
{
	// TODO: 在此添加命令处理程序代码
	Save();
}



void Cex2Dlg::OnFileSaveAs()
{
	// TODO: 在此添加命令处理程序代码
	SaveAs();
}



void Cex2Dlg::OnFileExit()
{
	// TODO: 在此添加命令处理程序代码
	if (SaveFile())
		AfxPostQuitMessage(0);

}


void Cex2Dlg::OnHelpAbout()
{
	// TODO: 在此添加命令处理程序代码
	CAboutDlg dlg;
	dlg.DoModal();

}

四、结果展示

程序界面
在这里插入图片描述
保存功能
在这里插入图片描述在这里插入图片描述

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值