Skip to content

CRichEditCtx Editing

José Roca edited this page Nov 3, 2026 · 3 revisions

Home › All Categories › sys/win › sys/win/richedit › CRichEditCtx › CRichEditCtx: editing

CRichEditCtx: editing

Selects, finds, inserts and replaces text in a rich edit control, and undoes edits.

Selects, finds, inserts and replaces text in a rich edit control, and undoes edits.

These are the CRichEditCtx members that work on the text itself: the selection and the caret, searching, lines and scrolling, inserting and replacing, undo and redo, word wrap, margins, tables, images and streams. Creating the control, its properties and the file members are on CRichEditCtx and CRichEditCtx: documents and formatting.

Positions. A character position is a zero-based index into the text. A paragraph break is one character, a carriage return (chr(13)), and an inserted image or object is one character too. Text read back with GetTextRange, GetSelText or GetLine has a lone carriage return at each paragraph break, not a CR/LF pair. The pair (0, -1) means the whole text. After the last character there is one more, the final paragraph mark, so selecting everything ends one past the text: for 31 characters the selection is 0 to 32.

Lines. Line numbers are zero-based and count the lines as the control shows them: with word wrap on, one paragraph can be several lines.

Unicode. The text members that take a wstring pass it to the control as UTF-16. Those that come in a string and a wstring form (SetTextEx, InsertText, ReplaceText) choose by the argument: a narrow literal, a string and a ustring all pick the string form, which the control reads in the ANSI code page, so "é" from a ustring arrives as two characters. Pass a wstring for anything beyond ASCII.

Results. Most members that return the control's answer to a message reset GetLastResult() to 0, and several of those that return nothing or a structure store the message's result there. The members that work through COM or a file (Undo( Count ), InsertImage, SaveRawText …) store an HRESULT or a Windows error code.

Importing

#import "sys/win"
#import "sys/win/gui"
#import "sys/win/richedit"
using win, gui, richedit

Example

A rich edit control with three buttons: Find fox selects the next "fox" after the selection, wrapping round to the top, and reports its line and column in the caption; Insert inserts a word at the caret; Undo undoes the last edit:

#import "sys/win"
#import "sys/win/gui"
#import "sys/win/richedit"
using win, gui, richedit

const IDC_EDIT = 101, IDC_FIND = 102, IDC_INSERT = 103, IDC_UNDO = 104

declare function WndProc( byval hwnd as HWND, byval uMsg as UINT, byval wParam as WPARAM, byval lParam as LPARAM ) as LRESULT

function main() as long
    SetProcessDpiAwareness( PROCESS_SYSTEM_DPI_AWARE )
    dim pWindow as CWindow = "EditingDemo"
    dim hWin as HWND = pWindow.Create( NULL, "CRichEditCtx: editing", @WndProc )
    pWindow.SetClientSize( 520, 300 )
    pWindow.Center
    dim pRichEdit as CRichEditCtx = CRichEditCtx( @pWindow, IDC_EDIT, "", 10, 10, 500, 240 )
    pRichEdit.SetText( "The quick brown fox jumps over the lazy dog." & chr(13) & "A second fox is waiting." )
    pRichEdit.EnableWordWrap()
    pRichEdit.EmptyUndoBuffer()
    pWindow.AddControl( "Button", hWin, IDC_FIND, "&Find fox", 10, 260, 90, 28 )
    pWindow.AddControl( "Button", hWin, IDC_INSERT, "&Insert", 110, 260, 90, 28 )
    pWindow.AddControl( "Button", hWin, IDC_UNDO, "&Undo", 210, 260, 90, 28 )
    return pWindow.DoEvents( SW_NORMAL )
end function

function WndProc( byval hwnd as HWND, byval uMsg as UINT, byval wParam as WPARAM, byval lParam as LPARAM ) as LRESULT
    select case uMsg
        case WM_COMMAND
            if CBCTLMSG( wParam, lParam ) = BN_CLICKED then
                dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hwnd, IDC_EDIT )
                if pRichEdit = NULL then return 0
                select case CBCTL( wParam, lParam )
                    case IDC_FIND
                        dim cr as CHARRANGE = pRichEdit->ExGetSel()
                        dim found as CHARRANGE = pRichEdit->FindTextEx( FR_DOWN, cr.cpMax, -1, "fox" )
                        if found.cpMin = -1 then found = pRichEdit->FindTextEx( FR_DOWN, 0, -1, "fox" )
                        if found.cpMin <> -1 then
                            pRichEdit->ExSetSel( found.cpMin, found.cpMax )
                            pRichEdit->ScrollCaret()
                            dim nLine as long = pRichEdit->ExLineFromChar( found.cpMin )
                            SetWindowText( hwnd, "fox at line " & ( nLine + 1 ) & ", column " & _
                                                 ( found.cpMin - pRichEdit->LineIndex( nLine ) + 1 ) )
                        end if
                    case IDC_INSERT
                        dim wszWord as wstring * 16 = "[note] "
                        pRichEdit->InsertText( wszWord )
                    case IDC_UNDO
                        if pRichEdit->CanUndo() then pRichEdit->Undo()
                end select
                SetFocus( pRichEdit->hRichEdit )
            end if
            return 0
        case WM_DESTROY
            PostQuitMessage( 0 )
            return 0
    end select
    return DefWindowProcW( hwnd, uMsg, wParam, lParam )
end function

end main()

Members

Member Does
CanPaste Says whether the clipboard holds a format the control can paste.
CanRedo Says whether there is anything to redo.
CanUndo Says whether there is anything to undo.
CallAutocorrectProc Runs the autocorrect procedure for a character.
DisplayBand Draws a band of text formatted with FormatRange.
EmptyUndoBuffer Empties the undo and redo queues.
ExGetSel Returns the selection as a CHARRANGE.
ExLimitText Limits how much text the user can type or paste.
ExLineFromChar Returns the line that holds a character.
ExSetSel Selects a range of characters.
FindText Finds text and returns where it starts.
FindTextEx Finds text and returns the range it covers.
FindWordBreak Finds the next word break, or classifies a character.
FirstVisibleLine, GetFirstVisibleLine Return the topmost visible line.
FormatRange Formats, measures or draws a range of text for a device.
CharFromPos, GetCharFromPos Return the character nearest a point.
IMECompMode, GetIMECompMode Return the current IME composition mode.
GetIMEColor, SetIMEColor Read or set the IME composition colours.
IMEProperty, GetIMEProperty Return a property of the current IME.
GetLine Returns the text of one line.
GetOleInterface Returns the control's IRichEditOle interface.
GetSel Returns the start and end of the selection.
SetSel Selects a range of characters.
CaretPos, GetCaretPos, SetCaretPos Read or move the caret.
GetSelText Returns the selected text.
WordWrapMode, GetWordWrapMode, SetWordWrapMode Read or set the word-wrap and word-break options.
GetZoom, SetZoom Read or set the zoom ratio.
GetTableParams, SetTableParams Read or change the parameters of table rows and cells.
GetTextEx Copies the text into a buffer, in a code page of your choice.
GetRawTextLength Returns the size of the buffer GetRawText uses.
GetRawText Returns the text as stored, in the ANSI code page.
SaveRawText Writes GetRawText to a file.
SetTextEx Sets, inserts or replaces text, plain or RTF.
InsertText Inserts text at the caret or at a position.
ReplaceText Replaces a range of text.
GetThumb Returns the position of the vertical scroll box.
WordBreakProc, GetWordBreakProc, SetWordBreakProc Read or replace the word-break procedure.
WordBreakProcEx, GetWordBreakProcEx, SetWordBreakProcEx Read or replace the extended word-break procedure.
HideSelection Hides or shows the selection highlight.
GetIMECompText Copies the IME composition text.
InsertImage Replaces the selection with an image.
InsertTable Inserts table rows with empty cells.
IsIME Says whether the input locale is East Asian.
GetLineCount Returns the number of lines.
LineFromChar Returns the line that holds a character.
LineIndex Returns the position of the first character of a line.
LineLength Returns the length of a line.
LineScroll Scrolls the text up or down by lines.
PasteSpecial Pastes one clipboard format.
PosFromChar Returns where a character is drawn.
Reconversion Opens the IME reconversion window.
ReplaceSel Replaces the selection with text.
RequestResize Asks the control to send EN_REQUESTRESIZE.
Scroll Scrolls by a line or a page.
ScrollCaret Scrolls the caret into view.
SelectionType Says what the selection contains.
SetBkgndColor Sets the background colour.
SetFontSize Makes the selected text larger or smaller.
Margins, SetMargins Set the left and right margins.
LeftMargin, SetLeftMargin Set the left margin.
RightMargin, SetRightMargin Set the right margin.
SetOleCallback Gives the control an IRichEditOleCallback object.
SetPalette Sets the palette the control draws with.
SetReadOnly Makes the control read-only or editable.
SetTabStops Sets the tab stops.
SetTargetDevice Sets the device and line width text is formatted for.
SetUIAName Sets the control's name for UI Automation.
SetUndoLimit Sets how many actions the undo queue holds.
ShowScrollBar Shows or hides a scroll bar.
StopGroupTyping Ends the current typing undo action.
StreamIn Reads text or RTF from a callback.
StreamOut Writes the text or RTF to a callback.
TextLengthEx, GetTextLengthEx Return the length of the text, counted as you choose.
GetTextRange Returns a range of text.
Redo Redoes one or more actions.
Undo Undoes one or more actions.
SuspendUndo Turns undo off and empties the undo queue.
ResumeUndo Turns undo back on.
EnableWordWrap Wraps lines at the width of the control.
DisableWordWrap Formats lines for a wide fixed width.

Reference

CanPaste

function CanPaste( byval clipformat as long ) as boolean

Says whether the control can paste the clipboard format clipformat (CF_UNICODETEXT, CF_BITMAP, a registered format …). With 0 it says whether the clipboard holds any format the control can paste.

Returns true when the format can be pasted.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
print "something to paste: "; pRichEdit->CanPaste( 0 )

Microsoft Learn: EM_CANPASTE

CanRedo

function CanRedo() as boolean

Says whether the redo queue holds an action, that is whether Redo would do anything.

Returns true when there is something to redo.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
if pRichEdit->CanRedo() then pRichEdit->Redo()

Microsoft Learn: EM_CANREDO

CanUndo

function CanUndo() as boolean

Says whether the undo queue holds an action, that is whether Undo would do anything. Text set with SetText does not go into the queue.

Returns true when there is something to undo.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
if pRichEdit->CanUndo() then pRichEdit->Undo()

Microsoft Learn: EM_CANUNDO

CallAutocorrectProc

function CallAutocorrectProc( byval char as WCHAR ) as long

Calls the autocorrect procedure set with SetAutoCorrectProc, as if the user had just typed char, provided the text before the insertion point is a candidate for correction.

Returns the control's answer to the message; it was 1 in a control with no autocorrect procedure set.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
pRichEdit->CallAutocorrectProc( asc( " " ) )

Microsoft Learn: EM_CALLAUTOCORRECTPROC

DisplayBand

function DisplayBand( byref rc as .RECT ) as boolean

Draws the text formatted by a FormatRange call with fRender set to false into the rectangle rc of that call's device context. Use it to print a page in bands.

Returns true on success.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
dim rcBand as RECT = type( 0, 0, 1440 * 6, 1440 )     ' twips
pRichEdit->DisplayBand( rcBand )

Microsoft Learn: EM_DISPLAYBAND

EmptyUndoBuffer

sub EmptyUndoBuffer()

Empties the undo and redo queues, so CanUndo and CanRedo return false until the next edit or undo. Call it after loading a document, so that the first undo does not remove it.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
pRichEdit->SetText( "A fresh document" )
pRichEdit->EmptyUndoBuffer()

Microsoft Learn: EM_EMPTYUNDOBUFFER

ExGetSel

function ExGetSel() as CHARRANGE
sub ExGetSel( byref cpMin as long, byref cpMax as long )

Reads the selection. cpMin is the first selected character and cpMax the position after the last one; when nothing is selected both are the caret position.

The first form returns both in a CHARRANGE. The second writes the start into cpMin and the end in cpMax.

Returns the selection (first form).

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
dim cr as CHARRANGE = pRichEdit->ExGetSel()
print "selected"; cr.cpMax - cr.cpMin; " characters from"; cr.cpMin

Microsoft Learn: EM_EXGETSEL

ExLimitText

sub ExLimitText( byval dwLimit as DWORD )

Sets the most characters the user can type or paste into the control; 0 restores the default of 64K characters. Text the program puts in is not held to it: SetText and ReplaceSel both went past a limit of 5.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
pRichEdit->ExLimitText( 1024 * 1024 )     ' a megabyte of characters

Microsoft Learn: EM_EXLIMITTEXT

ExLineFromChar

function ExLineFromChar( byval iIndex as long ) as long

Returns the zero-based line that holds the character at position iIndex. -1 gives the line of the caret, or of the start of the selection.

Returns the line number.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
print "the caret is on line"; pRichEdit->ExLineFromChar( -1 ) + 1

Microsoft Learn: EM_EXLINEFROMCHAR

ExSetSel

function ExSetSel( byref cr as CHARRANGE ) as DWORD
sub ExSetSel( byval cpMin as long = 0, byval cpMax as long = -1 )

Selects the characters from cpMin up to, not including, cpMax. (0, -1), the second form's default, selects everything; equal values put the caret there with nothing selected; a cpMin of -1 removes the selection and leaves the caret where it is. The control does not scroll: call ScrollCaret to bring the selection into view.

Returns first form: the end of the selection the control actually set, the higher of the two positions (3 for 1 to 3, and 4 for 4 to 2).

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
pRichEdit->ExSetSel()            ' select all
pRichEdit->ExSetSel( 4, 7 )      ' characters 4, 5 and 6

Microsoft Learn: EM_EXSETSEL

FindText

function FindText( byval fOptions as DWORD, byref ftw as FINDTEXTW ) as long
function FindText( byval fOptions as DWORD = FR_DOWN, byval cpMin as long = 0, byval cpMax as long = -1, byref wszText as wstring ) as long

Searches the text for wszText between cpMin and cpMax (-1: to the end). The second form fills the FINDTEXTW for you; the first takes one you filled.

Parameter Meaning
fOptions FR_DOWN to search forward from cpMin; without it the search goes backward from cpMin towards cpMax. Add FR_MATCHCASE and FR_WHOLEWORD as needed.
cpMin, cpMax The range to search.
wszText The text to find.

Returns the position where the match starts, or -1 when there is none. With the text "one two three", searching for "two" returned 4 and a whole-word search for "on" returned -1.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
dim nPos as long = pRichEdit->FindText( FR_DOWN or FR_MATCHCASE, 0, -1, "Total" )
if nPos >= 0 then pRichEdit->ExSetSel( nPos, nPos + 5 )

Microsoft Learn: EM_FINDTEXTW

FindTextEx

function FindTextEx( byval fOptions as DWORD, byref ftexw as FINDTEXTEXW ) as long
function FindTextEx( byval fOptions as DWORD = FR_DOWN, byval cpMin as long = 0, byval cpMax as long = -1, byref wszText as wstring ) as CHARRANGE

Searches like FindText and also reports the range the match covers, ready for ExSetSel. The first form returns the start and puts the range in ftexw.chrgText; the second returns the range itself.

Returns the range of the match (second form), (-1, -1) when there is none; the start of the match or -1 (first form).

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
dim found as CHARRANGE = pRichEdit->FindTextEx( FR_DOWN, 0, -1, "line" )
if found.cpMin <> -1 then pRichEdit->ExSetSel( found.cpMin, found.cpMax )

Microsoft Learn: EM_FINDTEXTEXW

FindWordBreak

function FindWordBreak( byval fOperation as DWORD, byval dwStartPos as DWORD ) as DWORD

Finds the next word break before or after the position dwStartPos, or says what kind of character is there, using the control's word-break rules.

Parameter Meaning
fOperation WB_MOVEWORDRIGHT / WB_MOVEWORDLEFT (start of the next / previous word), WB_RIGHT / WB_LEFT (next / previous break), WB_ISDELIMITER, WB_CLASSIFY …
dwStartPos The position to start from.

Returns a position, or for WB_ISDELIMITER nonzero when the character is a delimiter. In "one two three", WB_MOVEWORDRIGHT from 0 returned 4.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
dim nNext as DWORD = pRichEdit->FindWordBreak( WB_MOVEWORDRIGHT, pRichEdit->GetCaretPos() )
pRichEdit->SetCaretPos( nNext )

Microsoft Learn: EM_FINDWORDBREAK

FirstVisibleLine, GetFirstVisibleLine

property FirstVisibleLine() as long
function GetFirstVisibleLine() as long

Return the zero-based number of the topmost line the control shows.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
print "top line:"; pRichEdit->FirstVisibleLine + 1

Microsoft Learn: EM_GETFIRSTVISIBLELINE

FormatRange

function FormatRange( byval fRender as long, byref fr as FORMATRANGE ) as DWORD

Lays out the characters fr.chrg for the device context fr.hdc in the rectangle fr.rc (twips), as for printing. With fRender nonzero the text is drawn; with false it is only measured, for DisplayBand to draw later.

The control keeps information between calls. When you are done, free it by sending the message with no structure, which this member cannot do: call richedit.RichEdit.FormatRange( hRichEdit, false, NULL ) (the RichEdit functions are written with the module name in front, since RichEdit alone names the module).

Returns the position of the first character that did not fit, where the next page starts.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
dim hdcPrn as HDC = GetDC( hwnd )
dim fr as FORMATRANGE
fr.hdc = hdcPrn : fr.hdcTarget = hdcPrn
fr.rc = type( 0, 0, 1440 * 6, 1440 * 9 ) : fr.rcPage = fr.rc : fr.chrg = type( 0, -1 )
print "the next page starts at"; pRichEdit->FormatRange( false, fr )
richedit.RichEdit.FormatRange( pRichEdit->hRichEdit, false, NULL ) : ReleaseDC( hwnd, hdcPrn )

Microsoft Learn: EM_FORMATRANGE

CharFromPos, GetCharFromPos

property CharFromPos( byref ptl as .POINTL ) as long
function GetCharFromPos( byref ptl as .POINTL ) as long

Return the position of the character nearest the point ptl, in client coordinates. The reverse of PosFromChar.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
dim ptl as POINTL = type( 20, 40 )
print "character under (20, 40):"; pRichEdit->GetCharFromPos( ptl )

Microsoft Learn: EM_CHARFROMPOS

IMECompMode, GetIMECompMode

property IMECompMode() as DWORD
function GetIMECompMode() as DWORD

Return the composition mode of the Input Method Editor: ICM_NOTOPEN (0) when no IME is open, otherwise ICM_LEVEL3, ICM_LEVEL2, ICM_LEVEL2_5, ICM_LEVEL2_SUI or ICM_CTF.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
if pRichEdit->IMECompMode <> ICM_NOTOPEN then print "an IME is composing"

Microsoft Learn: EM_GETIMECOMPMODE

GetIMEColor, SetIMEColor

function GetIMEColor( byval rgCmpclr as .COMPCOLOR ptr ) as long
function SetIMEColor( byval pcompcolor as .COMPCOLOR ptr ) as long

Read or set the colours the control uses for IME composition text: an array of four COMPCOLOR, one for each composition state. These apply to East Asian versions of Windows.

Returns nonzero on success.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
dim cc(0 to 3) as COMPCOLOR
if pRichEdit->GetIMEColor( @cc(0) ) then print hex( cc(0).crText )

Microsoft Learn: EM_GETIMECOLOR, EM_SETIMECOLOR

IMEProperty, GetIMEProperty

property IMEProperty( byval figp as DWORD ) as DWORD
function GetIMEProperty( byval figp as DWORD ) as DWORD

Return one property of the IME of the current input locale: figp is IGP_PROPERTY, IGP_CONVERSION, IGP_SENTENCE, IGP_UI, IGP_SETCOMPSTR, IGP_SELECT or IGP_GETIMEVERSION.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
print "IME properties: "; hex( pRichEdit->GetIMEProperty( IGP_PROPERTY ) )

Microsoft Learn: EM_GETIMEPROPERTY

GetLine

function GetLine( byval which as DWORD ) as ustring

Returns the text of line which, as the control shows it. The line ends with the carriage return of its paragraph when it has one, and the last line ends with the final paragraph mark, so for "one" / "two" / "third" the three lines are 4, 4 and 6 characters long. A wrapped line has no carriage return. A line number past the end gives "". At most 32 765 characters are read.

Returns the line.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
dim uLine as ustring = pRichEdit->GetLine( 0 )
print "first line: "; rtrim( uLine, chr(13) )

Microsoft Learn: EM_GETLINE

GetOleInterface

function GetOleInterface() as IRichEditOle ptr

Returns the control's IRichEditOle interface, for working with the objects embedded in the text. The interface comes with a reference you own: call Release on it when you are done.

Returns the interface, or NULL on failure.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
dim pOle as IRichEditOle ptr = pRichEdit->GetOleInterface()
if pOle then print "objects:"; pOle->lpVtbl->GetObjectCount( pOle ) : pOle->lpVtbl->Release( pOle )

Microsoft Learn: EM_GETOLEINTERFACE

GetSel

function GetSel( byref dwStartPos as DWORD, byref dwEndPos as DWORD ) as long
function GetSel() as .POINTL

Read the selection: the first selected character and the position after the last one, both the caret position when nothing is selected. The first form writes them into dwStartPos and dwEndPos; the second returns them as x (start) and y (end) of a POINTL.

Returns the second form, the selection. The first form returns both positions packed in one value, the start in the low word and the end in the high word (&h70004 for 4 to 7), and -1 once a position is above 65 535; read the two variables instead.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
dim pt as POINTL = pRichEdit->GetSel()
print "selection:"; pt.x; " to"; pt.y

Microsoft Learn: EM_GETSEL

SetSel

sub SetSel( byval nStart as long, byval nEnd as long )
sub SetSel( byref pt as POINTL )

Selects from nStart to nEnd, or from pt.x to pt.y. (0, -1) selects everything; a start of -1 removes the selection. The two positions may come in either order.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
pRichEdit->SetSel( 0, -1 )

Microsoft Learn: EM_SETSEL

CaretPos, GetCaretPos, SetCaretPos

property CaretPos() as DWORD
property CaretPos( byval dwPos as DWORD )
function GetCaretPos() as DWORD
sub SetCaretPos( byval dwPos as DWORD )

Read or move the caret. Reading gives the start of the selection, the lower of its two ends. Setting removes the selection and puts the caret before the character at dwPos; -1 puts it at the end of the text.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
pRichEdit->CaretPos = -1          ' to the end
pRichEdit->ScrollCaret()

Microsoft Learn: EM_SETSEL

GetSelText

function GetSelText() as ustring

Returns the selected text, with a carriage return at each paragraph break. Selecting everything in "one" / "two" gives "one", chr(13), "two": the final paragraph mark is not included.

Returns the text, or "" when nothing is selected.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
dim uSel as ustring = pRichEdit->GetSelText()
if len( uSel ) then print "selected: "; uSel

Microsoft Learn: EM_GETSELTEXT

WordWrapMode, GetWordWrapMode, SetWordWrapMode

property WordWrapMode() as DWORD
property WordWrapMode( byval values as DWORD ) as DWORD
function GetWordWrapMode() as DWORD
function SetWordWrapMode( byval values as DWORD ) as DWORD

Read or set the word-wrap and word-break options used for East Asian text: a combination of WBF_WORDWRAP, WBF_WORDBREAK, WBF_OVERFLOW, WBF_LEVEL1, WBF_LEVEL2 and WBF_CUSTOM. A new control reports 0. These options do not turn wrapping of ordinary text on or off; that is EnableWordWrap and SetTargetDevice.

Returns the options.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
pRichEdit->SetWordWrapMode( WBF_WORDWRAP or WBF_WORDBREAK )
print hex( pRichEdit->GetWordWrapMode() )

Microsoft Learn: EM_GETWORDWRAPMODE, EM_SETWORDWRAPMODE

GetZoom, SetZoom

function GetZoom( byref pzNum as DWORD, byref pzDen as DWORD ) as long
function SetZoom( byval zNum as DWORD, byval zDen as DWORD ) as long

Read or set the zoom as the ratio zNum / zDen, which must lie between 1/64 and 64. SetZoom( 0, 0 ) turns zooming off, and GetZoom then reads 0 / 0.

Returns nonzero on success.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
pRichEdit->SetZoom( 150, 100 )          ' 150 %
dim as DWORD zNum, zDen
if pRichEdit->GetZoom( zNum, zDen ) then print zNum; "/"; zDen

Microsoft Learn: EM_GETZOOM, EM_SETZOOM

GetTableParams, SetTableParams

function GetTableParams( byref tp as TABLEROWPARMS, byref tcp as TABLECELLPARMS ) as DWORD
function SetTableParams( byref tp as TABLEROWPARMS, byref tcp as TABLECELLPARMS ) as DWORD

Read or change the parameters of a table row (tp) and its cells (tcp, the first of an array of tp.cCell cells). Set tp.cbRow and tp.cbCell to the sizes of the two structures and tp.cpStartRow to a position in the row first. After InsertTable made three 1440-twip cells, reading the row at 0 gave 3 cells, the first 1440 wide.

Returns an HRESULT: S_OK (0) on success.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
dim tp as TABLEROWPARMS : tp.cbRow = sizeof( TABLEROWPARMS ) : tp.cbCell = sizeof( TABLECELLPARMS )
tp.cCell = 3 : tp.cpStartRow = 0
dim cells(0 to 2) as TABLECELLPARMS
if pRichEdit->GetTableParams( tp, cells(0) ) = S_OK then print "first cell width:"; cells(0).dxWidth

Microsoft Learn: EM_GETTABLEPARMS, EM_SETTABLEPARMS

GetTextEx

function GetTextEx( byref gtex as .GETTEXTEX, byval buffer as any ptr ) as DWORD

Copies the text into buffer, converted to the code page gtex.codepage (1200 for UTF-16, CP_UTF8, CP_ACP …). gtex.cb is the size of the buffer in bytes; GT_USECRLF in gtex.flags turns each paragraph break into CR/LF, GT_SELECTION copies only the selection.

Returns the number of characters copied, the terminating null not counted.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
dim wszBuf as wstring * 1024
dim gtex as GETTEXTEX : gtex.cb = sizeof( wszBuf ) : gtex.flags = GT_USECRLF : gtex.codepage = 1200
print pRichEdit->GetTextEx( gtex, @wszBuf ); " characters: "; wszBuf

Microsoft Learn: EM_GETTEXTEX

GetRawTextLength

function GetRawTextLength() as long

Returns the length GetRawText makes its buffer. The flags it sends ask the control for a quick estimate in the ANSI code page rather than an exact count, and the estimate is generous: for 31 characters of plain text it was 62.

Returns the estimate, in bytes.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
print "raw buffer:"; pRichEdit->GetRawTextLength(); " bytes"

Microsoft Learn: EM_GETTEXTLENGTHEX

GetRawText

function GetRawText() as string

Returns the text exactly as the control stores it (GT_RAWTEXT), in the ANSI code page.

Returns the buffer.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
dim sRaw as string = pRichEdit->GetRawText()

Microsoft Learn: EM_GETTEXTEX

SaveRawText

function SaveRawText( byref wszFilename as wstring, byval Overwrite as boolean = false, byval dwFlagsAndAttributes as DWORD = FILE_ATTRIBUTE_NORMAL ) as boolean

Writes the whole string GetRawText returns to the file wszFilename, null byte and padding included: "abc" was saved as six bytes, a, b, c, a null and two spaces.

Parameter Meaning
wszFilename The file to write.
Overwrite true replaces an existing file; with false (the default) an existing file makes the call fail.
dwFlagsAndAttributes The attributes of a new file.

Returns true on success. On failure false, and GetLastResult() holds the Windows error code: 80 (ERROR_FILE_EXISTS) when the file is there and Overwrite is false.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
if pRichEdit->SaveRawText( "notes.txt", true ) = false then print "error"; pRichEdit->GetLastResult()

Microsoft Learn: CreateFileW

SetTextEx

function SetTextEx( byref strText as string ) as DWORD
function SetTextEx( byref wszText as wstring ) as DWORD
function SetTextEx( byref stex as .SETTEXTEX, byval buffer as any ptr ) as DWORD
function SetTextEx( byref stex as .SETTEXTEX, byref strText as string ) as DWORD
function SetTextEx( byref stex as .SETTEXTEX, byref wszText as wstring ) as DWORD
function SetTextEx( byval nStart as long, byval nEnd as long, byref strText as string ) as DWORD
function SetTextEx( byval nStart as long, byval nEnd as long, byref wszText as wstring ) as DWORD
function SetTextEx( byval nPos as long, byref strText as string ) as DWORD
function SetTextEx( byval nPos as long, byref wszText as wstring ) as DWORD

Puts text into the control. The text may be plain or RTF (it is RTF when it starts with {\rtf).

  • With a SETTEXTEX, the forms send the text as they are told: stex.flags says whether it replaces everything (ST_DEFAULT) or the selection (ST_SELECTION) and whether the edit can be undone (ST_KEEPUNDO); stex.codepage is the code page of the text, 1200 for a wstring.
  • With only text, the text is inserted at the caret: the selection is first reduced to its start, so nothing selected is replaced.
  • With nPos, the text is inserted at that position; with nStart and nEnd, it replaces that range.

The forms without a SETTEXTEX replace a selection and keep the undo queue, so the edit can be undone; their string forms read the text in the ANSI code page (see Unicode above). The same calls are also named InsertText and ReplaceText.

Returns the number of characters put in when a selection was replaced (3 for "def", 14 for the RTF below); 1 when all the text was set.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
dim stex as SETTEXTEX : stex.flags = ST_SELECTION : stex.codepage = CP_ACP
pRichEdit->SetTextEx( stex, "{\rtf1 Some {\b bold} text}" )

Microsoft Learn: EM_SETTEXTEX

InsertText

function InsertText( byref strText as string ) as DWORD
function InsertText( byref wszText as wstring ) as DWORD
function InsertText( byval nPos as long, byref strText as string ) as DWORD
function InsertText( byval nPos as long, byref wszText as wstring ) as DWORD

Inserts text at the caret, or at the position nPos, as an edit that can be undone. A selection is not replaced: the text goes in before it. With "abc" and the caret at 1, inserting "Z" gave "aZbc" and left the caret at 2.

Returns the number of characters inserted.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
dim wszStamp as wstring * 32 = "Checked ✓ "
pRichEdit->InsertText( 0, wszStamp )

Microsoft Learn: EM_SETTEXTEX

ReplaceText

function ReplaceText( byval nStart as long, byval nEnd as long, byref strText as string ) as DWORD
function ReplaceText( byval nStart as long, byval nEnd as long, byref wszText as wstring ) as DWORD

Replaces the characters from nStart up to nEnd with the text, as an edit that can be undone, and leaves the caret after the new text: replacing 1 to 3 of "abcdef" with "XY" left it at 3.

Returns the number of characters put in.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
dim found as CHARRANGE = pRichEdit->FindTextEx( FR_DOWN, 0, -1, "colour" )
if found.cpMin <> -1 then pRichEdit->ReplaceText( found.cpMin, found.cpMax, "color" )

Microsoft Learn: EM_SETTEXTEX

GetThumb

function GetThumb() as long

Returns the position of the scroll box in the vertical scroll bar; 0 when the text is not scrolled.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
print "scroll box at"; pRichEdit->GetThumb()

Microsoft Learn: EM_GETTHUMB

WordBreakProc, GetWordBreakProc, SetWordBreakProc

property WordBreakProc() as LONG_PTR
property WordBreakProc( byval pfn as LONG_PTR )
function GetWordBreakProc() as LONG_PTR
sub SetWordBreakProc( byval pfn as LONG_PTR )

Read or replace the procedure the control calls to find word breaks, for double-click selection, Ctrl+arrow moves and wrapping. Pass the address of an EDITWORDBREAKPROC function; reading gives 0 while the control uses its own rules.

Example

' a word ends only at a space
function SpaceBreak( byval lpch as WCHAR ptr, byval ichCurrent as long, byval cch as long, byval code as long ) as long
    dim i as long = ichCurrent
    select case code
        case WB_ISDELIMITER : return iif( lpch[i] = 32, 1, 0 )
        case WB_LEFT : do while i > 0 andalso lpch[i - 1] <> 32 : i -= 1 : loop
        case else : do while i < cch andalso lpch[i] <> 32 : i += 1 : loop
    end select
    return i
end function

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
pRichEdit->SetWordBreakProc( cast( LONG_PTR, @SpaceBreak ) )

Microsoft Learn: EM_SETWORDBREAKPROC, EM_GETWORDBREAKPROC

WordBreakProcEx, GetWordBreakProcEx, SetWordBreakProcEx

property WordBreakProcEx() as LONG_PTR
property WordBreakProcEx( byval pfn as LONG_PTR )
function GetWordBreakProcEx() as LONG_PTR
function SetWordBreakProcEx( byval pfn as LONG_PTR ) as LONG_PTR

Read or replace the extended word-break procedure, an EDITWORDBREAKPROCEX that also receives the character set of the text. Reading gives 0 when none is set.

Returns SetWordBreakProcEx: the address of the previous procedure.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
if pRichEdit->GetWordBreakProcEx() = 0 then print "the control's own word breaks"

Microsoft Learn: EM_SETWORDBREAKPROCEX, EM_GETWORDBREAKPROCEX

HideSelection

sub HideSelection( byval fHide as DWORD )

Hides the selection highlight (fHide nonzero) or shows it again (0). The selection itself does not change.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
pRichEdit->HideSelection( true )

Microsoft Learn: EM_HIDESELECTION

GetIMECompText

function GetIMECompText( byref ict as .IMECOMPTEXT, byval buffer as any ptr ) as DWORD

Copies the IME composition text into buffer. Set ict.cb to the size of the buffer in bytes and ict.flags to ICT_RESULTREADSTR.

Returns the number of characters copied.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
dim wszComp as wstring * 256
dim ict as IMECOMPTEXT : ict.cb = sizeof( wszComp ) : ict.flags = ICT_RESULTREADSTR
pRichEdit->GetIMECompText( ict, @wszComp )

Microsoft Learn: EM_GETIMECOMPTEXT

InsertImage

function InsertImage( byref ip as RICHEDIT_IMAGE_PARAMETERS ) as DWORD
function InsertImage( byref wszFileName as wstring, byval xWidth as long = 0, byval yHeight as long = 0, byval Ascent as long = 0, byval nType as long = TA_BASELINE, byref wszAlternateText as wstring = "" ) as boolean

Replaces the selection with an image, which then counts as one character. The first form takes a RICHEDIT_IMAGE_PARAMETERS you filled, with an IStream on the image and sizes in HiMetric. The second opens the file wszFileName (PNG, JPEG, GIF, BMP …) and fills the structure for you.

Parameter Meaning
wszFileName The image file.
xWidth, yHeight The size in pixels. When both are 0 the image's own size is read from the file; when only one is 0 it stays 0. Both are multiplied by the control's ScalingRatio.
Ascent For TA_BASELINE, how far the image rises above the baseline, in pixels.
nType Where the image sits on the line: TA_BASELINE, TA_BOTTOM or TA_TOP.
wszAlternateText Text that stands for the image, for screen readers.

Returns first form: an HRESULT, S_OK on success. Second form: true on success; on failure false, and GetLastResult() holds the HRESULT.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
pRichEdit->CaretPos = -1
if pRichEdit->InsertImage( "logo.png", 0, 0, 0, TA_BASELINE, "Company logo" ) = false then print "no image"

Microsoft Learn: EM_INSERTIMAGE, SHCreateStreamOnFileEx

InsertTable

function InsertTable( byref tp as TABLEROWPARMS, byref tcp as TABLECELLPARMS ) as DWORD

Inserts tp.cRow identical rows of tp.cCell empty cells. Set tp.cbRow and tp.cbCell to the structure sizes and tp.cpStartRow to -1 to insert at the selection; with tp.fIdentCells set to 1, tcp describes every cell, otherwise it is the first of tp.cCell cells. Widths are in twips.

Returns an HRESULT: S_OK (0) on success, E_INVALIDARG when the structures do not add up.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
dim tp as TABLEROWPARMS : tp.cbRow = sizeof( TABLEROWPARMS ) : tp.cbCell = sizeof( TABLECELLPARMS )
tp.cRow = 2 : tp.cCell = 3 : tp.dxCellMargin = 100 : tp.cpStartRow = -1 : tp.fIdentCells = 1
dim tcp as TABLECELLPARMS : tcp.dxWidth = 1440      ' one inch
pRichEdit->InsertTable( tp, tcp )

Microsoft Learn: EM_INSERTTABLE

IsIME

function IsIME() as long

Says whether the current input locale is an East Asian one, that uses an IME.

Returns nonzero for an East Asian locale.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
if pRichEdit->IsIME() then print "East Asian input locale"

Microsoft Learn: EM_ISIME

GetLineCount

function GetLineCount() as long

Returns the number of lines, as the control shows them; an empty control has one.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
print pRichEdit->GetLineCount(); " lines"

Microsoft Learn: EM_GETLINECOUNT

LineFromChar

function LineFromChar( byval index as DWORD ) as long

Returns the line that holds the character at index; -1 gives the line of the caret. The same as ExLineFromChar.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
print "line"; pRichEdit->LineFromChar( pRichEdit->GetCaretPos() ) + 1

Microsoft Learn: EM_LINEFROMCHAR

LineIndex

function LineIndex( byval nLine as long ) as long

Returns the position of the first character of line nLine; -1 gives the start of the caret's line. Subtract it from a position to get the column.

Returns the position, or -1 when there is no such line.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
dim nPos as long = pRichEdit->GetCaretPos()
print "column"; nPos - pRichEdit->LineIndex( -1 ) + 1

Microsoft Learn: EM_LINEINDEX

LineLength

function LineLength( byval index as DWORD ) as long

Returns the length of the line that holds the character at index (a position, not a line number), without its paragraph break.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
print "line 2 is"; pRichEdit->LineLength( pRichEdit->LineIndex( 1 ) ); " characters long"

Microsoft Learn: EM_LINELENGTH

LineScroll

function LineScroll( byval y as long ) as long

Scrolls the text y lines, down for a positive number and up for a negative one.

Returns nonzero on success.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
pRichEdit->LineScroll( 10 )

Microsoft Learn: EM_LINESCROLL

PasteSpecial

sub PasteSpecial( byval clpfmt as DWORD, byref rps as REPASTESPECIAL )
sub PasteSpecial( byval clpfmt as DWORD, byval dwAspect as DWORD, byval hMF as HMETAFILE )

Pastes the clipboard in the format clpfmt only, such as CF_UNICODETEXT to paste plain text. rps, or dwAspect and hMF, say how an object is shown: DVASPECT_CONTENT for its content, DVASPECT_ICON for an icon, with the metafile hMF as the picture.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
pRichEdit->PasteSpecial( CF_UNICODETEXT, DVASPECT_CONTENT, NULL )     ' paste without formatting

Microsoft Learn: EM_PASTESPECIAL

PosFromChar

function PosFromChar( byval index as DWORD ) as .POINTL

Returns the client coordinates of the top-left corner of the character at index. The reverse of CharFromPos.

Returns the point.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
dim pt as POINTL = pRichEdit->PosFromChar( pRichEdit->GetCaretPos() )
print "the caret is at"; pt.x; ","; pt.y

Microsoft Learn: EM_POSFROMCHAR

Reconversion

sub Reconversion()

Opens the IME reconversion window for the selected text, on an East Asian input locale.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
if pRichEdit->IsIME() then pRichEdit->Reconversion()

Microsoft Learn: EM_RECONVERSION

ReplaceSel

sub ReplaceSel( byval bCanBeUndone as long = true, byref wszText as wstring )

Replaces the selection with wszText, or inserts it at the caret when nothing is selected, and leaves the caret after it. With bCanBeUndone nonzero the edit goes into the undo queue. Both arguments are needed, since the default comes first.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
pRichEdit->ReplaceSel( true, "replacement" )

Microsoft Learn: EM_REPLACESEL

RequestResize

sub RequestResize()

Makes the control send its parent an EN_REQUESTRESIZE notification with the size its contents need. The notification comes only when ENM_REQUESTRESIZE is in the event mask.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
pRichEdit->SetEventMask( pRichEdit->GetEventMask() or ENM_REQUESTRESIZE )
pRichEdit->RequestResize()

Microsoft Learn: EM_REQUESTRESIZE

Scroll

function Scroll( byval nAction as long ) as long

Scrolls the text vertically, as the scroll bar does: nAction is SB_LINEUP, SB_LINEDOWN, SB_PAGEUP or SB_PAGEDOWN.

Returns on success, true in the high word and the number of lines scrolled in the low word.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
print "scrolled"; LOWORD( pRichEdit->Scroll( SB_PAGEDOWN ) ); " lines"

Microsoft Learn: EM_SCROLL

ScrollCaret

sub ScrollCaret()

Scrolls the text so that the caret is visible. Selecting text from code does not scroll; call this afterwards.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
pRichEdit->ExSetSel( 5000, 5010 )
pRichEdit->ScrollCaret()

Microsoft Learn: EM_SCROLLCARET

SelectionType

function SelectionType() as long

Says what the selection holds: SEL_EMPTY (0) when nothing is selected, otherwise a combination of SEL_TEXT (1), SEL_OBJECT (2), SEL_MULTICHAR (4) and SEL_MULTIOBJECT (8). One selected character gave 1, three gave 5, an image gave 2.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
if pRichEdit->SelectionType() and SEL_OBJECT then print "an object is selected"

Microsoft Learn: EM_SELECTIONTYPE

SetBkgndColor

function SetBkgndColor( byval pSysColor as DWORD, byval pBkColor as DWORD ) as DWORD

Sets the background colour. With pSysColor nonzero the control uses the system window colour and pBkColor is ignored; with 0 it uses pBkColor, a COLORREF.

Returns the previous background colour (&hFFFFFF, white, for a new control).

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
pRichEdit->SetBkgndColor( 0, BGR( 255, 255, 224 ) )     ' light yellow

Microsoft Learn: EM_SETBKGNDCOLOR

SetFontSize

function SetFontSize( byval ptsize as long ) as long

Makes the selected text larger or smaller. ptsize is a change, not a size: positive makes the text larger, negative smaller, and the control rounds the result to its own steps. Text of 8.25 points became 10 with +2, then 22 with +12, then 18 with -4. To set an exact size use SetTextHeight.

Returns nonzero on success.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
pRichEdit->SetFontSize( 2 )      ' one step larger

Microsoft Learn: EM_SETFONTSIZE

Margins, SetMargins

property Margins( byval nMargins as long, byval nWidth as long )
sub SetMargins( byval nMargins as long, byval nWidth as long )

Set the left and right margins, in pixels, and redraw the control. nMargins says which: EC_LEFTMARGIN, EC_RIGHTMARGIN or both. nWidth holds the left margin in its low word and the right margin in its high word. The property is written Margins( nMargins ) = nWidth.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
pRichEdit->SetMargins( EC_LEFTMARGIN or EC_RIGHTMARGIN, MAKELONG( 8, 8 ) )

Microsoft Learn: EM_SETMARGINS

LeftMargin, SetLeftMargin

property LeftMargin( byval nWidth as long )
sub SetLeftMargin( byval nWidth as long )

Set the left margin to nWidth pixels; the right margin stays as it is. The value is not scaled for DPI.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
pRichEdit->LeftMargin = 60

Microsoft Learn: EM_SETMARGINS

RightMargin, SetRightMargin

property RightMargin( byval nWidth as long )
sub SetRightMargin( byval nWidth as long )

Set the right margin to nWidth pixels; the left margin stays as it is. The value is not scaled for DPI.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
pRichEdit->SetRightMargin( 60 )

Microsoft Learn: EM_SETMARGINS

SetOleCallback

function SetOleCallback( byval pCallback as any ptr ) as long

Gives the control an IRichEditOleCallback object, which it asks for storage and menus when objects and images are pasted, dropped or inserted. CRichEditOleCallback is a ready-made one. Create it with new: the control releases it when it is destroyed, and its last Release deletes it.

Returns nonzero on success.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
pRichEdit->SetOleCallback( new CRichEditOleCallback )   ' the control releases it

Microsoft Learn: EM_SETOLECALLBACK

SetPalette

sub SetPalette( byval newPalette as HPALETTE )

Sets the palette the control draws with, on a display limited to 256 colours.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
pRichEdit->SetPalette( cast( HPALETTE, GetStockObject( DEFAULT_PALETTE ) ) )

Microsoft Learn: EM_SETPALETTE

SetReadOnly

function SetReadOnly( byval fReadOnly as long ) as boolean

Makes the control read-only (fReadOnly nonzero), so the user can select and copy but not change the text, or editable again (0). The program can still change it: SetText and InsertText worked on a read-only control.

Returns true on success.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
pRichEdit->SetReadOnly( true )

Microsoft Learn: EM_SETREADONLY

SetTabStops

function SetTabStops( byval nTabs as long, byval rgTabStops as LONG_PTR ) as long

Sets the tab stops of the control. rgTabStops is the address of an array of nTabs long values, in dialog template units; with one value the stops repeat at that distance, and with nTabs 0 they fall back to every 32 units.

Returns nonzero when all the tab stops were set.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
dim tabs(0 to 1) as long = { 40, 120 }
pRichEdit->SetTabStops( 2, cast( LONG_PTR, @tabs(0) ) )

Microsoft Learn: EM_SETTABSTOPS

SetTargetDevice

function SetTargetDevice( byval hDC as HDC, byval lnwidth as long ) as boolean

Sets the device the text is laid out for, and the line width. With a device context, lines are lnwidth twips wide on that device, which is how a document is made to wrap as it will print. With NULL the control formats for the screen: lnwidth 0 wraps lines at the width of the control, and 1 does not wrap at all (a 5000-character paragraph stayed one line).

Returns true on success; GetLastResult() is then S_OK, and S_FALSE on failure.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
pRichEdit->SetTargetDevice( NULL, 1 )      ' no word wrap

Microsoft Learn: EM_SETTARGETDEVICE

SetUIAName

function SetUIAName( byref wszName as wstring ) as DWORD

Sets the name screen readers and other UI Automation clients report for the control.

Returns nonzero on success.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
pRichEdit->SetUIAName( "Message body" )

Microsoft Learn: EM_SETUIANAME

SetUndoLimit

function SetUndoLimit( byval maxactions as DWORD ) as DWORD

Sets how many actions the undo queue holds; the default is 100. 0 turns undo off.

Returns the new limit (50 for SetUndoLimit( 50 )).

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
pRichEdit->SetUndoLimit( 500 )

Microsoft Learn: EM_SETUNDOLIMIT

ShowScrollBar

sub ShowScrollBar( byval nScrollBar as DWORD, byval fShow as long )

Shows (fShow nonzero) or hides (0) one scroll bar: nScrollBar is SB_VERT or SB_HORZ. The control must have been created with that scroll bar.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
pRichEdit->ShowScrollBar( SB_HORZ, false )

Microsoft Learn: EM_SHOWSCROLLBAR

StopGroupTyping

function StopGroupTyping() as DWORD

Closes the undo action that is collecting the user's typing, so the next keystrokes start a new one and one undo does not take back more than you want.

Returns 0.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
pRichEdit->StopGroupTyping()     ' e.g. after each word, or on a timer

Microsoft Learn: EM_STOPGROUPTYPING

StreamIn

function StreamIn( byval psf as long, byref edst as EDITSTREAM ) as DWORD

Replaces the text, or with SFF_SELECTION the selection, with data the control asks for in pieces from the callback edst.pfnCallback. psf is SF_TEXT or SF_RTF, optionally with SF_UNICODE or SFF_SELECTION. The callback copies up to cb bytes to pbBuff, stores how many in *pcb (0 at the end) and returns 0 to go on.

Returns the number of characters read in (10 for {\rtf1 hello {\b bold}\par}).

Example

dim shared as string gRtf
dim shared as long gRead

function ReadRtf( byval dwCookie as DWORD_PTR, byval pbBuff as BYTE ptr, byval cb as long, byval pcb as long ptr ) as DWORD
    dim n as long = len( gRtf ) - gRead
    if n > cb then n = cb
    if n > 0 then memcpy( pbBuff, strptr( gRtf ) + gRead, n )
    gRead += n : *pcb = n
    return 0
end function

gRtf = "{\rtf1 Hello {\b bold} world\par}" : gRead = 0
dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
dim es as EDITSTREAM : es.pfnCallback = @ReadRtf
pRichEdit->StreamIn( SF_RTF, es )

Microsoft Learn: EM_STREAMIN

StreamOut

function StreamOut( byval psf as long, byref edst as EDITSTREAM ) as DWORD

Hands the text, or with SFF_SELECTION the selection, to the callback edst.pfnCallback in pieces. psf is SF_TEXT, SF_RTF or SF_RTFNOOBJS, optionally with SF_UNICODE. The callback receives cb bytes at pbBuff, stores in *pcb how many it took and returns 0 to go on. Plain text comes out with CR/LF at paragraph breaks.

Returns the number of characters written: 33 for 31 characters in three paragraphs as SF_TEXT.

Example

dim shared as string gOut

function WriteOut( byval dwCookie as DWORD_PTR, byval pbBuff as BYTE ptr, byval cb as long, byval pcb as long ptr ) as DWORD
    dim s as string = space( cb )
    memcpy( strptr( s ), pbBuff, cb )
    gOut &= s : *pcb = cb
    return 0
end function

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
dim es as EDITSTREAM : es.pfnCallback = @WriteOut
pRichEdit->StreamOut( SF_RTF, es )
print left( gOut, 6 )      ' {\rtf1

Microsoft Learn: EM_STREAMOUT

TextLengthEx, GetTextLengthEx

function TextLengthEx( byref gtex as .GETTEXTLENGTHEX ) as long
function TextLengthEx( byval dwFlags as DWORD = GTL_DEFAULT ) as long
function GetTextLengthEx( byref gtex as .GETTEXTLENGTHEX ) as long
function GetTextLengthEx( byval dwFlags as DWORD = GTL_DEFAULT ) as long

Return the length of the text, counted as the flags say: GTL_USECRLF counts each paragraph break as two characters, GTL_PRECISE asks for an exact count, GTL_NUMCHARS for characters and GTL_NUMBYTES for bytes. The dwFlags forms use the code page 1200 (UTF-16); the others take a GETTEXTLENGTHEX you filled.

For "one two three", "second line" and "third" in three paragraphs: GTL_DEFAULT gives 31 and GTL_NUMCHARS or GTL_USECRLF gives 33. Without GTL_NUMCHARS other flags can give bytes: GTL_USECRLF alone gave 66.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
print pRichEdit->TextLengthEx( GTL_NUMCHARS or GTL_USECRLF ); " characters with CR/LF"

Microsoft Learn: EM_GETTEXTLENGTHEX

GetTextRange

function GetTextRange( byref trg as .TEXTRANGEW ) as DWORD
function GetTextRange( byval cpMin as long = 0, byval cpMax as long = -1 ) as ustring

Returns the characters from cpMin up to cpMax, with a carriage return at each paragraph break. (0, -1), the default, returns the whole text. A cpMax of -1 works only with a cpMin of 0: any other start with -1 returns "" and sets GetLastResult() to E_INVALIDARG. Equal positions return "". The first form fills a TEXTRANGEW whose lpstrText you pointed at a buffer large enough.

Returns the text (second form); the number of characters copied (first form).

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
print "characters 4 to 6: "; pRichEdit->GetTextRange( 4, 7 )
print "from 10 to the end: "; pRichEdit->GetTextRange( 10, pRichEdit->TextLengthEx() )

Microsoft Learn: EM_GETTEXTRANGE

Redo

function Redo() as long
function Redo( byval Count as long ) as long

Redoes the next action in the redo queue, or up to Count actions. The second form goes through the control's Text Object Model document.

Returns first form: nonzero on success. Second form: the number of actions redone (2 when 5 were asked for and 2 were queued); GetLastResult() holds the HRESULT.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
print "redid"; pRichEdit->Redo( 3 ); " actions"

Microsoft Learn: EM_REDO, ITextDocument::Redo

Undo

function Undo() as long
function Undo( byval Count as long ) as long

Undoes the last action in the undo queue, or up to Count actions; what was undone moves to the redo queue. The second form goes through the control's Text Object Model document.

Returns first form: nonzero on success. Second form: the number of actions undone; GetLastResult() holds the HRESULT.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
if pRichEdit->CanUndo() then pRichEdit->Undo( 2 )

Microsoft Learn: EM_UNDO, ITextDocument::Undo

SuspendUndo

function SuspendUndo() as long

Turns undo off, with tomFalse, so that the edits that follow are not recorded. It also empties the undo queue: after SuspendUndo and ResumeUndo, CanUndo is false even though there were actions to undo before.

Returns 0; GetLastResult() holds the HRESULT.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
pRichEdit->SuspendUndo()
pRichEdit->InsertText( 0, "Generated header" & chr(13) )
pRichEdit->ResumeUndo()

Microsoft Learn: ITextDocument::Undo

ResumeUndo

function ResumeUndo() as long

Turns undo back on, with tomTrue, after SuspendUndo. The edits that follow go into the undo queue again.

Returns 0; GetLastResult() holds the HRESULT.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
pRichEdit->ResumeUndo()

Microsoft Learn: ITextDocument::Undo

EnableWordWrap

function EnableWordWrap() as boolean

Makes lines wrap at the width of the control. A control made by CRichEditCtx with the default styles has a horizontal scroll bar and does not wrap until this is called.

Returns true on success; on failure false, and GetLastResult() is S_FALSE, or E_FAIL when no device context could be had.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
pRichEdit->EnableWordWrap()

Microsoft Learn: EM_SETTARGETDEVICE

DisableWordWrap

function DisableWordWrap( byval LineWidth as long = 32767 ) as boolean

Formats lines for a fixed width of LineWidth twips on the screen, instead of the width of the control. The default, 32 767 twips, is about 22.75 inches: lines shorter than that no longer wrap, but a longer paragraph still does (5000 characters broke after 364). To stop wrapping altogether call SetTargetDevice( NULL, 1 ).

Returns true on success; on failure false, and GetLastResult() is S_FALSE, or E_FAIL when no device context could be had.

Example

dim pRichEdit as CRichEditCtx ptr = CRichEditCtxPtr( hCtrl )
pRichEdit->DisableWordWrap()

Microsoft Learn: EM_SETTARGETDEVICE

See also

Clone this wiki locally