65.9K
CodeProject 正在变化。 阅读更多。
Home

围绕扩展的 RichTextBox 控件构建一个简单的文字处理器

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.70/5 (40投票s)

2006年9月13日

18分钟阅读

viewsIcon

344674

downloadIcon

9896

本文介绍了一种围绕扩展版 RichTextBox (RTB) 控件构建简单文字处理器 的简便方法。

Screenshot

引言

本文介绍了一种围绕扩展版 RichTextBox (RTB) 控件构建简单文字处理器 的简便方法。微软提供了一个扩展版的 RTB 控件,极大地简化了打印控件文本或 RTF 内容的要求。本文和示例应用程序将使用这个扩展版的 RTF 控件来演示以下文字处理器相关功能:

  • 打开文本、RTF、HTML 或其他文本文件到 RTB 控件
  • 从 RTB 控件保存文本、RTF、HTML 或其他文本文件
  • 页面设置对话框控件的实现
  • 打印预览对话框控件的实现
  • 打印对话框控件的实现
  • 为 RTB 控件中的选中文本或 RTF 设置字体属性
  • 在 RTB 控件中搜索并高亮显示文本
  • 在 RTB 控件中搜索并替换文本
  • 为 RTB 的内容部分添加缩进
  • 为 RTB 的内容部分添加项目符号
  • 在 RTB 中实现撤销/重做功能
  • 在 RTB 控件中实现全选、剪切、复制和粘贴
  • 将图像嵌入到 RTB 控件中
  • 设置页面和字体颜色
  • 在 RTB 控件中实现对齐选项

尽管这个项目不会让你成为 MS Word 的替代品,但它是一个不错的简易文字处理器,你可能会找到它的用途。我一直保留着一个这样的程序,并经常根据需要进行定制,例如提供一个自定义工具来查看报告、错误日志等内容,当你希望将此功能集成到产品中,而不是弹出到一个记事本文件中时。这样做可以让我控制应用程序的外观、窗体标题栏的标题等。

图 1:正在使用的编辑器应用程序

入门

要开始,请解压缩附件,并在 Visual Studio 2005 中加载解决方案。检查解决方案资源管理器,并注意项目中包含的文件。

图 2:解决方案资源管理器显示项目文件

首先,请注意解决方案中包含两个独立的项目。第一个项目是一个类库,名为“ExtendedRichTextBox”。该库包含一个单一的控件类,“RichTextBoxPrintCtrl”。这个控件类由微软提供,作为基本 RichTextBox 控件的替代品;该类继承自 RichTextBox 控件类,但在此基类上增加了对打印控件内容的支持。该控件提供的方法比传统的基于图形上下文操作的方法要简单得多。

第二个解决方案是编辑器应用程序本身(RichTextEditor)。该应用程序使用扩展的富文本框控件,然后在此基础上添加所有正常的文档操作技术(如字体选择、缩进和文件 I/O 支持)。除了主应用程序窗体(frmMain)之外,该项目还包括两个额外的窗体,一个用于在 RTB 的内容中搜索字符串,另一个用于在 RTB 中搜索和替换字符串。这些窗体分别是 frmFindfrmReplace

图 3:编辑器应用程序查找对话框

图 4:编辑器应用程序查找和替换对话框

除了前面提到的窗体类,该解决方案还包含一个名为“Graphics”的文件夹;该文件夹包含支持应用程序菜单和工具栏的所有图像文件。

项目引用

除了默认的引用之外,还添加了几个额外的引用。最值得注意的是,添加了扩展的富文本框控件库,以便可以使用扩展的富文本框控件。图 5 显示了项目中存在的引用。

图 5:项目引用

代码:主窗体类

主窗体类(frmMain)很容易理解。它以几个 Imports 语句开头,后跟类声明。代码按功能分为四个独立的区域,它们是:

  • 声明
  • 菜单方法
  • 工具栏方法
  • 打印

导入和类声明如下所示:

Imports System.Drawing
Imports System.Drawing.Image

Public Class frmMain

类声明很简单,不继承或实现任何基类或接口。我再次强调,利用微软的扩展富文本框控件可以大大减少支持此应用程序中所有方法所需的代码量。

声明部分也非常简单;该部分包含应用程序中使用的变量。内容如下:

#Region "Declarations"

    Private currentFile As String
    Private checkPrint As Integer

#End Region

currentFile”变量用于跟踪加载到扩展富文本框控件中的文件路径和文件名;每当用户打开文件、创建并保存文件,或者以新名称和/或文件扩展名保存文件时,它都会更新。

checkPrint”变量由微软在描述扩展富文本框控件使用方法的文章中推荐的简化打印过程使用。它用于确定文档发送到打印机时是否存在其他页面(以支持多页打印)。

下一部分代码是此应用程序使用的主要代码块。“Menu Methods”区域包含响应菜单选项选择的所有子程序。“Toolbar Methods”区域紧随“Menu Methods”区域之后,但工具栏控件部分中的所有子程序都会调用“Menu Methods”代码区域中定义的子程序,除非代码非常简单(只有一行),可以直接调用;因此,本文档不专门描述“Toolbar Methods”区域的内容。

菜单区域的第一段代码用于创建新文件。

    Private Sub NewToolStripMenuItem_Click(ByVal sender As _
            System.Object, ByVal e As System.EventArgs) _
            Handles NewToolStripMenuItem.Click

        If rtbDoc.Modified Then
            Dim answer As Integer
            answer = MessageBox.Show("The current document has not" & _ 
                     " been saved, would you like to " & _ 
                     "continue without saving?", "Unsaved Document", _
                     MessageBoxButtons.YesNo, MessageBoxIcon.Question)

            If answer = Windows.Forms.DialogResult.Yes Then
                rtbDoc.Clear()
            Else
                Exit Sub
            End If
        Else
            rtbDoc.Clear()
        End If

        currentFile = ""
        Me.Text = "Editor: New Document"
    End Sub

在此子程序中,在清除当前文档之前,通过使用控件的“Modified”测试来检查当前文档的状态;如果文档在打开时已被修改,该测试将返回 true。如果文档已被修改,将通过消息框向用户询问,以确定用户是否希望在清除文件之前保存(或丢失)对当前文件所做的修改。如果他们选择保存更改,则退出子程序;否则,将清除文档,并且更改将丢失。如果文档未被修改,子程序将不通知用户就清除文档。每当清除文档时,控件的标题都会更新,以指示新(未保存)文档是当前文档,并且“currentFile”变量被设置为包含一个空字符串。

图 6:用户请求新文档而不保存更改后显示的确认对话框

下一个子程序用于将现有文件打开到富文本框控件中。

    Private Sub OpenToolStripMenuItem_Click(ByVal sender _
            As System.Object, ByVal e As System.EventArgs) _
            Handles OpenToolStripMenuItem.Click

        If rtbDoc.Modified Then

            Dim answer As Integer
            answer = MessageBox.Show("The current document has not" & _ 
                     " been saved, would you like to continue " & _ 
                     "without saving?", "Unsaved Document", _
                     MessageBoxButtons.YesNo, MessageBoxIcon.Question)

            If answer = Windows.Forms.DialogResult.No Then
                Exit Sub
            Else
                OpenFile()
            End If
        Else
            OpenFile()
        End If

    End Sub

此子程序的工作方式与上一节讨论的“new”子程序类似。如果文件未被修改,或者用户决定不保存当前修改,则子程序会调用 OpenFile 子程序,该子程序会显示一个文件打开对话框,允许用户导航到他们希望打开的文件。OpenFile 子程序在下面,并包含以下代码:

    Private Sub OpenFile()

        OpenFileDialog1.Title = "RTE - Open File"
        OpenFileDialog1.DefaultExt = "rtf"
        OpenFileDialog1.Filter = "Rich Text Files|*.rtf|" & _ 
                                 "Text Files|*.txt|HTML Files|" & _ 
                                 "*.htm|All Files|*.*"
        OpenFileDialog1.FilterIndex = 1
        OpenFileDialog1.ShowDialog()

        If OpenFileDialog1.FileName = "" Then Exit Sub

        Dim strExt As String
        strExt = System.IO.Path.GetExtension(OpenFileDialog1.FileName)
        strExt = strExt.ToUpper()

        Select Case strExt
            Case ".RTF"
                rtbDoc.LoadFile(OpenFileDialog1.FileName, 
                RichTextBoxStreamType.RichText)
            Case Else
                Dim txtReader As System.IO.StreamReader
                txtReader = New 
                System.IO.StreamReader(OpenFileDialog1.FileName)
                rtbDoc.Text = txtReader.ReadToEnd
                txtReader.Close()
                txtReader = Nothing
                rtbDoc.SelectionStart = 0
                rtbDoc.SelectionLength = 0
        End Select

        currentFile = OpenFileDialog1.FileName
        rtbDoc.Modified = False
        Me.Text = "Editor: " & currentFile.ToString()

    End Sub

图 7:打开文件对话框

FileOpen 子程序的第一个部分用于配置和显示“打开文件”对话框;此代码设置文件类型(富文本、文本或 HTML)的过滤器,设置对话框标题,并选择一个扩展过滤器(RTF)。完成后,将显示对话框。如果用户在不指定文件名的情况下确认对话框,则子程序将退出。如果存在文件名,代码将从文件名中提取文件扩展名,将其放入本地字符串变量,转换为大写,并对字符串变量执行 Select Case 语句。如果用户选择的文件是 RTF 文件,则子程序调用控件的 LoadFile 方法,并将文件名和格式传递给它。如果文件不是 RTF 文件,则实例化一个流读取器,并将文件路径传递给它,然后通过流读取器的 ReadToEnd 方法将文件内容馈送到控件。然后关闭并释放读取器,并将光标移动到文档的开头,并将选择长度设置为零(如果不这样做,整个文档将初始化为完全选中)。文件加载后,“currentFile”变量将更新为包含当前文件路径和名称,控件的修改属性设置为 false,并且标题栏将更新以显示当前在富文本框控件中编辑的文件名。

接下来的项目是“保存”菜单选项;它包含以下代码:

    Private Sub SaveToolStripMenuItem_Click(ByVal sender As _
            System.Object, ByVal e As System.EventArgs) _
            Handles SaveToolStripMenuItem.Click

        If currentFile = "" Then
            SaveAsToolStripMenuItem_Click(Me, e)
            Exit Sub
        End If

        Dim strExt As String
        strExt = System.IO.Path.GetExtension(currentFile)
        strExt = strExt.ToUpper()

        Select Case strExt
            Case ".RTF"
                rtbDoc.SaveFile(currentFile)
            Case Else
                ' to save as plain text
                Dim txtWriter As System.IO.StreamWriter
                txtWriter = New System.IO.StreamWriter(currentFile)
                txtWriter.Write(rtbDoc.Text)
                txtWriter.Close()
                txtWriter = Nothing
                rtbDoc.SelectionStart = 0
                rtbDoc.SelectionLength = 0
                rtbDoc.Modified = False
        End Select

        Me.Text = "Editor: " & currentFile.ToString()

    End Sub

“保存”函数首先检查“currentFile”变量是否为空;如果是,则富文本框控件的内容尚未保存,并且子程序将调用“另存为”菜单选项,为当前未命名的文件提供一个界面供用户定义文件名和存储位置。如果文件已命名(并且有当前存储位置),则子程序将检查文件扩展名,并通过 Select Case 语句确定存储文件的适当方法,然后将内容保存到文件位置。这一切的工作方式与打开文件的方法非常相似。然而,它不是打开文件,而是调用富文本框控件的 SaveFile 方法(如果文件是富文本文件),或者实例化一个流写入器并将文件内容作为文本写入到文件位置(如果文件是纯文本或 HTML)。

对于文件打开和文件保存方法,如果文件不是富文本文件,应用程序将尝试使用流读取器或流写入器打开或保存它;这将允许应用程序处理任何文本文件,而不仅仅是 RTF、TXT 或 HTML 文件。这将允许您将其与自定义文件类型,或其他内容(如许可证文件或错误日志文件)一起使用。

下一个子程序处理“另存为”菜单选项;其代码如下:

    Private Sub SaveAsToolStripMenuItem_Click(ByVal sender As _
            System.Object, ByVal e As System.EventArgs) _
            Handles SaveAsToolStripMenuItem.Click

        SaveFileDialog1.Title = "RTE - Save File"
        SaveFileDialog1.DefaultExt = "rtf"
        SaveFileDialog1.Filter = "Rich Text Files|*.rtf|" & _ 
                                 "Text Files|*.txt|HTML Files" & _ 
                                 "|*.htm|All Files|*.*"
        SaveFileDialog1.FilterIndex = 1
        SaveFileDialog1.ShowDialog()

        If SaveFileDialog1.FileName = "" Then Exit Sub

        Dim strExt As String
        strExt = System.IO.Path.GetExtension(SaveFileDialog1.FileName)
        strExt = strExt.ToUpper()

        Select Case strExt
            Case ".RTF"
                rtbDoc.SaveFile(SaveFileDialog1.FileName, _
                       RichTextBoxStreamType.RichText)
            Case Else
                Dim txtWriter As System.IO.StreamWriter
                txtWriter = New 
                System.IO.StreamWriter(SaveFileDialog1.FileName)
                txtWriter.Write(rtbDoc.Text)
                txtWriter.Close()
                txtWriter = Nothing
                rtbDoc.SelectionStart = 0
                rtbDoc.SelectionLength = 0
        End Select

        currentFile = SaveFileDialog1.FileName
        rtbDoc.Modified = False
        Me.Text = "Editor: " & currentFile.ToString()

    End Sub

图 8:文件菜单选项

此时,这应该看起来很熟悉了;在代码中,将配置一个“另存为”文件对话框并显示给用户。该对话框允许用户将文件保存为 RTF、TXT 或 HTML。如果用户将文件保存为 RTF,则使用控件的 SaveFile 方法来存储文件内容,同时保留 RTF 格式。如果用户选择其他选项,文件将使用文本写入器保存为纯文本。在这两种情况下,文件保存后,“currentFile”变量都会更新,应用程序的标题栏会更新,并且文档的 Modified 属性会设置为 False

代码中的下一项是菜单的“退出”调用。它用于终止应用程序。在关闭应用程序之前,此子程序会检查当前文档是否已被修改,如果已被修改,则会向用户发出警告,并询问是否应该在关闭文档和应用程序之前保存它。代码如下:

    Private Sub ExitToolStripMenuItem_Click(ByVal sender As _
            System.Object, ByVal e As System.EventArgs) _
            Handles ExitToolStripMenuItem.Click

        If rtbDoc.Modified Then

            Dim answer As Integer
            answer = MessageBox.Show("The current document has not been" & _ 
                     " saved, would you like to continue without saving?", _
                     "Unsaved Document", MessageBoxButtons.YesNo, _
                     MessageBoxIcon.Question)

            If answer = Windows.Forms.DialogResult.No Then
                Exit Sub
            Else
                Application.Exit()
            End If
        Else
            Application.Exit()
        End If

    End Sub

下一个菜单选项是编辑菜单的“全选”功能。全选是富文本框控件中嵌入的一个方法,因此可以直接调用它,无需编写任何额外的代码来实现全选;要使用它,只需按如下方式调用:

    Private Sub SelectAllToolStripMenuItem_Click(ByVal sender _
            As System.Object, ByVal e As System.EventArgs) _
            Handles SelectAllToolStripMenuItem.Click

        Try
            rtbDoc.SelectAll()
        Catch exc As Exception
            MessageBox.Show("Unable to select all document content.", _
                            "RTE – Select", MessageBoxButtons.OK, _
                            MessageBoxIcon.Error)
        End Try

    End Sub

在编辑菜单的“全选”功能之后,我们有剪切、复制和粘贴子程序。就像全选方法存在于富文本框控件中一样,这些方法也存在于其中,因此您可以以类似于全选的方式直接调用它们。因此,我在这里不展示它们,但如果您愿意的话,可以在示例应用程序中查看它们是如何调用的。

图 9:编辑菜单选项

接下来是用于选择当前字体的菜单选项。此代码仅使用标准的字体对话框将富文本框控件的 SelectionFont 属性设置为用户通过字体对话框选择的字体。用于此的代码如下:

    Private Sub SelectFontToolStripMenuItem_Click(ByVal sender _
            As System.Object, ByVal e As System.EventArgs) _
            Handles SelectFontToolStripMenuItem.Click

        If Not rtbDoc.SelectionFont Is Nothing Then
            FontDialog1.Font = rtbDoc.SelectionFont
        Else
            FontDialog1.Font = Nothing
        End If

        FontDialog1.ShowApply = True
        If FontDialog1.ShowDialog() = Windows.Forms.DialogResult.OK Then
            rtbDoc.SelectionFont = FontDialog1.Font
        End If

    End Sub

图 10:正在使用的字体对话框

类似地,字体颜色菜单选项用于向用户显示标准的颜色对话框;如果用户从对话框中选择了一种颜色,则文档的 ForeColor 属性将更新为包含所选颜色。由于富文本框控件主要处理选中文本(即,您在选择字体或更改颜色时所做的更改),因此此功能只会改变选中文本的颜色。如果未选中文本,则插入点处的颜色将保留前景色选择,并且从插入点开始的输入将显示为新选中的颜色。

    Private Sub FontColorToolStripMenuItem_Click(ByVal sender _
            As System.Object, ByVal e As System.EventArgs) _
            Handles FontColorToolStripMenuItem.Click

        ColorDialog1.Color = rtbDoc.ForeColor
        If ColorDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
            rtbDoc.SelectionColor = ColorDialog1.Color
        End If

    End Sub

接下来的三个代码部分是用于设置选中文本的粗体、斜体或下划线属性的子程序。每个部分都设置为:如果选中文本是粗体,则选择粗体选项将删除粗体(或斜体、或下划线)。(由于它们都基本相同,我只展示粗体。)

    Private Sub BoldToolStripMenuItem_Click(ByVal sender As _
           System.Object, ByVal e As System.EventArgs) _
           Handles BoldToolStripMenuItem.Click
        If Not rtbDoc.SelectionFont Is Nothing Then
            Dim currentFont As System.Drawing.Font = rtbDoc.SelectionFont
            Dim newFontStyle As System.Drawing.FontStyle
            If rtbDoc.SelectionFont.Bold = True Then
                newFontStyle = FontStyle.Regular
            Else
                newFontStyle = FontStyle.Bold
            End If

            rtbDoc.SelectionFont = New Font(currentFont.FontFamily, _
                                   currentFont.Size, newFontStyle)
        End If
    End Sub

“普通”字体菜单选项将选中文本恢复为正常、无装饰的格式。

    Private Sub NormalToolStripMenuItem_Click(ByVal sender As _
            System.Object, ByVal e As System.EventArgs) _
            Handles NormalToolStripMenuItem.Click
        If Not rtbDoc.SelectionFont Is Nothing Then
            Dim currentFont As System.Drawing.Font = rtbDoc.SelectionFont
            Dim newFontStyle As System.Drawing.FontStyle
            newFontStyle = FontStyle.Regular

            rtbDoc.SelectionFont = New Font(currentFont.FontFamily, _
                                   currentFont.Size, newFontStyle)
        End If
    End Sub

用于设置页面颜色的菜单选项用于向用户显示颜色对话框;如果用户从对话框中选择了一种颜色,则富文本框控件的背景颜色将设置为该颜色。支持此功能的代码如下:

    Private Sub PageColorToolStripMenuItem_Click(ByVal sender _
            As System.Object, ByVal e As System.EventArgs) _
            Handles PageColorToolStripMenuItem.Click
        ColorDialog1.Color = rtbDoc.BackColor
        If ColorDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
            rtbDoc.BackColor = ColorDialog1.Color
        End If
    End Sub

图 11:正在使用的颜色对话框

撤销和重做功能用于备份或恢复在编辑过程中对控件内容所做的更改;富文本框控件直接支持撤销和重做功能,因此您所需要做的就是直接从控件调用该方法,进行调用,测试以确定控件是否可以执行撤销或重做请求,如果支持,则调用该方法。

    Private Sub mnuUndo_Click(ByVal sender As System.Object, _
            ByVal e As System.EventArgs) Handles mnuUndo.Click
        If rtbDoc.CanUndo Then rtbDoc.Undo()
    End Sub

    Private Sub mnuRedo_Click(ByVal sender As System.Object, _
            ByVal e As System.EventArgs) Handles mnuRedo.Click
        If rtbDoc.CanRedo Then rtbDoc.Redo()
    End Sub

接下来的三个代码部分处理将文档的水平对齐属性设置为支持选中文本的左对齐、居中对齐或右对齐。这些对齐控件选项中的每一个都由控件直接支持。

    Private Sub LeftToolStripMenuItem_Click_1(ByVal sender _
            As System.Object, ByVal e As System.EventArgs) _
            Handles LeftToolStripMenuItem.Click
        rtbDoc.SelectionAlignment = HorizontalAlignment.Left
    End Sub

    Private Sub CenterToolStripMenuItem_Click_1(ByVal sender _
            As System.Object, ByVal e As System.EventArgs) _
            Handles CenterToolStripMenuItem.Click
        rtbDoc.SelectionAlignment = HorizontalAlignment.Center
    End Sub

    Private Sub RightToolStripMenuItem_Click_1(ByVal sender As _
            System.Object, ByVal e As System.EventArgs) _
            Handles RightToolStripMenuItem.Click
        rtbDoc.SelectionAlignment = HorizontalAlignment.Right
    End Sub

图 12:对齐选项

添加和删除项目符号也由控件直接支持。BulletIndent 属性设置项目符号和文本之间的间隙,而 SelectionBullet 属性仅指示控件为选中文本添加或删除项目符号。

    Private Sub AddBulletsToolStripMenuItem_Click(ByVal sender _
            As System.Object, ByVal e As System.EventArgs) _
            Handles AddBulletsToolStripMenuItem.Click
        rtbDoc.BulletIndent = 10
        rtbDoc.SelectionBullet = True
    End Sub

    Private Sub RemoveBulletsToolStripMenuItem_Click(ByVal sender _
            As System.Object, ByVal e As System.EventArgs) _
            Handles RemoveBulletsToolStripMenuItem.Click
        rtbDoc.SelectionBullet = False
    End Sub

图 12:项目符号选项

设置选中文本的缩进级别也由控件直接支持。

    Private Sub mnuIndent0_Click(ByVal sender As System.Object, _
            ByVal e As System.EventArgs) Handles mnuIndent0.Click
        rtbDoc.SelectionIndent = 0
    End Sub

图 13:缩进选项

该应用程序包含一个单独的对话框,用于在当前文档中查找文本字符串。如果用户选择“查找”菜单选项,应用程序将创建一个新实例并显示搜索窗体(frmFind.vb)。

    Private Sub FindToolStripMenuItem_Click(ByVal sender As System.Object, _
            ByVal e As System.EventArgs) Handles FindToolStripMenuItem.Click
        Dim f As New frmFind()
        f.Show()
    End Sub

类似地,如果用户选择“查找和替换”菜单选项,应用程序将创建一个新实例并显示查找和替换窗体(frmReplace.vb)。

    Private Sub FindAndReplaceToolStripMenuItem_Click(ByVal sender _
            As System.Object, ByVal e As System.EventArgs) _
            Handles FindAndReplaceToolStripMenuItem.Click
        Dim f As New frmReplace()
        f.Show()
    End Sub

打印文档被设置为包含当前富文本框控件的内容。为了支持打印预览、页面设置和打印,考虑到对扩展富文本框控件所做的修改,所要做的就是将打印文档传递给每个相关的标准对话框。

    Private Sub PreviewToolStripMenuItem_Click(ByVal sender _
            As System.Object, ByVal e As System.EventArgs) _
            Handles PreviewToolStripMenuItem.Click
        PrintPreviewDialog1.Document = PrintDocument1
        PrintPreviewDialog1.ShowDialog()
    End Sub

    Private Sub PrintToolStripMenuItem_Click(ByVal sender As System.Object, _
            ByVal e As System.EventArgs) _
            Handles PrintToolStripMenuItem.Click
        PrintDialog1.Document = PrintDocument1
        If PrintDialog1.ShowDialog() = Windows.Forms.DialogResult.OK Then
            PrintDocument1.Print()
        End If
    End Sub

    Private Sub mnuPageSetup_Click(ByVal sender As System.Object, _
            ByVal e As System.EventArgs) Handles mnuPageSetup.Click
        PageSetupDialog1.Document = PrintDocument1
        PageSetupDialog1.ShowDialog()
    End Sub

下一个子程序更有趣;它用于将图像文件嵌入到扩展富文本框文档中。此子程序使用一个文件打开对话框,该对话框设置为过滤位图、JPEG 和 GIF 文件扩展名。用户可以导航到他们希望嵌入到文档中的文件(将其放置在光标定义的插入点)。

    Private Sub InsertImageToolStripMenuItem_Click(ByVal sender _
            As System.Object, ByVal e As System.EventArgs) _
            Handles InsertImageToolStripMenuItem.Click

        OpenFileDialog1.Title = "RTE - Insert Image File"
        OpenFileDialog1.DefaultExt = "rtf"
        OpenFileDialog1.Filter = "Bitmap Files|*.bmp|JPEG Files|*.jpg|GIF 
        Files|*.gif"
        OpenFileDialog1.FilterIndex = 1
        OpenFileDialog1.ShowDialog()

        If OpenFileDialog1.FileName = "" Then Exit Sub

        Try
            Dim strImagePath As String = OpenFileDialog1.FileName
            Dim img As Image
            img = Image.FromFile(strImagePath)
            Clipboard.SetDataObject(img)
            Dim df As DataFormats.Format
            df = DataFormats.GetFormat(DataFormats.Bitmap)
            If Me.rtbDoc.CanPaste(df) Then
                Me.rtbDoc.Paste(df)
            End If
        Catch ex As Exception
            MessageBox.Show("Unable to insert image format selected.", "RTE – 
            Paste", MessageBoxButtons.OK, MessageBoxIcon.Error)
        End Try

    End Sub

图 15:嵌入图像文件

一旦用户通过打开文件对话框选择了一个文件,子程序将使用 Image.FromFile 方法创建一个图像。然后将此图像放入剪贴板,并随后粘贴到文档中。

主窗体代码的最后一部分包含在打印区域。由于使用了扩展富文本框控件,用于打印的调用非常简单。

    Private Sub PrintDocument1_BeginPrint(ByVal sender As Object, _
            ByVal e As System.Drawing.Printing.PrintEventArgs) _
            Handles PrintDocument1.BeginPrint
        ' Adapted from Microsoft's example for extended richtextbox control
        '
        checkPrint = 0
    End Sub

BeginPrint 子程序用于在每次新打印作业开始时将“checkPrint”变量重置为零。

PrintPage 子程序调用扩展富文本框控件的 Print 方法,将当前文档的全部或选定部分发送到打印机。该调用还会检查是否存在不止一页,并且它将继续打印,直到所有页面都已传递到打印机。用于打印的代码如下:

    Private Sub PrintDocument1_PrintPage(ByVal sender As Object, _
            ByVal e As System.Drawing.Printing.PrintPageEventArgs) _
            Handles PrintDocument1.PrintPage

        ' Adapted from Microsoft's example for extended richtextbox control
        '
        ' Print the content of the RichTextBox. Store the last character 
          printed.
        checkPrint = rtbDoc.Print(checkPrint, rtbDoc.TextLength, e)

        ' Look for more pages
        If checkPrint < rtbDoc.TextLength Then
            e.HasMorePages = True
        Else
            e.HasMorePages = False
        End If

    End Sub

图 16:打印预览

打印部分总结了主窗体类的其余部分。

代码:查找和替换窗体

查找和替换窗体由 frmReplace 类支持。查找类定义在 frmFind 中,但由于它包含两个子程序(Find 和 Find Next),它们也包含在查找和替换窗体中,我将只讨论查找和替换窗体中的代码。

查找和替换窗体支持四个子程序:

  • 查找
  • 查找下一个
  • 替换
  • 全部替换

Find 子程序非常直接,它将搜索整个文档以查找用户在窗体上定义的搜索词的第一个出现。它将以两种方式之一进行搜索:匹配或不匹配搜索词的大小写。根据用户是否选中了窗体上的“匹配大小写”复选框,应用程序将使用二进制或文本比较方法搜索文本。使用二进制方法,搜索词必须完全匹配(包括大小写);使用文本比较方法,字符串只需要匹配。“StartPosition”整数值设置为从 InStr 调用返回的值;InStr 传递起始位置 1、富文本框控件中包含的文本的整个正文(作为要搜索的文章)、用户输入的搜索词以及搜索比较方法。如果找到文本,InStr 将返回找到文本的索引位置。如果找不到任何内容,它将返回零。如果起始位置值为零,将通知用户未找到搜索词;否则,应用程序将高亮显示文档中找到的文本,滚动到其位置,并将焦点设置回主窗体(这将使高亮显示对用户可见)。

    Private Sub btnFind_Click(ByVal sender As System.Object, _
            ByVal e As System.EventArgs) Handles btnFind.Click

        Dim StartPosition As Integer
        Dim SearchType As CompareMethod

        If chkMatchCase.Checked = True Then
            SearchType = CompareMethod.Binary
        Else
            SearchType = CompareMethod.Text
        End If

        StartPosition = InStr(1, frmMain.rtbDoc.Text, _
                         txtSearchTerm.Text, SearchType)

        If StartPosition = 0 Then
            MessageBox.Show("String: '" & txtSearchTerm.Text.ToString() & _
                            "' not found", "No Matches", _
                            MessageBoxButtons.OK, MessageBoxIcon.Asterisk)
            Exit Sub
        End If

        frmMain.rtbDoc.Select(StartPosition - 1, txtSearchTerm.Text.Length)
        frmMain.rtbDoc.ScrollToCaret()
        frmMain.Focus()

    End Sub

Find Next 函数的工作方式与 Find 函数一致;唯一的区别是它将起始位置设置为文档中选定起始点的当前位置,这样 Find Next 函数每次搜索时都不会从文档开头开始。

    Private Sub btnFindNext_Click(ByVal sender As System.Object, _
            ByVal e As System.EventArgs) Handles btnFindNext.Click

        Dim StartPosition As Integer = frmMain.rtbDoc.SelectionStart + 2
        Dim SearchType As CompareMethod

        If chkMatchCase.Checked = True Then
            SearchType = CompareMethod.Binary
        Else
            SearchType = CompareMethod.Text
        End If

        StartPosition = InStr(StartPosition, frmMain.rtbDoc.Text, _
                        txtSearchTerm.Text, SearchType)

        If StartPosition = 0 Then
            MessageBox.Show("String: '" & txtSearchTerm.Text.ToString() & _
                            "' not found", "No Matches", _
                            MessageBoxButtons.OK, MessageBoxIcon.Asterisk)
            Exit Sub
        End If

        frmMain.rtbDoc.Select(StartPosition - 1, txtSearchTerm.Text.Length)
        frmMain.rtbDoc.ScrollToCaret()
        frmMain.Focus()

    End Sub

Replace 子程序很简单。它仅测试是否有文本被选中,如果有,则将其替换为用户在窗体中输入的替换文本;然后,如果存在搜索词的下一个出现,它将移至下一个。

    Private Sub btnReplace_Click(ByVal sender As System.Object, _
            ByVal e As System.EventArgs) Handles btnReplace.Click

        If frmMain.rtbDoc.SelectedText.Length <> 0 Then
            frmMain.rtbDoc.SelectedText = txtReplacementText.Text
        End If

        Dim StartPosition As Integer = frmMain.rtbDoc.SelectionStart + 2
        Dim SearchType As CompareMethod

        If chkMatchCase.Checked = True Then
            SearchType = CompareMethod.Binary
        Else
            SearchType = CompareMethod.Text
        End If

        StartPosition = InStr(StartPosition, frmMain.rtbDoc.Text,_
                        txtSearchTerm.Text, SearchType)

        If StartPosition = 0 Then
            MessageBox.Show("String: '" & txtSearchTerm.Text.ToString() & _
                            "' not found", "No Matches", _
                            MessageBoxButtons.OK, MessageBoxIcon.Asterisk)
            Exit Sub
        End If

        frmMain.rtbDoc.Select(StartPosition - 1, txtSearchTerm.Text.Length)
        frmMain.rtbDoc.ScrollToCaret()
        frmMain.Focus()

    End Sub

Replace All 函数稍有不同,因为它使用 Replace 方法将整个文本体中搜索词的每个实例替换为替换词。

    Private Sub btnReplaceAll_Click(ByVal sender As System.Object, _
            ByVal e As System.EventArgs) Handles btnReplaceAll.Click

        Dim currentPosition As Integer = frmMain.rtbDoc.SelectionStart
        Dim currentSelect As Integer = frmMain.rtbDoc.SelectionLength

        frmMain.rtbDoc.Rtf = Replace(frmMain.rtbDoc.Rtf, _
                             Trim(txtSearchTerm.Text), _
                             Trim(txtReplacementText.Text))
        frmMain.rtbDoc.SelectionStart = currentPosition
        frmMain.rtbDoc.SelectionLength = currentSelect
        frmMain.Focus()

    End Sub

同样,frmFind 类与 Replace 类相同,唯一的例外是它不支持 Replace 和 Replace All 方法。

代码:富文本框打印控件

RichTextBoxPrintCtrl 类中包含的类库中的代码由微软开发;有关该类的完整内容描述,请参阅 Visual Studio 2005 帮助文件中的此链接

摘要

本文和示例应用程序试图演示一些有用的技术,通过使用 RichTextBox 控件来创建和管理文本及文本文件。该控件本身通过微软推荐的方法进行了修改,极大地简化了打印文本或富文本文件内容所需的难度。此外,该应用程序提供了一种将图像插入到 RichTextBox 中的方法,从而创建了一个基于 RichTextBox 控件的更有用的应用程序。

© . All rights reserved.