As of 12-2003, I know of several versions of this control
Riched.dll | 236Kb 98 | This is identified as a Windows 95 version, but it is not on my Windows 95 system. It is on a Windows 98 system, has the same date, time, and version as one of the Riched32.dll files, but not the same size. |
Riched32.dll | 174Kb 95 184Kb 98 4Kb XP | This is identified as a Windows 95 version. The Windows XP version is just a wrapper for Riched20.dll. |
Riched20.dll | 288Kb 95 422Kb 98 417Kb XP | 288Kb is version 2; 422Kb and 417Kb are version 3 |
Visual Basic 6.0
The built-in help is completely worthless ... except for the sections on how to manipulate selected text.
Scrollbar control is very responsive.
There is no obvious way to disable word wrap!! (give me a break!)
It appears that the RightMargin property controls this.
0 (the default) forces word wrap.
Since the value is in twips, use a large value
(like 500000) to disable word wrap.
A related example from some c-code supplied with VB
SendMessage(predoc->hwndRE, EM_SETTARGETDEVICE, (WPARAM) predoc->hdcTarget, (LPARAM) xWidth);
SelStart | Current insertion point. Setting this forces SelLength=0, must be >=0 |
SelLength | Returns or sets the number of characters selected, must be >=0 |
SelText | Currently selected text |
SelColor | Changes (or returns) the color of the selected text. If no text is selected, it sets the color of any new text entered at the insertion point. |
Scrollbars | Controls whether the scrollbars are horizontal or vertical. Read only at run time. |
DisableNoScroll | Enables/disables scrollbars. |
AutoVerbMenu | Controls the display of the automatic Cut, Copy, Paste pop-up menu. |
The help says to use SelFontColor in one section and SelColor in another section.
Search the help for EM_ (Windows messages) and ES_ (Edit Styles)
' Edit Control Messages - from WIN32API.TXT Const EM_GETSEL = &HB0 Const EM_SETSEL = &HB1 ' Selects all text Const EM_GETRECT = &HB2 Const EM_SETRECT = &HB3 Const EM_SETRECTNP = &HB4 Const EM_SCROLL = &HB5 ' Scrolls one page or one line up or down Const EM_LINESCROLL = &HB6 ' Goes to end of file only Const EM_SCROLLCARET = &HB7 ' Seems ok Const EM_GETMODIFY = &HB8 Const EM_SETMODIFY = &HB9 Const EM_GETLINECOUNT = &HBA ' Works Const EM_LINEINDEX = &HBB Const EM_SETHANDLE = &HBC Const EM_GETHANDLE = &HBD ' Fails - the Borland help explains why Const EM_GETTHUMB = &HBE ' Fails Const EM_LINELENGTH = &HC1 Const EM_REPLACESEL = &HC2 Const EM_GETLINE = &HC4 ' Const EM_LIMITTEXT = &HC5 Const EM_CANUNDO = &HC6 Const EM_UNDO = &HC7 Const EM_FMTLINES = &HC8 Const EM_LINEFROMCHAR = &HC9 Const EM_SETTABSTOPS = &HCB Const EM_SETPASSWORDCHAR = &HCC Const EM_EMPTYUNDOBUFFER = &HCD Const EM_GETFIRSTVISIBLELINE = &HCE ' Works Const EM_SETREADONLY = &HCF Const EM_SETWORDBREAKPROC = &HD0 Const EM_GETWORDBREAKPROC = &HD1 Const EM_GETPASSWORDCHAR = &HD2
EM_GETTHUMB - to retrieve the position of the scroll box (thumb) - Fails EM_SCROLL - to scroll the text vertically - up or down one page or line EM_LINESCROLL - to scroll the text vertically or horizontally - FailsThe following always returns zero
The EM_SCROLL messages only uses 4 of the 17 ScrollBar constants
(yes, I tried all 8 unique codes).
Const SB_LINEUP = 0 ' Scrolls up one line Const SB_LINEDOWN = 1 ' Scrolls down one line Const SB_PAGEUP = 2 ' Scrolls up one page Const SB_PAGEDOWN = 3 ' Scrolls down one page
Delphi
procedure TCustomRichEdit.CreateParams(var Params: TCreateParams); const RichEditModuleName = 'RICHED32.DLL'; begin FRichEditModule := LoadLibrary(RichEditModuleName);
The LoadLibrary function explains why Depends does NOT list either Riched32.dll or Riched20.dll as one of the required modules.
Notice that this actually selects different controls depending on which operating system is used. Specifically,
UIRichEdit.SelAttributes.color := clGreen; UIRichEdit.WordWrap := false; BoldButton.Down := fsBold in RichEdit1.SelAttributes.Style; (in is not in the regular help index, search delphi.hlp This example is from the SelAttributes example) Memo1.Font.Style := [fsBold]; // Style is a set // The square bracket syntax is not explained // but it is required for sets
RichEdit1.Perform(EM_SCROLLCARET, 0, 0); // Directly send a Windows message procedure TWinControl.DefaultHandler(var Message); Result := CallWindowProc(FDefWndProc, FHandle, Msg, WParam, LParam);
property WordWrap: Boolean; procedure ScrollBy(DeltaX, DeltaY: Integer); // Values are in pixels
// Set the selection to the beginning of a line with RichEdit1 do begin SelStart := perform(em_LineIndex, spinedit1.value, 0);
When you copy text to the clipboard, several different formats may be saved.
When you paste from the clipboard, TRichEdit decides which format to use and how to render it.
The default functionality can be observed by simply placing a TRichEdit component on a blank form and running the application.
I have one web page that actually displays html tags (which I use to copy and paste to pages I write using notepad). When these are pasted, the tags are interpreted (kind of defeats the purpose).
The problem is that I just want the clipboard pasted as text with bold, italic and other crap removed. (In this case, I am using TRichEdit as a replacement for TMemo which has a size limitation - ~32K)
While I was not able to find any obvious way to control this (the ability to set a preferred clipboard format would have been nice), I was able to develop a work around. Simply deriving a new component based on TRichEdit does not work because most of the functionality is based on RICHED32.DLL (that is why copy and paste work without adding any additional code.) Instead, I used 2 menu selections and the TEditPaste action to capture the Paste keystrokes and to paste the clipboard data as text.
The following code shows how the TEditPaste action normally works - WM_PASTE instructs the dll to do whatever it wants.
procedure TEditPaste.ExecuteTarget(Target: TObject); begin GetControl(Target).PasteFromClipboard; end; procedure TCustomEdit.PasteFromClipboard; begin SendMessage(Handle, WM_PASTE, 0, 0); end;
The solution is to
procedure TForm1.EditPaste1Execute(Sender: TObject); begin SendMessage(RichEdit1.Handle, EM_PASTESPECIAL, CF_TEXT, 0); end;Normally, Actions are written to determine their targets at runtime. However, since that is not possible when code is attached to OnExecute, RichEdit1.Handle is used instead. If you need that functionality, then derive a new action from TEditPaste.
I tried several other approaches, but these did not work. For instance
Notes: When copying from notepad or a TMemo, the clipboard contained 3 formats (1, 16, 7). When pasting these, html code was not interpreted. When copying from Internet Explorer, the clipboard contained 8 formats (51906, 1, 13, 53478, 52434, 51949, 16, 7), 4 of them not defined. When pasting these, html code was interpreted.
Other
****
Use this to search the text
From EM_FINDTEXTEX in the Windows SDK help fuFlags FT_MATCHCASE FT_WHOLEWORD FR_DOWN is new to version 2, It must be added for a version 2 search to be the same as a version 1 search Microsoft SDK ****Copying rtf text from one RichEdit control to another works fine in Windows 98, but causes a "resource error" in Windows XP because it converts the rtf codes and does not place them in the Text property. XP RichEdit Design Problem presents a solution using streams.
How to insert a Smiley image into a TRxRichEdit? shows how to do this with streams and a callback function.
Windows XP Problems
This is unbelievable - I wrote a program using
One of the things that bothers me about this is that I was not able to find any information related to these problems by searching the internet.
This line of code works perfectly in Windows 98, but fails in Windows 2000 (and Windows XP).
PlainText_UIRichEdit.Text := rtf_string;It is executed in Controls.pas via
Perform(WM_SETTEXT, 0, Longint(Buffer)); Perform(CM_TEXTCHANGED, 0, 0);Here is one way to work around the problem, this method converts the string to a stream and then loads the RichEdit control from the stream - when this is done the PlainText property controls the rtf conversion.
var xx: TStringStream ; begin xx := TStringStream.Create(rtf_string); PlainText_UIRichEdit.Lines.LoadFromStream(xx); xx.Free; end;Another option is to tell the RichEdit control not to interpret the text as rtf - this code should work with
SendMessage(PlainText_UIRichEdit.Handle, EM_SETTEXTMODE, TM_PLAINTEXT, 0); PlainText_UIRichEdit.Text := rtf_string;Well, it doesn't exactly work - in Windows XP, it interprets the rtf codes and displays the formatted text ... except that the "hidden" text is not displayed and there is no documented method to display it. CFE_HIDDEN is defined in CHARFORMAT2 and implemeted in Rich Edit 3.0.
There is no difference using TM_PLAINTEXT or TM_RICHTEXT - though the help files say that there is supposed to be.
Do not confuse these
Faster rich edit syntax highlighting explains how to speed up a syntax highlighting algorithm - it was 3 minutes, now its 8 seconds. Basically, disable screen updates (with WM_SETREDRAW), disable OnChange messages (with EM_SETEVENTMASK), and use messages to modify the colors (instead of the TRichEdit properties).