Home

Windows Controls: The Rich Edit Control

 

Introduction to the Rich Edit Control

 

Overview

A rich edit control is a Windows object that resembles an edit box but can handle text that is formatted. This mean that it can display text with various characters formats and can show paragraphs with different alignments. A rich edit control can also allow a user to change the formatting on characters and control the alignment of paragraphs.

 

Practical LearningPractical Learning: Introducing the Rich Edit Controls

  1. Start Microsoft Visual Studio
  2. To create a new application, on the main menu, click File -> New Project...
  3. In the middle list, click MFC Application
  4. Set the Name to RichFormatter
  5. Click OK
  6. In the first page of the MFC Application Wizard, click Next
  7. In the second page of the wizard, click Dialog Box
  8. Click Next
  9. In the third page of the wizard, click About Box to remove the check mark on it
  10. Change the Dialog Title to Rich Editor
  11. Click Next twice
  12. Click Finish
  13. On the dialog box, click TODO: and press Delete

Creating a Rich Edit Control

To create a rich edit control, you ca use the Rich Edit 2.0 Control Rich Edit 2.0 Control from the Toolbox. You can also programmatically create this control using the CRichEditCtrl class. To do this, use its (default) constructor:

CRichEditCtrl RichEditor;

After declaring this variable, you can define the characteristics of the control using the CRichEditCtrl::Create() method. Its syntax is:

BOOL Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID);

The dwStyle argument specifies the window style to apply to the control. Since the rich edit control is not a container, it is usually positioned on another control such as a form or dialog box. Therefore, the primary style you must apply is WS_CHILD. To display the control to the user, also add the WS_VISIBLE style. This primary style can be defined as follows:

DWORD RichStyle = WS_CHILD | WS_VISIBLE;

Although a rich edit control can be used as a single-line text object, to make it more efficient, you should make it use various lines. This can be taken care of by setting the Multiline property to True or adding the ES_MULTILINE style. An example would be:

DWORD RichStyle = WS_CHILD | WS_VISIBLE | ES_MULTILNE;

Once a rich edit can display multiple lines of text, if the text is longer than the control can display, you should equip it with scroll bars. The vertical scroll bar is made available by adding checking the Vertical Scroll check box or setting it to True. This can be done programmatically by adding the WS_VSCROLL window style. Here is an example:

DWORD RichStyle = WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_MULTILNE;

The horizontal scroll bar is made possible by setting the Horizontal Scroll property to True. To do this programmatically, add the WS_HSCROLL window style.

If you do not want the user to change the text in the rich edit control, you can set the Read-Only property to True. This can also be done by adding the ES_READONLY style.

The rect argument specifies the location and dimensions of the control.

The pParentWnd argument is the control that is hosting the rich edit control. It is usually a form or a dialog box.

The nID is an identifier for the rich edit control.

Practical LearningPractical Learning: Creating a Rich Edit Application

  1. In the Solution Explorer, in the Source Files node, double-click RichFormatter.cpp
  2. In the InitInstance method, type ::AfxInitRichEdit2();
    BOOL CRichFormatterApp::InitInstance()
    {
        //TODO: call AfxInitRichEdit2() to initialize richedit2 library.
    	// InitCommonControlsEx() is required on Windows XP if an application
    	// manifest specifies use of ComCtl32.dll version 6 or later to enable
    	// visual styles.  Otherwise, any window creation will fail.
    	INITCOMMONCONTROLSEX InitCtrls;
    	InitCtrls.dwSize = sizeof(InitCtrls);
    	// Set this to include all the common control classes you want to use
    	// in your application.
    	InitCtrls.dwICC = ICC_WIN95_CLASSES;
    	InitCommonControlsEx(&InitCtrls);
    
    	::AfxInitRichEdit2();
    
    	CWinApp::InitInstance();
    
    	. . . No Change
    	
    	// Since the dialog has been closed, return FALSE so that we exit the
    	//  application, rather than start the application's message pump.
    	return FALSE;
    }
  3. On the Toolbox, click the Rich Edit 2.0 Control Rich Edit and draw a rectangle from the left border to the left of the right border
  4. On the Properties window, change its ID to IDC_EDITOR
  5. Set the following properties to True: Multiline, Want Return, Vertical Scroll
  6. Right-click the rich edit control and click Add Variable
  7. Make sure the Variable Type is set to CRichEditCtrl. Set the Name to m_RichEditor
     
    Add Member Variable Wizard
  8. Click OK

Characteristics of a Rich Edit Control

 

Introduction

The primary role of a rich edit control is to hold text. When its content is long or large, it can be equipped with scroll bars, either or both horizontal and vertical. The control allows you to specify these characteristics or you can control them at design time if you want.

Practical LearningPractical Learning: Controlling the Scroll Bars

  1. On the dialog box, click the rich edit control
  2. In the Properties window, change the values of the following characteristics
    Auto HScroll: False
    Auto VScroll: True
    Vertical Scroll: True

Formatting the Selected Text

At first glance, a rich edit appears like a regular edit control. Its ability to format text and paragraph sets them apart. To change the appearance of a letter, a word or a paragraph, you can change its size, height, or weight. This can be done by calling the CRichEditCtrl::SetSelectionCharFormat() method. Its syntax is:

BOOL SetSelectionCharFormat(CHARFORMAT& cf);

This simply means that the rich edit control relies on the Win32 API's CHARFORMAT structure to format text. This structure is defined as follows:

typedef struct _charformat {
    	UINT cbSize;
	DWORD dwMask;
	DWORD dwEffects;
	LONG yHeight;
	LONG yOffset;
	COLORREF crTextColor;
	BYTE bCharSet;
	BYTE bPitchAndFamily;
	TCHAR szFaceName[LF_FACESIZE];
} CHARFORMAT;

To format the characters, declare a variable of this structure and take its size. Then initialize the necessary member variables, ignoring those you do not need. To start, initialize dwMask with the type of formatting you want to apply or the type of operation you want to perform. The possible values are:

Value Used to
CFM_BOLD Make the character(s) bold
CFM_ITALIC Italicize the character(s)
CFM_UNDERLINE Underline the character(s)
CFM_STRIKEOUT Strike out the character(s)
CFM_SIZE Change the size the character(s)
CFM_CHARSET Access character set
CFM_COLOR Change the color of the text
CFM_FACE Set the font name
CFM_OFFSET Offset the character(s)
CFM_PROTECTED Protect the character(s)

You can apply the actual text formatting using the dwEffects member variable. Its possible values are: CFE_AUTOCOLOR, CFE_BOLD, CFE_ITALIC, CFE_STRIKEOUT, CFE_UNDERLINE, and CFE_PROTECTED. These effects can be combined as needed using the bitwise OR operator. For example, you can combine CFE_BOLD and CFE_ITALIC as CFE_BOLD | CFE_ITALIC to have text that is both in bold and italic.

The yHeight variable is used to set the new height of the text.

The yOffset variable is used to create a superscript or subscript effect.

The crTextColor variable is used to set the color for the text.

The bCharSet variable is used to the character set value as defined for the Win32's LOGFONT structure.

The bPitchAndFamily member variable is the same as set for the LOGFONT structure.

The szFaceName variable is used to specify the name of the font to apply to the text.

If you want to find out what formatting is applied on a character or text, call the CRichEditCtrl::GetSelectionCharFormat() method. Its syntax is:

DWORD GetSelectionCharFormat(CHARFORMAT& cf) const;

This method returns the type of dwMask of the CHARFORMAT structure applied on the character or text.

 
 
 

Formatting A Paragraph

To control the alignment of a paragraph on a right edit control, you can call the CRichEditCtrl::SetParaFormat() method. Its syntax is:

BOOL SetParaFormat(PARAFORMAT& pf);

The actual paragraph formatting is set using the Win32 API's PARAFORMAT structure. It is created as follows:

typedef struct _paraformat {
	UINT cbSize;
	DWORD dwMask;
	WORD wNumbering;
	WORD wReserved;
	LONG dxStartIndent;
	LONG dxRightIndent;
	LONG dxOffset;
	WORD wAlignment;
	SHORT cTabCount;
	LONG rgxTabs[MAX_TAB_STOPS];
} PARAFORMAT;

To define the necessary values for this structure, first declare a variable from it and retrieve its size. This is done with the cbSize member variable. Secondly, use the dwMask member variable to specify what formatting you want to perform. For example, to control paragraph alignment, initialize dwMask with PFM_ALIGNMENT. On the other hand, if you want to set or remove a bullet on a paragraph, initialize the dwMask variable with PFM_NUMBERING.

The wNumbering member variable is used to apply or remove the bullet from a paragraph.

You will need to use wReserved. Therefore, you can either ignore it or set its value to 0.

The dxStartIndent, the dxRightIndent, and the dxOffset member variables are used to indent text.

If you had initialized dwMask with PFM_ALIGNMENT, you can use wAlignment to specify the alignment of the paragraph. The possible values are:

Value Description
PFA_LEFT The paragraph will be aligned to the left
PFA_CENTER The paragraph will be aligned to the center
PFA_RIGHT The paragraph will be aligned to the right

The cTabCount and the rgxTabs member variables are used to control tab separation.

To retrieve the paragraph formatting applied on a paragraph, you can call the CRichEditCtrl::GetParaFormat() method. Its syntax is:

DWORD GetParaFormat(PARAFORMAT& pf) const;

This method returns formatting applied on the selected paragraph.

Practical LearningPractical Learning: Using Rich Edit Properties

  1. Add the following 8 buttons:
     
    Rich Edit 2.0 Control
    Button: ID Caption
    IDC_BOLD_BTN  Bold
    IDC_ITALIC_BTN Italic
    IDC_UNDERLINE_BTN Underline
    IDC_STRIKEOUT_BTN Strikeout
    IDC_LEFT_BTN Align Left
    IDC_CENTER_BTN Center
    IDC_RIGHT_BTN Align Right
    IDC_BULLET_BTN Bullets
  2. Add a BN_CLICKED event handler for each button and implement the events as follows:
    void CRichFormatterDlg::OnBnClickedBoldBtn()
    {
    	// TODO: Add your control notification handler code here
    	CHARFORMAT Cfm;
    
    	m_RichEditor.GetSelectionCharFormat(Cfm);
    
    	Cfm.cbSize = sizeof(CHARFORMAT);
    	Cfm.dwMask = CFM_BOLD;
    	Cfm.dwEffects ^= CFE_BOLD; 
    
    	m_RichEditor.SetSelectionCharFormat(Cfm); 
    	m_RichEditor.SetFocus();
    }
    
    void CRichFormatterDlg::OnBnClickedItalicBtn()
    {
    	// TODO: Add your control notification handler code here
    	CHARFORMAT Cfm;
    
    	m_RichEditor.GetSelectionCharFormat(Cfm);
    
    	Cfm.cbSize = sizeof(CHARFORMAT);
    	Cfm.dwMask = CFM_ITALIC;
    	Cfm.dwEffects ^= CFE_ITALIC; 
    
    	m_RichEditor.SetSelectionCharFormat(Cfm); 
    	m_RichEditor.SetFocus();
    }
    
    void CRichFormatterDlg::OnBnClickedUnderlineBtn()
    {
    	// TODO: Add your control notification handler code here
    	CHARFORMAT Cfm;
    
    	m_RichEditor.GetSelectionCharFormat(Cfm);
    
    	Cfm.cbSize = sizeof(CHARFORMAT);
    	Cfm.dwMask = CFM_UNDERLINE;
    	Cfm.dwEffects ^= CFE_UNDERLINE; 
    
    	m_RichEditor.SetSelectionCharFormat(Cfm); 
    	m_RichEditor.SetFocus();
    }
    
    void CRichFormatterDlg::OnBnClickedStrikeoutBtn()
    {
    	// TODO: Add your control notification handler code here
    	CHARFORMAT Cfm;
    
    	m_RichEditor.GetSelectionCharFormat(Cfm);
    
    	Cfm.cbSize = sizeof(CHARFORMAT);
    	Cfm.dwMask = CFM_STRIKEOUT;
    	Cfm.dwEffects ^= CFE_STRIKEOUT; 
    
    	m_RichEditor.SetSelectionCharFormat(Cfm); 
    	m_RichEditor.SetFocus();
    }
    
    void CRichFormatterDlg::OnBnClickedLeftBtn()
    {
    	// TODO: Add your control notification handler code here
    	PARAFORMAT Pfm;
    
    	Pfm.cbSize = sizeof(PARAFORMAT);
    	Pfm.dwMask = PFM_ALIGNMENT;
    	Pfm.wAlignment = PFA_LEFT;
    
    	m_RichEditor.SetParaFormat(Pfm);
    	m_RichEditor.SetFocus();
    }
    
    void CRichFormatterDlg::OnBnClickedCenterBtn()
    {
    	// TODO: Add your control notification handler code here
    	PARAFORMAT Pfm;
    
    	Pfm.cbSize = sizeof(PARAFORMAT);
    	Pfm.dwMask = PFM_ALIGNMENT;
    	Pfm.wAlignment = PFA_CENTER;
    
    	m_RichEditor.SetParaFormat(Pfm);
    	m_RichEditor.SetFocus();
    }
    
    void CRichFormatterDlg::OnBnClickedRightBtn()
    {
    	// TODO: Add your control notification handler code here
    	PARAFORMAT Pfm;
    
    	Pfm.cbSize = sizeof(PARAFORMAT);
    	Pfm.dwMask = PFM_ALIGNMENT;
    	Pfm.wAlignment = PFA_RIGHT;
    
    	m_RichEditor.SetParaFormat(Pfm);
    	m_RichEditor.SetFocus();
    }
    
    void CRichFormatterDlg::OnBnClickedBulletBtn()
    {
    	// TODO: Add your control notification handler code here
    	PARAFORMAT Pfm;
    
    	m_RichEditor.GetParaFormat(Pfm);
    	Pfm.cbSize = sizeof(PARAFORMAT);
    	Pfm.dwMask = PFM_NUMBERING;
    
    	Pfm.wNumbering ^= PFN_BULLET;
    
    	m_RichEditor.SetParaFormat(Pfm);
    	m_RichEditor.SetFocus();
    }
  3. Execute the application to test it
  4. Type some text and format some sections. Here are examples:
     
    Rich Edit Control
  5. Close the dialog box and return to your programming environment
 
 
   
 

Home Copyright © 2010-2011 FunctionX, Inc.