荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: jek (好好学习天天向上), 信区: Program
标  题: 用C++ Builder3 制作NotePad(记事本)
发信站: BBS 荔园晨风站 (Sat Mar 11 14:34:15 2000), 转信

用C++ Builder3 制作NotePad(记事本)


启动C++ Builder3后,在File菜单中选New APPlication来建立一个新程序。这时,显示在
屏幕中间的窗口的标题是Form1,这个窗口是程序的主表单(就是主窗口的意恩),它将
在程序启动时自动显示。而以后再创建的表单(Form)一般需要用Show()方法(Method)
来显示。和组件一样,系统为第一个表单起名为Form1,以后的表单起名为Form2、Form3
等等,标题(Caption)也是如此。
   当然,你可以将它们改成你喜欢的名字。我们先来把Form1的名字(Name)属性设为
MainForm,把MainForm的标题(Caption)属性设为“Untited.txt--我的记事本”。接着
可以用鼠标拖动窗口的位置和改变窗口的大小。以上的这些工作,几乎每个程序都需要如
法炮制一番。
   随后,我们要开始NotePad的编程工作了。知己知彼,百战不殆,先来分析一下
MicroSoft NotePad的结构。其实NotePad是附件里最简单的程序了,它的主窗口中只包含
一个占据全部用户区域(Client Area)的多行的编辑控制(Edit)。由于编辑控制最多
容纳64KB文字(Windows95),所以NotePad只能打开小于64KB的文件。好,我们来依样画
葫芦,选择Standard中的多行编辑(Memo)组件(而不是单行编辑组件)。
   放入表单中,将多行编辑Memo1的Align属性设为alClient,这时Memo1撑满了整个窗口
,Memo1中显示的是Memo1。选择Memo1的Lines属性,[TString]后面出现了一个按钮。
   单击该按钮,将出现一个设置Lines属性的对话框,其中第一行便是“Memo1”。多行
编辑(Memo)组件的Lines属性在设计时(Design Time)设定的内容将在该窗口创建时自
动显示。由于我们不需要显示什么,所以把“Memo1”擦掉,选OK退出。你一定想看看目
前的效果,运行一下吧。编译……连接……启动程序……怎么样,是不是和NotePad一模
一样,能打字、删字、删行,还能使用右键菜单来复制(copy)和粘贴(paste)。
   本来就是嘛,用一样的编辑控制,不一样才怪呢。哎,不对,好像字体小了点,而且
没有滚动条。没有关系,关闭程序回到C++ Builder3中,先修改Memo1的字体(Font)属
性,选择system字体(当然你爱选什么字体都可以),然后设置滚动条(ScrollBars)属
性,选择ssBoth(两根滚动条都要)。在这些改动之后,先别急着运行,windows的程序
没菜单是不行的。在C++ Builder中,菜单也是组件之一。选择Standard中的主菜单
(MainMenu)组件放入表单中。主菜单(MainMenu)组件显示为一个图标。顺便提一句菜
单,对话框或系统功能之类组件属于非可视组件(nonvisual components),它们的工作
基本不是用来满足视觉的,或者在程序运行时根本就看不见(相对于界面上可视组件来说
),因此你可以将非可视组件放在表单中的任意位置。
   接下来的工作是制作菜单,双击主菜单MainMenu1的图表,会弹出菜单编辑窗口,开始
时是一个空菜单。按右键会弹出一个菜单(不是我们要做的菜单),其中:
Insert(添加一个菜单项,按Insert键完成相同的功能)
Delete(删除一个菜单项,按Delete键完成相同的功能)
Create SubMenu(添加一个子菜单,按Ctrl + →键完成相同的功能)
Select Menu(选择一个菜单,用来关闭当前编辑的菜单并选择另一个菜单来编辑)
Save as Template(将当前菜单保存为模板,供以后使用)
Insert From Template(将已有的菜单模板加入当前菜单)
Delete Template(删除菜单模板)
Insert From Resource(从资源文件中取得菜单加入当前菜单)
   制作“我的记事本”的菜单有一种偷懒的方法,就是照抄Microsoft记事本的菜单。你
可以用BC5.02的IDE打开Notepad.exe(先把打开文件对话框中的Viewer设为
Edit Resource,再把文件类型设为Exe cutable(*.exe),这样才是以编辑资源的方式
打开EXE文件,否则默认的打开方式是Debug调试程序),将里面的菜单导出以RC(资源脚
本)方式存盘,然后用Insert From Resource导入该菜单;一共用不了2分钟。
   还有一种方法就是自己一项一项慢慢地做。当然,不管你用什么方法,最后都要做出
菜单来才能继续下面的工作。下面附上从Windows NT4.0中Notepad导出的菜单的资源脚本
menu.rc,把下面的文件以menu.rc存盘就能用C++ Builder3来导入了:
1 MENU
{ POPUP "文件(&F)"
  { MENUITEM "新建(&N)", 9
    MENUITEM "打开(&O)...", 10
    MENUITEM "保存(&S)", 1
    MENUITEM "另MENUITEM "撤消(&U)\tCtrl+Z", 25
    MENUITEM SEPARATOR
    MENUITEM "剪切(&T)\tCtrl+X", 768,GRAYED
    MENUITEM "复制(&C)\tCtrl+C", 769, GRAYED
    MENUITEM "粘贴(&P)\tCtrl+V", 770,GRAYED
    MENUITEM "删除(&L)\tDel",771, GRAYED
    MENUITEM SEPARATOR
    MENUITEM "全部选定(&A)", 7
    MENUITEM "时间/日期(&D)\tF5",12
    MENUITEM SEPARATOR
    MENUITEM "自动换行(&W)", 27
    MENUITEM "设置字体(&F)...", 37
  }
  POPUP "搜索(&S)"
  { MENUITEM "查找(&F)...", 3
    MENUITEM "查找下一个(&N)\tF3", 8
    MENUITEM "替换(&R)"', 40
  }
  POPUP "帮助(&H)"
  { MENUITEM "帮助主题(&H)", 5
    MENUITEM SEPARATOR
    MENUITEM "关于记事本(&A)...",11
  }
}
关于菜单,还有两点要提:
1.一般没有必要去改动菜单项的Name属性,使用系统给出的默认名就可以了。
2.以“-”为标题的菜单项即是菜单分割条,而菜单项的Break属性提供的分割则是一种很
奇怪的样子--“垂直分害条”(群山笑:这个名词是我自已加上的)。
   OK,到此为止,界面部分的工作已经全部完成了,接下来便是代码部分的编写。首先
要做的就是打开文件和存盘的工作。我们来建立一个char *UserFileNa对话框的,当然用
Windows API也能实现此功能,这里将使用SaveDialog组件。将SaveDialog1的
DefaultExt(默认的扩展名)属性设为.txt,这表示如果用户没有加扩展名,系统会自动
加上“.txt”。按Filter属性后的[…]按钮,在弹出的对话框中输入“文本文件”
“*.txt”“所有文件”“说项“另存为(A)...”,这时C++ Builder3会自动切换到代
码编辑区,而光标停在一个函数的开头。在该例中菜单项“另存为(A)…”的名字属性
是A1,所以这个函数的名字是A1Click(TObject * Sender),表示用户选择(Click)这
个菜单项而执行的函数。我们所要做的是弹出Save As对话框来获得用户输入的文件名,
并将这个文件存盘。所以在这个函数里加如下的语句:
if(!SaveDialog1->Execute()) return; //如果用户选择了取消,我们就return
UserFileName = SaveDialog1 -> FileName.c_str();
/ * FileName保存了用户输入的文件名,但是AnsiString类型地将编辑控制中的内容存盘
 */
   类似地,我们再来处理打开文件的工作。首先,在表单中放置一个OpenDialog组件,
DefaultExt和Filter属性同SaveDialog1,将Options属性中的ofFileMustExist(文件必
须存在)设为true。然后在表单编辑区中的菜单中选菜单项“打开(O)...”,在代码编辑
区中输入如下语句。
if(!if_saved)
if(Application ->MessageBox("文件还未保存,是否要保存?","我的记事本",
MB_OKCANCEL+MB_DEFBUTTON1+MB_ICONWARNING)==ID_OK) S1Click(NULL);
/ * 如果文件没有保存,我们得先征求用户是否要保存文件。s1Click()是“保存(s)”菜
单项的处理函数(就是接下来处理的菜单项),“保存(S) ”菜单项的工作就是将文件存
盘,所以我们没有必要写重复的代码,而只要直接调用该函数就可以了。注意,如果你的
“保存(S)”菜单项的名字属性不是S1而是其他,那么这个函数的名字也会有所不同,但
总是“名字”+Click()
*/ if(!OpenDialog1->Execute())return;
UserFileName=OpenDialog1->FileName.c_str();
Memo1->Lines->LoadFromFile(UserFileName);
sprintf(title_buf,"% s - 我的记事本", UserFileName);
Caption = title_buf;
(为节省篇幅,以下凡是重复的操作描述省略)
   处理“保存(S)”菜单项,输入:
Memo1->Lines->SaveToFile(UserFileName);
If_saved=TRUE;
sprintf(title_buf,"% s - 我的记事本", UserFileName)";
Caption = title_buf;
   处理“新建(N)”菜单项,输入如下语句:
lf(!If_saved)
if(Application ->MessageBox ("文件还未保存,是否要保存?","我的记事本",
MB_OKCANCEL+MB_DEFBUTTON1+MB_ICONWARNING)==ID_OK)S1Click(NULL);
sprintf(UserFileName,"Untitled.txt");
sprintf(title_buf, "% s - 我的记事本-未存盘",UserFileName);
Caption=title_buf;
Memo1->Lines->Clear(); //将编辑控制中的内容清空

随后,我们要处理Memo1的OnChange事件(Events)。一旦编辑控制中的内容有改变,
Memo1就将产生OnChange事件,这时需要将If_saved置为FALSE,表示文件已经改动过了,
并在标题上显示“未存盘”。在对象观察器中选Memo1,再单击下面的Events,将列出许
多事件,第一个就是OnChange,双击后面的编辑框,后面的操作和处理菜单项是一样的
(其实前面处理的菜单项就是处理菜单的OnClick事件),输入:
If_saved=FALSE;
sprintf(title_buf,"% s -我的记事本-未存盘", UserFileName);
Caption=title_buf;
   随后处理MainForm的OnClose事件,输入:
//OnClose事件在关闭窗口时产生,需要做一些收尾工作
if(!If_saved)
if(application->MessageBox("文件还未保存?","我的记事本",
MB_OKCANCEL+MB_DEFBUTTON1+MB_ICONWARNING)==ID_OK)S1Click(NULL);
   最后,处理“退出(X)”菜单项,输入如下语句:
if(!If_saved)
if(application->MessageBox("文件还未保存,是否要保存?","我的记事本",
MB_OKCANCEL+MB_DEFBUTTON1+MB_ICONWARNING)==ID_OK)S1Click(NULL);
Application->Terminate(); //程序结束
   到此为止,终于小功告成了,快把项目保存下来吧。在File菜单中选
Save Project As…,首先弹出的对话框要求输入表单的文件名(不能和表单的名字属性相
同),我们就输入Main。随后弹出的对话框才是要求输入项目(Project)的文件名,该文
件名也就是exe文件的名字,我们输入NotePad。保存后再选Project菜单里的Make
NotePad,或按Ctrl+F9,就会产生一个NOtePad.exe,这就是我们自己做的记事本,目前
它已经能打开文件、编辑并保存。你一定发现菜单中还有许多功能尚未实现,这就是我只
说小功告成的原因,不过下次我们会完成它。
   附件中除了记事本(NotePad),还有一个写字板(WordPad)。它们最大的区别在于
前者使用的是编辑控制(Edit),而后者使用的是Rich Edit控制(有些书翻译成丰富文
本控制)。与编辑控制相比,Rich Edit除了能给文本加上各种修饰,还支持简单的对象
链接和嵌入技术(Object Linking and Embedding)。
   此外,Microsoft Win32 SDK的文档中说Rich Edit控制能接受的文本大小将只受内存
大小的限制,这比编辑控制的64KB强多了。当然,效率又是另一个问题。我曾试图用写字
板(WordPad)打开一个15MB的文件,硬盘读了10多分钟还没结果,只能按Reset重新启动
了(我可有64MB内存哦)。自然使用Rich Edit控制也比编辑控制难的多。在以后讲到
RichEdit组件时,详细讲述它的用法。


--
※ 来源:·BBS 荔园晨风站 bbs.szu.edu.cn·[FROM: 192.168.1.118]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店