November 1998

Setting the TRichEdit font

by Gerry Myers

Setting the font of a TRichEdit component isn't very difficult. To easily let the user select the font setting, you can drop a TFontDialog component onto your form and tie it to a menu item or button.

In the article "Transferring TRichEdit Text,", that's exactly what we do. The user clicks a button, and up pops the standard Font dialog box shown
in Figure A.

Figure A: By clicking a button, the user can open this Font dialog box and select text-formatting options.
[ Figure A ]

The user can then specify the font name, style, and size. When the dialog box closes, our program accesses the TFontDialog Font property to get the individual font attributes.

Since both TRichEdit and TFontDialog have a Font property, your first inclination may be to simply make the assignment


RichEdit1->Font = FontDialog1->Font

However, this code will more than likely produce an unexpected result--the TRichEdit's Font property specifies the default font to use when no other font is specified for a text selection. When the user highlights some text and selects a specific font, you must use a different property, so only that text is set to the new font. You'll use the SelAttribute property, which has many of the same subproperties as the TFont class: Color, Height, Pitch, Style, and so on. Assigning most of the properties is straightforward, as you can see in
Listing A.

Listing A: Assigning text properties

// Must set just the selected text.
Graphics::TFont* theFont = FontDialog1->Font;
RichEdit1->SelAttributes->Charset = theFont->Charset;
RichEdit1->SelAttributes->Color = theFont->Color;
RichEdit1->SelAttributes->Height = theFont->Height;
RichEdit1->SelAttributes->Name = theFont->Name;
RichEdit1->SelAttributes->Pitch = theFont->Pitch;
RichEdit1->SelAttributes->Size = theFont->Size;

The only fly in the ointment is the Style property, which is of type Set. Strangely, when you're loading characteristics into a Set, the set must appear as an L-value and as an R-value within the same statement. For example, to load the Bold characteristic, you must write your statement as follows:

RichEdit1->SelAttributes->Style = 
    RichEdit1->SelAttributes->Style << 
    fsBold;

Notice that the Style property shows up on both sides of the assignment operator. Also, notice the double left-angle bracket (<<), which is the Set insertion operator. After looking at the TFont class, you may say, "Wait--TFont has a Style property and SelAttribute has a similar Style property. Can't I simply assign one to the other?" That's the other strange thing about the Style property. If you try to make a direct assignment to Style, as in

RichEdit1->SelAttributes->Style = 
    theFont->Style;

or even as in

RichEdit1->SelAttributes->Style =
    RichEdit1->SelAttributes->Style + 
    theFont->Style;

your code will compile and run without error--but your style selections (italics, bold, underline, and strikeout) won't show up in the TRichEdit component. Sorry, you'll have to load each of the four style characteristics separately. The easiest way we've found to do this is to clear the rich edit's Style property and then reload only the desired styles, as shown in Listing B.

Listing B: Clearing and reloading styles

RichEdit1->SelAttributes->Style = 
    RichEdit1->SelAttributes->
Style.Clear();
if ( theFont->Style.Contains( fsBold ) )
    RichEdit1->SelAttributes->Style = 
      RichEdit1->SelAttributes->Style << fsBold;
if ( theFont->Style.Contains( fsItalic ) )
    RichEdit1->SelAttributes->Style = 
      RichEdit1->SelAttributes->Style << fsItalic;
if ( theFont->Style.Contains( fsUnderline ) )
    RichEdit1->SelAttributes->Style = 
      RichEdit1->SelAttributes->Style << fsUnderline;
if ( theFont->Style.Contains( fsStrikeOut ) )
    RichEdit1->SelAttributes->Style = 
      RichEdit1->SelAttributes->Style << fsStrikeOut;