一、程序界面设计
设计目标:
(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();
}
四、结果展示
程序界面
保存功能