Table of Contents
Using Rich Edit controls
by Richard Russell, March 2007
Rich Edit controls are superficially very similar to ordinary Edit Boxes, but they give you much greater control over the formatting of their contents. Amongst the many features available are:
- Setting of background and text colours
- Bold, italic, underline and strike-out fonts
- Indentation, alignment, tabs
- Drag and Drop editing
This article explains how to incorporate Rich Edit controls in your BBC BASIC programs.
Initialisation
To start off with we need to include this initialisation code:
SYS "LoadLibrary", "RICHED20.DLL" EM_SETBKGNDCOLOR = 1091 EM_SETCHARFORMAT = 1092 ES_MULTILINE = 4 WS_BORDER = &800000 WS_CHILD = &40000000 WS_VISIBLE = &10000000 CFM_BOLD = 1 CFM_ITALIC = 2 CFM_UNDERLINE = 4 CFM_STRIKEOUT = 8 CFM_FACE = &20000000 CFM_COLOR = &40000000 CFM_SIZE = &80000000 CFE_BOLD = 1 CFE_ITALIC = 2 CFE_UNDERLINE = 4 CFE_STRIKEOUT = 8 SCF_SELECTION = 1 SCF_ALL = 4
Now we can create the Rich Edit control itself. The process depends on whether you want to display it in a dialogue box or directly on your program's main window.
Dialogue box
As usual, we must install the appropriate library for working with dialogue boxes:
INSTALL @lib$+"WINLIB2"
(alternatively install WINLIB2A or WINLIB2B if you need the facilities they provide).
Now we will create a simple dialogue box containing just a cancel button and a Rich Edit control:
dlg% = FN_newdialog("Rich Edit control", 250, 20, 150, 140, 8, 1000) PROC_pushbutton(dlg%, "Cancel", 2, 20, 120, 56, 14, 0) reid% = 101 PROC_dlgctrl(dlg%, "", reid%, 20, 20, 64, 12, WS_CHILD OR WS_VISIBLE OR WS_BORDER, \ \ "RichEdit20A")
Note that the Rich Edit control has been allocated the ID number 101. Refer to the documentation for PROC_dlgitem for the meaning of the other parameters.
You may want to combine other window styles with the WS_BORDER value. Rich Edit controls will respond to most of the style values allocated to multiline edit controls; notable exceptions are ES_LOWERCASE, ES_UPPERCASE and ES_OEMCONVERT which are not supported by Rich Edit controls.
The dialogue box is displayed in the usual way:
PROC_showdialog(dlg%)
Main output window
As usual, we must install the appropriate library for working with boxes and buttons:
INSTALL @lib$+"WINLIB5"
(alternatively install WINLIB5A, and remember to pass the parent window handle @hwnd% as the first parameter of FN_createwindow).
The Rich Edit control is created as follows:
hre% = FN_createwindow("RichEdit20A", "", 200, 50, 140, 200, 0, \ \ WS_BORDER OR ES_MULTILINE, 0)
Refer to the documentation for FN_createwindow for the meaning of the parameters.
You may want to combine other window styles with the WS_BORDER value. Rich Edit controls will respond to most of the style values allocated to multiline edit controls; notable exceptions are ES_LOWERCASE, ES_UPPERCASE and ES_OEMCONVERT which are not supported by Rich Edit controls.
Controlling the control
Each of the sections below lists code for both the Dialogue Box and Main Window cases; use whichever version is applicable to your program.
You load text into a Rich Edit control in exactly the same way as a multiline edit control:
REM Control in dialogue box: SYS "SetDlgItemText", !dlg%, reid%, text$ REM Control on main window: SYS "SetWindowText", hre%, text$
Lines of text should be delimited by the CRLF (CHR$13+CHR$10) character sequence.
Similarly, to read (edited) text from the control, use the same method as for a regular edit box:
REM Control in dialogue box: DEF FNgettext(dlg%, id%) LOCAL text% DIM text% LOCAL 65535 SYS "GetDlgItemText", !dlg%, reid%, text%, 65536 = $$text% REM Control on main window: DEF FNgettext(hedit%) LOCAL text% DIM text% LOCAL 65536 SYS "GetWindowText", hedit%, text%, 65536 = $$text%
You may want to adapt the above code to reduce the size of the buffer. You can discover the length of text in the Rich Edit control using the GetWindowTextLength API function.
To change the background colour use code similar to the following:
REM Control in dialogue box: SYS "SendDlgItemMessage", !dlg%, reid%, EM_SETBKGNDCOLOR, 0, bgcolor% REM Control on main window: SYS "SendMessage", hre%, EM_SETBKGNDCOLOR, 0, bgcolor%
Here bgcolor% should contain the required colour in the COLORREF format, i.e. a hexadecimal value of the form &00BBGGRR.
To change the text font (including its colour and style) you first need to create and initialise a CHARFORMAT structure:
DIM cfmt{cbSize%, dwMask%, dwEffects%, yHeight%, yOffset%, crTextColor%, \ \ bCharSet&, bPitchAndFamily&, szFaceName&(31), padding&(1)} cfmt.cbSize% = DIM(cfmt{}) cfmt.dwMask% = CFM_BOLD OR CFM_ITALIC OR CFM_UNDERLINE OR \ \ CFM_STRIKEOUT OR CFM_FACE OR CFM_COLOR OR CFM_SIZE cfmt.dwEffects% = style% cfmt.yHeight% = height% cfmt.crTextColor% = fgcolor% cfmt.szFaceName&() = facename$
Here style% is a combination of the “CFE_” constants (see the initialisation code above), height% is the character height in twips (1/1440 inch), fgcolor% is the text colour (as for bgcolor% above) and facename$ is the font name (e.g. ““Arial””).
Once you have initialised the CHARFORMAT structure you can use it to format the text in the control as follows:
REM Control in dialogue box: SYS "SendDlgItemMessage", !dlg%, reid%, EM_SETCHARFORMAT, SCF_ALL, cfmt{} REM Control on main window: SYS "SendMessage", hre%, EM_SETCHARFORMAT, SCF_ALL, cfmt{}
As shown all the text is affected; if you want to format only the currently selected text change SCF_ALL to SCF_SELECTION.
This article only scratches the surface of what can be achieved using Rich Edit controls. For more information consult Microsoft's documentation.
Addendum: by Michael Hutton, July 2010
You may want to use the CHARFORMAT2{} with the Rich Edit Control. Here is its definition:
DIM CHARFORMAT2{cbSize%, \
\ dwMask%, \
\ dwEffects%, \
\ yHeight%, \
\ yOffset%, \
\ crTextColor%, \
\ bCharSet&, \
\ bPitchAndFamily&, \
\ szFaceName&(31), \
\ padding&(1), \
\ wWeight{l&,h&}, \
\ sSpacing{l&,h&}, \
\ crBackColor%, \
\ lcid%, \
\ dwReserved%, \
\ sShort{l&,h&}, \
\ xKerning{l&,h&}, \
\ bUnderlineType&, \
\ bAnimation&, \
\ bRevAuthor&, \
\ bReserved1& }