Home

Windows Controls: The Rich Text

 

Introduction to the Rich Text

 

Description

Text is considered rich if it can display various characters or paragraphs in different styles and features that make it more attractive than a regular ASCII text. Such a text can have some of its sections in different colors. Its paragraphs can have customized attributes or arranged independent of each other.

Although you can create a complete rich but static text, the common use of a rich text is to let the user process most of the formatting.

Creating a Rich Text Control

To support a rich text, the .NET Framework provides the RichTextBox control that is implement from the RichTextBox class. Like TextBox, the RichTextBox class is based on TextBoxBase. Therefore, to have right text in an application, from the Common Controls section of the Toolbox, click RichTextBox and click the form.

To programmatically create rich text, declare a variable of type RichTextBox, use the new operator to allocate memory for it, and add it to the Controls collection of its parent. Here is an example:

#include <windows.h>

#using <System.dll>
#using <System.Drawing.dll>
#using <System.Windows.Forms.dll>

using namespace System;
using namespace System::Drawing;
using namespace System::Windows::Forms;

public ref class CExercise : Form
{
private:
    RichTextBox ^ rtbNote;

public:
    CExercise()
    {
        InitializeComponent();
    }
	
private:
    void InitializeComponent()
    {
        rtbNote = gcnew RichTextBox;

        Controls->Add(rtbNote);
    }
};

[STAThread]
int APIENTRY WinMain(HINSTANCE hInstance,
		     HINSTANCE hPrevInstance,
		     LPSTR lpCmdLine,
		     int nCmdShow)
{
    Application::Run(gcnew CExercise);

    return 0;
}

ApplicationPractical Learning: Starting a Rich Text Application

  1. Create a new Windows Forms Application named Notice3
  2. From the Dialogs section of the Toolbox, click OpenFileDialog OpenFileDialog and click the form
  3. In the Properties window, click DefaultExt and type rtf
  4. Click (Name) and type dlgOpen
  5. Click Filter and type Rich Text Format (*.rtf)|*.rtf|Text File (*.txt)|*.txt|All Files|
  6. From the Dialogs section of the Toolbox, click SaveFileDialog and click the form
  7. In the Properties window, click DefaultExt and type rtf
  8. Click (Name) and type dlgSave
  9. Click Filter and type Rich Text Format (*.rtf)|*.rtf|Text File (*.txt)|*.txt|All Files|
  10. From the Common Controls section of the Toolbox, click RichTextBox RichTextBox and click the form
  11. From the Menus & Toolbars section of the Toolbox, click MenuStrip and click the form
  12. On the form, click Type Here, type File and press Enter
  13. Under File, click Type Here, type New and press Enter
  14. On the right side of File, click Type Here, type Edit and press Enter
  15. Under Edit, click Type Here, type New and press Enter
  16. In the same way, complete the menu strip with the following items:
     
    Notice
  17. Double-click an unoccupied area of the form
  18. In the top section of the file, add the System::IO namespace and declare a string variable named CurrentFileName:
    namespace Notice3
    {
        using namespace System;
        using namespace System::ComponentModel;
        using namespace System::Collections;
        using namespace System::Windows::Forms;
        using namespace System::Data;
        using namespace System::Drawing;
        using namespace System::IO;
    
    	/// <summary>
    	/// Summary for Form1
    	/// </summary>
    	public ref class Form1 : public System::Windows::Forms::Form
    	{
    	private:
            String ^ CurrentFileName;
  19. Change the file as follows:
    System::Void Form1_Load(System::Object^  sender, System::EventArgs^  e)
    {
        CurrentFileName = "<Not Allowed>";
        rtbEditor->Modified = false;
    }
  20. Return to the form and click the rich text control
  21. In the Properties window, change the its properties as follows:
    Name: rchEditor
    AcceptsTab: True
    Font: Times New Roman, 12pt
    Dock: Fill
    ScrollBars: Vertical
  22. On the form, click Edit and double-click Undo
  23. Implement the event as follows:
    System::Void mnuEditUndo_Click(Object ^ sender, EventArgs ^ e)
    {
        rtbEditor->Undo();
    }
  24. Return to the form
  25. On the form, click Edit and double-click Redo
  26. Implement the event as follows:
    System::Void mnuEditRedo_Click(Object ^ sender, EventArgs ^ e)
    {
        rtbEditor->Redo();
    }
  27. Return to the form
  28. On the form, click Edit and double-click Cut
  29. Implement the event as follows:
    System::Void mnuEditCut_Click(Object ^ sender, EventArgs ^ e)
    {
        rtbEditor->Cut();
    }
  30. Return to the form
  31. On the form, click Edit and double-click Copy
  32. Implement the event as follows:
    System::Void mnuEditCopy_Click(Object ^ sender, EventArgs ^ e)
    {
        rtbEditor->Copy();
    }
  33. Return to the form
  34. On the form, click Edit and double-click Paste
  35. Implement the event as follows:
    System::Void mnuEditPaste_Click(Object ^ sender, EventArgs ^ e)
    {
        rtbEditor->Paste();
    }
  36. Return to the form
  37. On the form, click Edit and double-click Select All
  38. Implement the event as follows:
    System::Void mnuSelectAll_Click(Object ^ sender, EventArgs ^ e)
    {
        rtbEditor->SelectAll();
    }
  39. Return to the form
  40. Click Format and double-click Word Wrap
  41. Implement the event as follows:
    System::Void mnuFormatWordWrap_Click(Object ^ sender, EventArgs ^ e)
    {
        rtbEditor->WordWrap = true;
    }

The Text of a Rich Text Box

 

Introduction

Like the other graphical Windows controls, the right text box uses the common characteristics such as the location, the size, the minimum size, the maximum size, the anchor, the docking, the font, the ability to be visible or hidden, the ability to be enabled or disabled, and the border style. Like the TextBox control, the rich text control inherits various characteristics from the TextBoxBase class, including the Text property, the Lines collection, the read-only attribute, the ability to select and manipulate text. The rich text box also shares various characteristics with the multi-line text box such as the Multiline property, the scroll bars, the word wrap, the ability to accept the Tab and the Enter keys. Here is an example:

void InitializeComponent()
{
    rtbNote = gcnew RichTextBox;
    rtbNote->Size = System::Drawing::Size(Width, Height);
    rtbNote->Multiline = true;
    rtbNote->ScrollBars = RichTextBoxScrollBars::Both;
    rtbNote->AcceptsTab = true;
    rtbNote->Font = gcnew System::Drawing::Font("Verdana", 10.0F);

    array<String ^> ^  strLines =
    {
	"Leaving Sydney",
        "When we decided to leave, we knew we were "
        "making a hard decision. We had spent so much "
	"time this had become our new home. A few "
        "weeks or months before, we wanted to make "
        "Sydney our newly found settlement, a "
	"permanent place we could proudly call ours. "
        "It appeared that, unpredictably, fate had "
        "decided otherwise.",
        "Author: Arthur D. Pale",
        "Title: Stories Of My Life"
    };
    rtbNote->Lines = strLines;

    Controls->Add(rtbNote);
}

Saving the Contents of a Rich Text Document

After creating and formatting a rich text document, you may want to save it for later use. To support this, the RichTextBox class provides a member function named named SaveFile that is overloaded with three versions. One of the versions uses the following syntax:

public:
    void SaveFile(String^ path);

This member function takes as argument the name or path to a file. It will save the file as RTF. If you want the user to save a file that is either RTF, ASCII, or another format, to specify the desired format, you can use the following version of the member function:

public:
    void SaveFile(String^ path, RichTextBoxStreamType fileType);

As seen in the first version, the first argument is the name or path of the file. The second argument allows you to specify the type of file that is being saved, which could be a normal ASCII text. This argument is of type RichTextBoxStreamType, which is an enumeration. The members of the RichTextBoxStreamType enumeration are PlainText, RichNoOleObjs, RichText, TextTextOleObjs, or TextTextOleObjs.

Instead of directly using the name of the file, you can create it as a stream. In this case, the RichTextBox class provides the following version of the SaveFile() member function:

public:
    void SaveFile(Stream^ data, RichTextBoxStreamType fileType);

This version expects a Stream-based object such as a FileStream variable.

 
 
 

Opening a Rich Text File

To assist you with opening a rich text file, the RichTextBox class is equipped with the LoadFile() member function overloaded with three versions. The simplest versions has the following syntax:

public:
    void LoadFile(String^ path);

This member function takes as argument the name or path to a file. The file must be in RTF format. If it is not, the file will not be opened and the compiler would throw an IOException exception. If you want to give the user the ability to open different types of files, you should use the following version of the LoadFile() member function:

public:
    void LoadFile(String^ path, RichTextBoxStreamType fileType);

The first argument is the same as a the single argument of the first version. The second argument allows you to specify the type of file that is being opened, which could be a normal ASCII text. This argument is of type RichTextBoxStreamType.

Instead of directly using the name of the file, you can create it as a stream. In this case, the RichTextBox class provides the following version of the LoadFile() member function:

public:
    void LoadFile(Stream^ data, RichTextBoxStreamType fileType);

This version expects a Stream-based object such as a FileStream variable.

ApplicationPractical Learning: Opening a Rich Text File

  1. On the form, click File and double-click New
  2. Implement the event as follows:
    System::Void mnuFileNew_Click(System::Object^  sender, System::EventArgs^ e)
    {
        // This is the question the user will have to answer
        System::Windows::Forms::DialogResult answer = MessageBox::Show(
                        "The document has changed. Do you want to save it?"
                        "\nClick\n"
                        "Yes:\tTo save the document and create a new one.\n"
                        "No:\tNot to save the document but create a new one.\n"
                        "Cancel:\tNot to do anything",
                        "Editor - Saving a File",
                        MessageBoxButtons::YesNoCancel,
                        MessageBoxIcon::Question);
    
        // When the user clicks File -> New to start a new document,
        // before creating a new document,
        // find out if the document is "dirty" ask the user whether to save or not
        if( rtbEditor->Modified == true)
        {
            // Present the message box to the user who 
            // will decide whether to save
            if( answer == System::Windows::Forms::DialogResult::Yes)
            {
                // If the user answers Yes
                // Find out if the current document has never been saved
                if( CurrentFileName == "<Not Allowed>")
                {
                    // If it has never been saved, then display the Save dialog box
                    if( dlgSave->ShowDialog() == System::Windows::Forms::DialogResult::OK)
                    {
                        // Save the file
                        rtbEditor->SaveFile(dlgSave->FileName);
                        // Change the current file name to something not allowed
                        CurrentFileName = "<Not Allowed>";
                        // Display Untitled name of the current file on the title bar
                        Text = "Parasol - Untitled";
                        // Since the document has been saved and the user wants 
                        // to create a new one, empty the control
                        rtbEditor->Clear();
                        // Update the Modified attribute
                        rtbEditor->Modified = false;
                    }
                    else // the user had clicked Cancel, don't do anything
                        return;
                }
                else // If the document was saved before, then simply update it
                {
                    rtbEditor->SaveFile(CurrentFileName);
                    // Change the current file name to something not allowed
                    CurrentFileName = "<Not Allowed>";
                    // Display Untitled name of the current file on the title bar
                    Text = "Parasol - Untitled";
                    rtbEditor->Clear();
                    // Update the Modified attribute
                    rtbEditor->Modified = false;
                }
            }
            else if( answer == System::Windows::Forms::DialogResult::No)
            {
                // If the user answered No, 
                // then simply start a new document
                rtbEditor->Clear();
                // Change the current file name to something not allowed
                CurrentFileName = "<Not Allowed>";
                // Display Untitled name of the current file on the title bar
                Text = "Parasol - Untitled";
                // Update the Modified attribute
                rtbEditor->Modified = false;
            }
            else // If the user clicked Cancel, don't do anything
                return;
        }
        else // If the document was not modified, then start a new one
        {
            // If the user answered No, 
            // then simply start a new document
            rtbEditor->Clear();
            // Change the current file name to something not allowed
            CurrentFileName = "<Not Allowed>";
            // Display Untitled name of the current file on the title bar
            Text = "Parasol - Untitled";
            // Update the Modified attribute
            rtbEditor->Modified = false;
        }
    }
  3. Return to the form
  4. On the form, click File and double-click Open
  5. Implement the event as follows:
    System::Void mnuFileOpen_Click(System::Object^  sender, System::EventArgs^  e)
    {
    	// Find out if there was a document and if the document was "dirty"
        if( rtbEditor->Modified == true )
        {
            // Here is the question the user will answer
            System::Windows::Forms::DialogResult answer = MessageBox::Show(
                            "The document has changed. Do you want to save it?"
                            "\nClick\n"
                            "Yes:\tTo save the document and open a new one.\n"
                            "No:\tNot to save the document but open a new one.\n"
                            "Cancel:\tNot to do anything",
                            "Editor - Opening a File",
                            MessageBoxButtons::YesNoCancel,
                            MessageBoxIcon::Question);
    
            // Find out if the user wants to save the current document
            if( answer == System::Windows::Forms::DialogResult::Yes)
            {
                // Find out if this is a new document
                if( CurrentFileName == "<Not Allowed>" )
                {
                    // Since the user wants to save the document, display the Save dialog box
                    if( dlgSave->ShowDialog() == System::Windows::Forms::DialogResult::OK)
                    {
                        // Save the file
                        rtbEditor->SaveFile(dlgSave->FileName);
                    }
                    else
                        return;
                }
                else
                {
                    // This was not a new document,
                    // so, simply save it
                    rtbEditor->SaveFile(CurrentFileName);
    			}
            }
            else if( answer == System::Windows::Forms::DialogResult::No)
            {
                // If the user answered No to the question, don't save
                // Simply open the file
                if( dlgOpen->ShowDialog() == System::Windows::Forms::DialogResult::OK)
                {
                    // Open the new document after letting the user select it
                    rtbEditor->LoadFile(dlgOpen->FileName);
                    // Change the file name of our archives
                    CurrentFileName = dlgOpen->FileName;
                    // Get the name of the file that the user selected
                    FileInfo ^ fleParasol = gcnew FileInfo(dlgOpen->FileName);
                    Text = "Parasol - " + fleParasol->Name;
                    rtbEditor->Modified = false;
                }
                else
                    return;
            }
            else
                return;
        }
        else
        {
            if( dlgOpen->ShowDialog() == System::Windows::Forms::DialogResult::OK)
            {
                // Open the new document after letting the user select it
                rtbEditor->LoadFile(dlgOpen->FileName);
                // Change the file name of our archives
                CurrentFileName = dlgOpen->FileName;
                // Get the name of the file that the user selected
                FileInfo ^ fleParasol = gcnew FileInfo(dlgOpen->FileName);
                Text = "Parasol - " + fleParasol->Name;
                rtbEditor->Modified = false;
            }
        }
    }
  6. Return to the form
  7. On the form, click File and double-click Save
  8. Implement the event as follows:
    System::Void mnuFileSave_Click(System::Object^  sender, System::EventArgs^  e)
    {
    	// Find out if the current document has never been saved
        // but is not empty
        if( (rtbEditor->Modified == true) &&
            (CurrentFileName == "<Not Allowed>") )
        {
            // Since the document is dirty, display the Save As dialog box
            if( dlgSave->ShowDialog() == System::Windows::Forms::DialogResult::OK)
            {
                // Retrieve the new name file and display
                // the file in the rich edit control
                rtbEditor->SaveFile(dlgSave->FileName);
                // Change/Update the global and complete name of the file,
                // including its path
                CurrentFileName = dlgSave->FileName;
                // Extract the name of the file
                FileInfo ^ fleParasol = gcnew FileInfo(dlgSave->FileName);
                // Display the name of the current file on the title bar
                Text = "Parasol - " + fleParasol->Name;
            }
            else
                return;
        }
        else
        {
            // It appears that this document already had a name
            // but the document was previously modified
            // Therefore, simply save it internally
            rtbEditor->SaveFile(CurrentFileName);
        }
    }
  9. Return to the form
  10. On the form, click File and double-click Save As
  11. Implement the event as follows:
    System::Void mnuFileSaveAs_Click(System::Object^  sender, System::EventArgs^  e)
    {
        if( dlgSave->ShowDialog() == System::Windows::Forms::DialogResult::OK)
        {
            rtbEditor->SaveFile(dlgSave->FileName);			
            // Change the file name of our archives
            CurrentFileName = dlgSave->FileName;
            // Get the name of the file that the user selected
            FileInfo ^ fleParasol = gcnew FileInfo(dlgSave->FileName);
            Text = "Parasol - " + fleParasol->Name;
            rtbEditor->Modified = false;
        }
    }
  12. Return to the form
  13. On the form, click File and double-click Exit
  14. Implement the event as follows:
    System::Void mnuFileExit_Click(System::Object^  sender, System::EventArgs^  e)
    {
    	// Is the document dirty?
        if( rtbEditor->Modified == true)
        {
            // Since the document is dirty, find out if the user wants to save it
            System::Windows::Forms::DialogResult answer = MessageBox::Show(
                     "The document has changed. Do you want to save it?"
                        "\nClick\n"
                        "Yes:\tTo save the document and close the application.\n"
                        "No:\tNot to save the document but close the application.\n"
                        "Cancel:\tNot to do anything",
                        "Parasol - Saving a File",
                        MessageBoxButtons::YesNoCancel, MessageBoxIcon::Question);
    
            // If the user wants to save it
            if( answer == System::Windows::Forms::DialogResult::Yes)
            {
                // Behave as if the user had clicked File . Save
                mnuFileSave_Click(sender, e);
                Close();
            }
            else if( answer == System::Windows::Forms::DialogResult::No)
            {
                // If the user doesn't want to save the document
                Close();
            }
            // The user cancelled the action: do nothing
            else
                return;
    
        }
        else // There is no action to take
            Close();
    }
  15. Return to the form

Rich Text Formatting

 

Formatting Text

We saw that you could change the general font of a text box and you can change the color of the characters. If you do this on a text box, all of the characters are changed to the same font and the same color. One of the extended properties of a rich text box over a regular text box is the ability to change the font and/ the color of individual characters, words, or paragraphs and the change applies only to the desired characters.

Before changing a character or a word, you must first select it. To change the font of the text that is selected on the control, the selected text is identified with the SelectionFont property. To change the color of the text that is selected, the selected text is identified with the SelectionColor property.

To assist you with this, you can use the Font dialog box. After selecting the character or word, you can transfer their attributes to the Font dialog box before displaying it. After using the dialog box, if the user clicks OK, you can retrieve the font and color characteristics then apply them to the selected character or text.

ApplicationPractical Learning: Formatting Text

  1. From the Dialogs section of the Toolbox, click FontDialog and click the form
  2. Click (Name) and type dlgFont
  3. Double-click ShowColor to set its value to True
  4. On the form, click Format and double-click Font
  5. Implement the event as follows:
    System::Void mnuFormatFont_Click(System::Object^  sender, System::EventArgs^  e)
    {
        // Get the characteristics of the selected text
        // Apply them to the Font dialog box
        dlgFont->Font = rtbEditor->SelectionFont;
        dlgFont->Color = rtbEditor->SelectionColor;
    
        if( dlgFont->ShowDialog() == System::Windows::Forms::DialogResult::OK)
        {
            // Display the Font dialog box
            // If the user clicks OK, get the characteristics of the font
            // Apply them to the selected text of the Rich Edit control
            rtbEditor->SelectionFont = dlgFont->Font;
            rtbEditor->SelectionColor = dlgFont->Color;
        }
    }
  6. Return to the form

The Paragraph Alignment

For a text-based control, a paragraph is a series of words that start with a letter or empty space until the flow of text is interrupted, which is usually made with a carriage return, or the end of the document. By itself, the paragraph controls its alignment and such details as Tab measurements or indentation. To set or change the properties of a paragraph, you must first select it. To select a paragraph, you don't need to formally select it or any portion of its text. As long as the cursor is positioned inside of the paragraph, any paragraph attribute you set or change would apply to the whole paragraph. To manipulate more than one paragraph at the same time, you or your user must select them. The paragraphs do not need to be wholly selected. As long as a section is selected on it, a paragraph is considered selected.

The most common property of a paragraph is its alignment, which states whether the paragraph is positioned to the left, the center, or the right. This characteristic is controlled by the SelectionAlignment property. The SelectionAlignment property is based on the HorizontalAlignment enumeration whose members are Left, Center, and Right. Because this property is applied on (individual) paragraphs, it is not available at design time.

To change the alignment at run time, assign the desired value to the SelectionAlignment property. In the following example, the alignment of the selected paragraph is set in response to the user clicking a button:

System::Void button1_Click(Object ^ sender, EventArgs ^ e)
{
        richtextBox1->SelectionAlignment = HorizontalAlignment::Center;
}

Application Topic Applied: Aligning a Paragraph

  1. On the form, click Format and double-click Paragraph Align Left
  2. Implement the event as follows:
    System::Void mnuFormatAlignLeft_Click(Object ^ sender, EventArgs ^ e)
    {
        rtbEditor->SelectionAlignment = HorizontalAlignment::Left;
    }
  3. Return to the form, click Format and double-click Paragraph Align Center
  4. Implement the event as follows:
    System::Void mnuFormatAlignCenter_Click(Object ^ sender, EventArgs ^ e)
    {
        rtbEditor->SelectionAlignment = HorizontalAlignment::Center;
    }
  5. Return to the form, click Format and double-click Paragraph Align Right
  6. Implement the event as follows:
    System::Void mnuFormatAlignRight_Click(Object ^ sender, EventArgs ^ e)
    {
        rtbEditor->SelectionAlignment = HorizontalAlignment::Right;
    }
  7. Return to the form

The Indentation of a Paragraph

Indentation is the number of empty characters that separate a paragraph edge from one of the borders of the rich text control. Indentation refers to the left side or the right side of a paragraph. Based on this, left indentation refers to the number of empty characters from the left border of the rich text control to the left edge of a paragraph. The rich text control provides indentation through various properties.

To support indentation from the left side of a paragraph, the RichTextBox class is equipped with a property named SelectionIndent property. To indent from the right side, the RichTextBox is equipped with the SelectionRightIndent property.

Application Topic Applied: Indenting a Paragraph

  1. On the form, click Format and double-click Left Indent
  2. Implement the event as follows:
    System::Void mnuFormatLeftIndent_Click(Object ^ sender, EventArgs ^ e)
    {
        rtbEditor->SelectionIndent += 10;
    }
  3. Return to the form, click Format and double-click Right Indent
  4. Implement the event as follows:
    System::Void mnuFormatRightIndent_Click(Object ^ sender, EventArgs ^ e)
    {
        rtbEditor->SelectionRightIndent += 10;
    }
  5. Return to the form

A Bulleted Paragraph

Instead of just a regular section made only of text, you can create an unordered list of lines or paragraphs in your document. To support this, the RichTextBox class is equipped with a Boolean property named SelectionBullet. If you set this property to false on a paragraph, the paragraph would start with a bullet. If you apply this property to more than one consecutive paragraph, each would start with a bullet.

ApplicationTopic Applied: Using a Rich Text Control

  1. On the form, click Format and double-click each button and implement their Click events as follows:
    System::Void mnuFormatBulletList_Click(Object ^ sender, EventArgs ^ e)
    {
        rtbEditor->SelectionBullet = true;
    }
  2. Execute the application to test it
  3. Close the form and return to your programming environment
 
 
   
 

Home Copyright © 2011 FunctionX, Inc. Home