Home

Rich Edit

 

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.

A Rich Edit Control

To create a rich edit control, you ca use the Rich Edit button from the Controls 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 Learning Practical Learning: Creating a Rich Edit Application

  1. Create a Dialog Based Application Type project named Richer and based on CFormView
  2. Delete the TODO line and the OK button
  3. Change the caption of the Cancel button to Close
  4. On the Control toolbox, click the Rich Edit button Rich Edit Control and draw a rectangle from the left border to the left of the Cancel
     
  5. On the Properties window, change its ID to IDC_RICHER
  6. Set the following properties to True: Multiline, Want Return, Vertical Scroll
  7. Add a Control variable (of type CRichEditCtrl) to the rich edit control and name it m_Richer

Rich Edit Properties

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.

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 Learning Practical Learning: Using Rich Edit Properties

  1. Add the following 8 buttons:
     
    ID Caption
    IDC_BTN_BOLD B
    IDC_BTN_ITALIC I
    IDC_BTN_UNDERLINE U
    IDC_BTN_STRIKEOUT S
    IDC_BTN_LEFT <
    IDC_BTN_CENTER =
    IDC_BTN_RIGHT >
    IDC_BTN_BULLET :
  2. Add a BN_CLICKED event handler for each button and implement the events as follows:
     
    void CRicher1Dlg::OnBnClickedBtnBold()
    {
    	// TODO: Add your control notification handler code here
    	CHARFORMAT Cfm;
    
    	m_Richer.GetSelectionCharFormat(Cfm);
    
    	Cfm.cbSize = sizeof(CHARFORMAT);
    	Cfm.dwMask = CFM_BOLD;
    	Cfm.dwEffects ^= CFE_BOLD; 
    
    	m_Richer.SetSelectionCharFormat(Cfm); 
    	m_Richer.SetFocus();
    }
    
    void CRicher1Dlg::OnBnClickedBtnItalic()
    {
    	// TODO: Add your control notification handler code here
    	CHARFORMAT Cfm;
    
    	m_Richer.GetSelectionCharFormat(Cfm);
    
    	Cfm.cbSize = sizeof(CHARFORMAT);
    	Cfm.dwMask = CFM_ITALIC;
    	Cfm.dwEffects ^= CFE_ITALIC; 
    
    	m_Richer.SetSelectionCharFormat(Cfm); 
    	m_Richer.SetFocus();
    }
    
    void CRicher1Dlg::OnBnClickedBtnUnderline()
    {
    	// TODO: Add your control notification handler code here
    	CHARFORMAT Cfm;
    
    	m_Richer.GetSelectionCharFormat(Cfm);
    
    	Cfm.cbSize = sizeof(CHARFORMAT);
    	Cfm.dwMask = CFM_UNDERLINE;
    	Cfm.dwEffects ^= CFE_UNDERLINE; 
    
    	m_Richer.SetSelectionCharFormat(Cfm); 
    	m_Richer.SetFocus();
    }
    
    void CRicher1Dlg::OnBnClickedBtnStrikeout()
    {
    	// TODO: Add your control notification handler code here
    	CHARFORMAT Cfm;
    
    	m_Richer.GetSelectionCharFormat(Cfm);
    
    	Cfm.cbSize = sizeof(CHARFORMAT);
    	Cfm.dwMask = CFM_STRIKEOUT;
    	Cfm.dwEffects ^= CFE_STRIKEOUT; 
    
    	m_Richer.SetSelectionCharFormat(Cfm); 
    	m_Richer.SetFocus();
    }
    
    void CRicher1Dlg::OnBnClickedBtnLeft()
    {
    	// TODO: Add your control notification handler code here
    	PARAFORMAT Pfm;
    
    	Pfm.cbSize = sizeof(PARAFORMAT);
    	Pfm.dwMask = PFM_ALIGNMENT;
    	Pfm.wAlignment = PFA_LEFT;
    
    	m_Richer.SetParaFormat(Pfm);
    	m_Richer.SetFocus();
    }
    
    void CRicher1Dlg::OnBnClickedBtnCenter()
    {
    	// TODO: Add your control notification handler code here
    	PARAFORMAT Pfm;
    
    	Pfm.cbSize = sizeof(PARAFORMAT);
    	Pfm.dwMask = PFM_ALIGNMENT;
    	Pfm.wAlignment = PFA_CENTER;
    
    	m_Richer.SetParaFormat(Pfm);
    	m_Richer.SetFocus();
    }
    
    void CRicher1Dlg::OnBnClickedBtnRight()
    {
    	// TODO: Add your control notification handler code here
    	PARAFORMAT Pfm;
    
    	Pfm.cbSize = sizeof(PARAFORMAT);
    	Pfm.dwMask = PFM_ALIGNMENT;
    	Pfm.wAlignment = PFA_RIGHT;
    
    	m_Richer.SetParaFormat(Pfm);
    	m_Richer.SetFocus();
    }
    
    void CRicher1Dlg::OnBnClickedBtnBullet()
    {
    	// TODO: Add your control notification handler code here
    	PARAFORMAT Pfm;
    
    	m_Richer.GetParaFormat(Pfm);
    	Pfm.cbSize = sizeof(PARAFORMAT);
    	Pfm.dwMask = PFM_NUMBERING;
    
    	Pfm.wNumbering ^= PFN_BULLET;
    
    	m_Richer.SetParaFormat(Pfm);
    	m_Richer.SetFocus();
    }
  3. Test the application
     
  4. Return to MSVC

Home Copyright © 2003-2005 FunctionX, Inc.