=================================
(一) 用VB编写记事本
=================================
用VB做一个记事本实在不很复杂,我们完全可以通过向导来很方便地做出来。但本文只打算讨
论用手动方法制作记事本,旨在向VB初学者展示:学VB原来是如此容易!
通过阅读、研究本文并按本文所述进行尝试,初学者将学到很多东西,如怎样使用RichText控件
来打开和保存文件,怎样制作菜单、工具栏和状态栏以及如何对其编写代码等。
第一章 让我们的记事本马上运行
急于求成是初学者共有的心愿。那好,请按如下三个步骤做,我们的愿望立即就可以实现!
步骤一:绘制界面。
新建一个标准EXE工程,将其Caption属性改为“超级记事本”,点击Icon属性给它找个合适的
Icon图标。单击菜单“工程”-“部件”,在弹出的“部件”对话框里找到Microsoft RichText
Box 6.0和公共对话框Microsoft Common Dialog 6.0并选中它们,单击“确定”按钮。这时左
边的工具栏上出现了我们刚才新添的两个控件了。在窗体上绘制RichText Box和Commn Dialog
,其中RichText Box的大小和位置可不用理睬,我们将在代码中处理它,当然,有必要把它的
ScrollBar属性设为2-rtfVertical,这样在打开和编辑文件时垂直滚动条才可用。
步骤二:编辑菜单。
按Ctrl+E调出菜单编辑器,我们来做如下几个菜单:
一.文件菜单:
文件(第一层) mnuFile
新建(第二层) mnuNew
打开(第二层) mnuOpen
保存(第二层) mnuSave
- (第二层) mnuFileSep (分隔线)
退出(第二层) mnuExit
二.编辑菜单:
编辑(第一层) mnuEdit
复制(第二层) mnuCopy
剪切(第二层) mnuCut
粘贴(第二层) mnuPaste
- (第二层) mnuEditSep (分隔线)
全选(第二层) mnuSelecAll
三.搜索菜单:
搜索(第一层) mnuSearch
查找(第二层) mnuFind
查找下一个(第二层) mnuFindOn
四.帮助菜单:
帮助(第一层) mnuHelp
使用说明(第二层) mnuUsage
关于(第二层) mnuAbout
(注:各菜单项的快捷键请自行设置)
好了,其它的菜单项以后再根据需要添加。现在进入:
=======================================
步骤三:编写代码。
'声明查找变量
Dim sFind As String
'声明文件类型
Dim FileType, FiType As String
'初始化程序
Private Sub Form_Load()
'设置程序启动时的大小
Me.Height = 6000
Me.Width = 9000
End Sub
'设置编辑框的位置和大小
Private Sub Form_Resize()
On Error Resume Next '出错处理
RichTextBox1.Top=20
RichTextBox1.Left=20
RichTextBox1.Height = ScaleHeight-40
RichTextBox1.Width = ScaleWidth-40
End Sub
'新建文件
Private Sub mnuNew_Click()
RichTextBox1.Text = "" '清空文本框
FileName = "未命名"
Me.Caption = FileName
End Sub
'打开文件
Private Sub mnuOpen_Click()
CommonDialog1.Filter = "文本文档(*.txt)|*.txt|RTF文档(*.rtf)|*.rtf|所有文件(*.*)
|*.*"
CommonDialog1.ShowOpen
RichTextBox1.Text = "" '清空文本框
FileName = CommonDialog1.FileName
RichTextBox1.LoadFile FileName
Me.Caption = "超级记事本:" & FileName
End Sub
'保存文件
Private Sub mnuSave_Click()
CommonDialog1.Filter = "文本文档(*.txt)|*.txt|RTF文档(*.rtf)|*.rtf|所有文件(*.*)
|*.*"
CommonDialog1.ShowSave
FileType = CommonDialog1.FileTitle
FiType = LCase(Right(FileType, 3))
FileName = CommonDialog1.FileName
Select Case FiType
Case "txt"
RichTextBox1.SaveFile FileName, rtfText
Case "rtf"
RichTextBox1.SaveFile FileName, rtfRTF
Case "*.*"
RichTextBox1.SaveFile FileName
End Select
Me.Caption = "超级记事本:" & FileName
End Sub
'退出
Private Sub mnuExit_Click()
End
End Sub
'复制
Private Sub mnuCopy_Click()
Clipboard.Clear
Clipboard.SetText RichTextBox1.SelText
End Sub
'剪切
Private Sub mnuCut_Click()
Clipboard.Clear
Clipboard.SetText RichTextBox1.SelText
RichTextBox1.SelText = ""
End Sub
'全选
Private Sub mnuSelectAll_Click()
RichTextBox1.SelStart = 0
RichTextBox1.SelLength = Len(RichTextBox1.Text)
End Sub
'粘贴
Private Sub mnuPaste_Click()
RichTextBox1.SelText = Clipboard.GetText
End Sub
'查找
Private Sub mnuFind_Click()
sFind = InputBox("请输入要查找的字、词:", "查找内容", sFind)
RichTextBox1.Find sFind
End Sub
'继续查找
Private Sub mnuFindOn_Click()
RichTextBox1.SelStart = RichTextBox1.SelStart + RichTextBox1.SelLength + 1
RichTextBox1.Find sFind, , Len(RichTextBox1)
End Sub
'使用说明
Private Sub mnuReadme_Click()
On Error GoTo handler
RichTextBox1.LoadFile "Readme.txt", rtfText '请写好Readme.txt文件并存入程序所在文件
夹中
Me.Caption = "超级记事本:" & "使用说明"
Exit Sub
handler:
MsgBox "使用说明文档可能已经被移除,请与作者联系。", vbOKOnly, " 错误信息"
End Sub
'关于
Private Sub mnuAbout_Click()
MsgBox "超级记事本 Ver1.0 版权所有(C) 2001 土人",vbOKOnly,"关于"
End Sub
'设置弹出式菜单(即在编辑框中单击鼠标右键时弹出的动态菜单)
Private Sub RichTextBox1_MouseDown(Button As Integer, Shift As Integer, X As
Single, Y As Single)
If Button = 2 Then
PopupMenu mnuEdit, vbPopupMenuLeftAlign
Else
Exit Sub
End If
End Sub
'防止在切换输入法时字体自变(感谢王必成先生提供此方案)
Private Sub RichTextBox1_KeyUp(KeyCode As Integer, Shift As Integer)
If KeyCode = vbKeySpace Then
RichTextBox1.SelFontName = CommonDialog1.FontName
End If
End Sub
至此,我们的记事本可以编译使用了。点击菜单“文件”-“生成XXX.EXE”,回到桌面运行我
们的记事本看看,是不是颇有成就感?
当然,这样的记事本还比较粗糙,我们还需要做些工作,请看下一章。
========================================================
第二章 美化程序界面
多数字处理软件都有工具栏和状态栏。工具栏和状态栏除了能美化我们的程序使其更具有专业
性质外,还给用户带来操作上的便利。现在我们就来做一做这两样东西。
一.工具栏
(一)制作工具栏
单击“工程”-“部件”,选中Microsoft Windows Common Control 6.0并确定。这时,我们要
用到的控件就出现在左边的工具栏上了。
要做工具栏,首先需要一个叫ImageList的控件来装载图像。在程序界面上添加它,然后右键单
击此控件,左键单击“属性”,弹出“属性页”对话框的“图像”,再单击“插入图片”就可
以一次性装载图片了(如不满意,以后还可以添加)。图片可在C:\Microsoft Visual
Studio\Common\Graphics\Bitmaps\TlBr_W95下选择(这里假设你的VB安装在C盘下)。注意了:
在插入图片时给每一张图片注明关键字,以便在引用图片时不至于混乱。如插入“新建”的图
片,我们在“关键字”栏注明“New”。
图片有了,接下来在程序界面添加工具栏(ToolBar)。添加后工具栏就出现在菜单下面,右键单
击它,选择“属性”,在弹出的“属性页”对话框中的“通用”项作些设置,主要如下两项:
1.“图像列表”:选择ImageList1
2.“样式”:根据喜爱选择1-trbStandard或者2-trbFlat
继续点击“属性页”的“按钮”选项,插入若干按钮。按钮有多种样式,请根据需要设置。这
里请一定注意:每一个与用户操作有关的按钮都必须注明关键字、装载图片,如“新建”按钮
,在“关键字”项注明“新建”,在“图像”项键入“New”(即ImageList1中的图片关键字)
,需要的话还可以在“工具提示文本”项填入适当的提示语。
(二)编写工具栏的按钮代码
工具栏按钮的代码编辑很简单,可以按照下面的格式去编写:
Private Sub ToolBar1_ButtonClick(ByVal Button As MSComctlLib.Button)
On Error Resume Next '出错处理
Select Case Button.Key '按关键字选择
Case "新建"
mnuNew_Click '等于菜单项“新建”被单击
Case "打开" '等于菜单项“打开”被单击
mnuOpen_Click
'......(继续编写其它按钮的代码)
End Select
End Sub
完成后试运行一下我们的程序,我们发现,有了工具栏之后,程序变得漂亮多了,只是有一个
问题:打开一个较长的文档后,编辑框的下拉滚动条向上的箭头不见了。原因是:工具条占用
一定的空间。解决方法:将“设置编辑框的位置和大小”中的RichTextBox1.Top = 20 和
RichTextBox1.Height = Me.ScaleHeight - 40分别改为RichTextBox1.Top = 380,
RichTextBox1.Height = Me.ScaleHeight - 400即可。
二.状态栏
(一)制作状态栏
状态栏的英文名字叫StatusBar,在窗体上添加它后会默认出现在窗体的最下方。用鼠标右键点
击它,调出“属性页”对话框,单击“窗格”项,插入一些窗格,可以将各个窗格的“样式”
设置为:
0-sbrText 显示文本,需编写代码
1-sbrCaps 显示大小写状态,无需编程
2-sbrNum 显示NumLock键开关状态,无需编程
3-sbrIns 显示Insert键状态,无需编程
4-sbrScr1
5-sbrTime 显示时间,不编程时时间不会随系统时钟变化
6-sbrDate 显示日期,无需编程
注意:加进状态栏后需将Form_Resze中的RichTextBox1.Height = Me.ScaleHeight - 400改为
RichTextBox1.Height = Me.ScaleHeight - 600。
(二)状态栏根据其“样式”属性决定用不用编写代码(如上文所述)。下面举些例子,读者可以
认真揣摩,从而达到举一反三的效果。
例一:用户选取了“新建”后,让第一个窗格显示:“目前状态:正在打开文件《……》”。
请将下面代码写进“打开”菜单里面:
StatusBar1.Panels(1).Text = "目前状态:正在打开文件" & "《"
&CommonDialog1.FileTitle & "》"
例二:让第三个窗格显示时间并让时间跟随系统时钟变化。
首先,给程序加一个Timer控件,将其Interval属性设为1000。然后:
在Form_Load过程加入:StatusBar1.Panels(1).Text = Time;然后给Timer控件编写代码:
Private Sub Timer1_Timer()
If StatusBar1.Panels(3).Text <> CStr(Time) Then
StatusBar1.Panels(3).Text = Time
End If
End Sub
例三:当编辑框的文本发生变化时让第一个窗格显示:“正在编辑文档:文件名”。
Private Sub RichTextBox1_Chang()
StatusBar1.Panels(1).Text = "正在编辑文档:" & CommonDialog1.FileName
End Sub
辛苦了那么久,我们现在已经拥有一个象模象样的记事本了。这个记事本由于用了RichText控
件,理论上它能打开和编辑任意大的文档,使用起来的确比Windows自带的记事本方便得多。当
然,还有一些其它的功能需要添加和完善,这就靠你慢慢去完成了。
============================================
(二) 用VB实现象Windows记事本的一些功能
============================================
内容:讨论如何在用VB编写的记事中实现自动将日志添加到文档尾部、判断保存还是另存为、
确认文件是否需要保存等功能。
Windows自带的记事本即Notepad有一些功能还是颇具吸引力的,比如自动在特定的文档尾部加
入计算机时钟的时间和日期,截取已经打开或者保存了的纯文档名[见记事本的标题栏]以及搜
索等,给用户带来许多方便。本文就TextBox控件讨论如何实现这些功能。
一、将日志添加到文档
在Windows中,如果文档的第一行最左边有".LOG"字样,那么每次用记事本打开此文时,记事本
会自动在文档尾部加入时间日期。
".LOG"共占四个字节,又置于文档第一行顶格处,因此可以用VB的Left函数来读取这个字符串
,如有,则用CStr函数来自动添加时间和日期。
我们可以在打开文件的程序加入以下代码:
DimaAsString
a=Left(Text1.Text,4)'取得头4个字节
Ifa=".LOG"Then'若有则:
Text1.SelStart=Len(Text1.Text)'光标移到文件尾
Text1.SelText=vbCrLf&CStr(Now)'加入换行和时间
Else'若无,退出过程
ExitSub
EndIf
这样,我们用VB编写的记事本就和Windows的Notepad一样具有自动将日志添加到文档的功能了
。
二、截取FileName中的纯文档名
如若我们用Notepad打开文件D:\VBFILE\NEW\Textbox控件用法举例.txt,Notepad的标题栏的
Caption变为:TextBox控件用法举例-记事本。这个,我们用VB来完成还是比较容易的。
为了方便在程序的各处使用,我们不妨编写一个截取字符串的函数:
'截取纯文栏名函数
FunctionGetFileTitle(OldStrAsString)AsString
OnErrorResumeNext
DimnAsInteger,mAsInteger'声明字符串变量
DimiAsString,rAsString
DimpAsInteger
i="\"'要查找的指定字符
Forn=1ToLen(OldStr)'用Len函数计算已知字符串的字节数
m=InStrRev(OldStr,i,-1)'"\"所在的位置(其中的-1是默认的)
Nextn'找下去!
'截取最后一个"\"后面的字符串
r=Right(OldStr,Len(OldStr)-m)'获取Title
p=InStrRev(r,".",-1)'"."所在位置
GetFileTitle=Left(r,p-1)'去掉后缀
EndFunction
现在我们来调用这个函数以获取纯文档名:
DimMyStrAsString,ResultAsString
MyStr="d:\games\6do\oldtucom\heart\Story001.TXT"
Result=GetFileTitle(MyStr)
Me.Caption=Result&"-记事本"
执行之,则窗体的标题变为:Story001-记事本,与NotePad的效果无异!
三、判断保存还是另存为
通常,我们通过使用CommonDialog控件来保存文件,不过,VB的公共对话框提供的ShowSave其
实只是SaveAs,如不作处理则在运行程序中每次保存文件都会跳出另存为对话框,为避免这种
不便,我们可以声明一个窗体级或模块级的文件名变量[类型:String],并在每一次相关操作
中给此变量赋值且保存于内存之中,然后在保存文件时给予识别,如变量不为空则直接保存文
件,否则调出另存为对话框,让用户输入文件名。
试看:
DimSaveFileNameAsString'窗体或模块级变量
'在打开文件事件加入:
SaveFileName=CommonDialog1.FileName
'保存文件
IfSaveFileName<>""Then
OpenSaveFileNameForInputAs#1
Print#1,Text1.Text
Close#1
Else
'此处写上用公共对话框保存文件的代码
EndIf
这样,我们的记事本变得象Notepad一样聪明了:那令人讨厌的另存为对话框不会总是弹出来了
!
四、从“我的电脑”拖动文件并打开
当从“我的电脑”拖动文件到Notepad编辑界面,文件格式正确的话则自动打开。在VB中,我们
可以这样处理:
1.在Form_Load事件中加入:
Text1.OLEDropMode=1'令Text1成为可接受文件拖放的OLE容器
2.采用OLE技术实现拖放并打开功能:
'当文件拖到文本框
PrivateSubText1_OLEDragOver(dataAsDataObject,effectAsLong,_
ButtonAsInteger,ShiftAsInteger,XAsSingle,YAsSingle,_
StateAsInteger)
Ifdata.GetFormat(vbCFFiles)Then'如是文件则显示可放下图标
effect=vbDropEffectCopyAndeffect
Else'否则显示不可放下图标
effect=vbDropEffectNone
EndIf
EndSub
'当文件被放下
PrivateSubText1_OLEDragDrop(dataAsDataObject,effectAsLong,_
ButtonAsInteger,ShiftAsInteger,XAsSingle,YAsSingle)
DimsFileName$AsString'放下的文件名变量
'检查放下的东西是不是文件名
Ifdata.GetFormat(vbCFFiles)=TrueThen'如是则sFileName=data.Files(1)'只读取第一个文件
信息
OnErrorResumeNext'出错处理:不予理睬
'在TextBox中打开文件
OpensFileNameForInputAs#1
IfmnuComb(0).CheckedThenText1.Text=Text1.Text&StrConv(InputB$_
(LOF(1),1),vbUnicode):MyLen=Len(Text1.Text)
IfmnuComb(1).CheckedThenText1.Text=StrConv(InputB$(LOF(1),1),_
vbUnicode):MyLen=Len(Text1.Text)
Close#1
EndIf
EndSub
注意:可要记得写出错处理代码,否则……你知道的。
五、确认文件是否需要保存
从当前状态退出程序或转移到其它状态如新建文件、打开文件等,如若当前文件已经改变而用
户又没有保存,应该提醒用户要不要保存已做的改变。这一点Notepad是有的,在VB中该怎么办
呢?
我们可以声明一个布尔变量,用来记录文本框是否有了改变,并利用TextBox控件的Change事件
来监视文本框的状态,若有变化,则改变变量值。
1.模块或窗体级声明:
DimAskAsBoolean
2.在Form_Load中:
Ask=False'初值
3.在Text1_Change中加入:
Ask=True
4.退出程序或转移到新的状态时:
IfAsk=Truethen
DimFlagAsInteger,MsgStrAsString
MsgStr="文件已经改变,是否要存盘?"'提示语
Flag=MsgBox(MsgStr,vbYesNoCancel,"提示")'给予提示
IfFlag=vbYesThenSaveIt'选择了确定则保存之:这里假定已有了一个保存文件的子过程SaveIt
IfFlag=vbCancelThenExitSub
IfFlag=vbNoThenCancel=False
EndIf
'......这里写上其它主要处理事件代码
Ask=False'操作结束令其为假,以免老提示
六、搜索功能
Notepad提供了查找和继续查找字符串的功能。VB中,控件TextBox并不象RichTextBox控件那样
提供了Find方法。这样我们只好求助于VB的一些内部函数了。以下是笔者自行编写的一个专用
于TextBox控件中查找字符串的函数,函数中用上了VB的InStr等内部函数,这里就不多作解释
了。
'查找字符串函数[可置于模块或窗体级中]
FunctionFindMyStr(MyNameAsTextBox,SearchStrAsString)AsInteger
DimWhere'获取需要查找的字符串变量
DimStartAsInteger
MyName.SetFocus'文本框获得焦点,以显示所找到的内容
Start=MyName.SelStart MyName.SelLength 1
Where=InStr(Start,MyName.Text,SearchStr)'在文本中查找字符串
IfWhereThen
'若找到则设置选定的起始位置并使找到的字符串高亮
'FindStr=Where-1
MyName.SelStart=Where-1
MyName.SelLength=Len(SearchStr)
'否则给出提示
Else:MsgBox"未找到所要查找的字符串。",vbInformation,"提示"
EndIf
EndFunction
有了这个函数,我们可以这样查找和继续查找字符串:
1.在窗体级声明:
DimSearchAsString'声明要查找的变量
2.第一次查找:
DimsFindAsString
'若光标不在开头处则令其回到开头
IfText1.SelStart<>0ThenText1.SelStart=0
Search=InputBox("请输入要查找的字词:")
sFind=FindMyStr(Text1,Search)
3.继续查找[就简单了]:
DimsFindAsString
sFind=FindMyStr(Text1,Search)
这样,搜索功能就基本具备了,如再提供向上查找功能,则更令人满意。
以上是笔者在学习、探索中的一些体会,在Win98、VB中文企业版6.0下调试成功。如有不妥当
之处,敬请各位高手斧正!