发信人: chenjz(不再哭傲江湖)
整理人: cobe(2001-01-19 09:20:28), 站内信件
|
走近编程通过实例学VB(五)
大家好,在本章中,我们需要完成文本编辑器编辑菜单中的最后一个功能项:替换。
我们可以首先打开UltraEdit,打开一篇文章,然后按快捷键Ctrl+R打开替换对话框执行一次替换操作,可以看到如果点击其中的Replace All按钮,讲会替换文档中的所有符合条件的字符串。而点击Start按钮,就会弹出一个替换工具栏,让用户可以选择一次替换一个字符串或者跳过到下一个。在我们的程序中也讲实现这两种功能。
首先来实现全部替换功能,点击VB菜单的“Project|Add Form”项添加一个窗体到工程中,将Name属性更改为frmReplace,保存窗体。然后在窗体中添加两个TextBox控件,一个用于输入查找文本,Name属性设置为txtFind;另一个用于输入替换文本,Name属性设置为txtReplace。添加三个CommandButton控件,一个用于执行替换操作,Name属性设置为cmdStart,Caption属性设置为:开始[&S];一个用于执行全部替换操作,Name属性设置为cmdAll,Caption属性设置为:全部替换[&A];一个用于退出替换对话框,Name属性设置为cmdCancel,Caption属性设置为:取消,Cancel属性设置为True。窗体的界面如图1所示。
接下来打开MDIForm1,在菜单项mEditReplace的Click事件中添加如下代码:
With frmReplace
.Show 0
If Me.ActiveForm.FindStr="" Then
.txtFind.Text=Me.ActiveForm.RichTextBox1.SelText
Else
.txtFind.Text=Me.ActiveForm.FindStr
End If
End With
Me.ActiveForm.RichTextBox1.SelAlignment=0
上面的代码执行显示窗体frmReplace的工作。
打开Module,在其中加入下面一句定义:
Public strReplace As String
打开frmReplace的代码窗口,添加如下的查找替换子程序:
Sub ReplaceAll()
Dim L1,L2,L3,Count As Long
With MDIForm1.ActiveForm.RichTextBox1
利用API获得当前插入点位置
SendMessageByRef .hwnd,EM_GETSEL,L1,L2
L3=L2
While .Find(txtFind.Text,L2)>-1
.SelText=strReplace
将查找位置移到替换完成的文本后面
L2=L2+LenB(StrConv(strReplace,vbUnicode))
Count=Count+1
DoEvents
Wend
将查找位置移动到文本开头。
L2 = 0
While ((.Find(txtFind.Text,L2)>-1) And (L2 .SelText=strReplace
L2=L2+LenB(StrConv(strReplace,vbUnicode))
Count=Count+1
DoEvents
Wend
End With
MsgBox "共执行" & Str(Count) & "个替换"
End Sub
Private Sub cmdAll_Click()
If txtFind.Text="" Then
Beep
txtFind.SetFocus
Exit Sub
End If
strReplace=txtReplace.Text
ReplaceAll
MDIForm1.ActiveForm.FindStr=txtFind.Text
Me.Hide
End Sub
Private Sub cmdCancel_Click()
Me.Hide
End Sub
其中子程序ReplaceAll执行全部替换操作,其中执行了两遍的While…Wend循环,在第一个循环内执行从当前编辑窗口的插入点向下查找并执行替换直到找不到查找字符串。第二个循环从文档开始查找并执行替换直到找不到查找字符串或者查找到第一个While…Wend循环开始的位置。执行完毕后弹出对话框显示执行了多少个替换。在全部替换功能的实现使用了While…wend循环,使用这一类的循环操作必须十分的小心,如果退出循环的条件设定不当,很容易就会陷入无限循环中,如果While的条件比较复杂的话,最好加入一个计数器(例如你判断你的While…Wend循环的次数不会超过1000次,则可以定义一个变量,每次循环加1,当大于5000时退出循环)。另外在循环中加入了一个DoEvents语句。该语句的作用是转让控制权,在一个循环执行一次以便让操作系统处理其它的事件。这样,当在执行一个耗时比较长的操作(例如搜索文件)时,可以使系统可以进行其它操作或者用户终止操作而不会看起来象死机了一样。
现在执行一下程序,打开一个文档,然后按快捷键Ctrl+R调用查找窗口,分别输入查找和替换字符串,然后点击全部替按钮,看看程序的执行效果。
下面实现的是替换功能,同全部替换不同,替换功能应该可以让用户选择替换或者跳过替换。象UltraEdit中的那样,首先要建立一个替换窗口。点击VB菜单的“Project|Add Form”项添加一个窗体到工程中,将Name属性更改为frmFR,将BorderStyle属性设置为3 。然后添加4个CommandButton控件,分别用于执行替换、查找下一个、全部替换和取消操作,Caption属性分别设置为替换[&R]、查找下一个[&F]、全部替换[&A]、取消。Name属性分别设置为cmdReplace、cmdFindNext、cmdAll、cmdCancel 。其中cmdReplace的Default属性设置为True,cmdCancel的Cancel属性设置为True。窗体的外观如图2所示。
现在工程列表中的窗体和模块列表应该如图3所示。
打开窗体frmReplace,双击开始按钮,在cmdStart_Click事件中添加如下代码:
If txtFind.Text="" Then
Beep
txtFind.SetFocus
Exit Sub
End If
strReplace=txtReplace.Text
MDIForm1.ActiveForm.FindStr=txtFind.Text
MDIForm1.FindStrRTF MDIForm1.ActiveForm.RichTextBox1
If MDIForm1.ActiveForm.RichTextBox1.SelText="" Then
Exit Sub
End If
Me.Hide
frmFR.Show 0
在上面的程序中,当用户点击开始按钮后,程序首先判断查找文本框内的文本是否为空,然后执行FindStrRTF操作从活动编辑窗口的插入点位置开始查找字符串,查找到以后显示frmFR窗体并隐藏自身。
打开frmFR窗体,打开窗体的代码窗口。然后在通用区域添加如下代码:
Private Sub cmdAll_Click()
Me.Hide
frmReplace.ReplaceAll
End Sub
Private Sub cmdCancel_Click()
Me.Hide
End Sub
Private Sub cmdFindNext_Click()
MDIForm1.FindStrRTF MDIForm1.ActiveForm.RichTextBox1
End Sub
Private Sub cmdReplace_Click()
With MDIForm1.ActiveForm.RichTextBox1
If .SelText<>"" Then
.SelText=strReplace
MDIForm1.FindStrRTF MDIForm1.ActiveForm.RichTextBox1
End If
End With
End Sub
分析上面的程序,在cmdReplace的Click事件中,由于在frmReplace的cmdStart的Click事件中执行了一次查找操作,所以第一步就是替换查找到的字符串,然后再执行FindStrRTF来查找下一个字符串。
在运行程序之前打开Form1,点击RichTextBox1,在属性栏中将HideSelection属性设置为False,改属性决定RTF控件在失去焦点后是否隐藏选择的文本,如果设置为False,即使RTF控件失去焦点,被选择的文本仍然被高亮显示。
运行程序,打开一个文件,然后点击菜单中的替换项调用查找替换窗口,分别输入查找和替换字符串,然后点击开始按钮,在替换窗口中分别点击替换、查找下一个按钮,看看程序的执行效果。程序执行的效果如图4所示。
最后介绍一下如何实现窗口菜单中的层叠和平铺功能,MDI窗口提供了Arrange方法用于排列MDI子窗口。打开MDIForm1,点击窗口菜单“窗口|层叠”,在mWindowCa_Click事件中添加下面一句代码:Me.Arrange 0
点击窗口菜单“窗口|平铺”,在mWindowTitle_Click事件中添加下面一句代码:Me.Arrange 1
本章就讲到这里,在下一章内,我们将完善程序使其成为一个基本可用的编辑器并向大家简单的介绍一下关于Windows API调用方面的问题。
本章功课:运行程序,打开不同的文件并反复执行替换操作,看看替换部分的程序在界面操作的实现以及功能上面有没有不完善的地方,考虑并完善程序。(未完待续)(长沙 陈锐)
---- 我能翻译善写作熟电脑会说话可是为什么没工作?
|
|