Author Topic: RichEd20.DLL bugs  (Read 1695 times)

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 10113
  • Assembler is fun ;-)
    • MasmBasic
RichEd20.DLL bugs
« on: September 24, 2017, 08:14:04 PM »
Searching the forum, I just realised that we do not yet have a dedicated thread on bugs in Microsoft's RichEdit control. So I hope we can collect observations here, and I kindly ask you for real contributions, not philosophical observations.

If you have a bug to report, please modify the title of the post, and try to be very brief and to the point.
« Last Edit: September 24, 2017, 11:34:06 PM by jj2007 »

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 10113
  • Assembler is fun ;-)
    • MasmBasic
RichEd20.DLL tables
« Reply #1 on: September 24, 2017, 11:31:14 PM »
Let's start with a really exotic bug: The way the RichEdit control stores tables. I stumbled over this one when trying to create a "serial letter" application. It uses a template wirh tags:
Code: [Select]
This file was created on #date#
#column1# #column2# #column3#
#value11# #value12# #value13#
#value21# #value22# #value23#

In the RTF file (attached), it is a nice table. You can read the whole file into a string, replace the tags with appropriate values, save the result, and voilà, there is a RTF file ready for printing. Code:

include \masm32\MasmBasic\MasmBasic.inc         ; download
  Init
  Let esi=FileRead$("TemplateHashes.rtf")       ; read a template into a buffer
  Let esi=Replace$(esi, "#date#", Date$)        ; replace tags
  Let esi=Replace$(esi, "#column1#", "First column")
  Let esi=Replace$(esi, "#column2#", "Second column")
  Let esi=Replace$(esi, "#column3#", "Third column")
  FileWrite "LetterHashes.rtf", esi             ; save result
  ShEx "LetterHashes.rtf"                       ; and open it in the default editor
EndOfCode


The line "This file was created on #date#" works fine. Always.

The table works fine if your template was saved with certain versions of RichEd20.dll, but it fails miserably if the template was saved with others :(

Code: [Select]
System32 ; OK (but C:\Windows\System32\RichEd20.dll is utterly slow and lacks many features)
Office15 ; OK (but has some other bugs)
Office14 ; bad
Office12 ; bad
Office11 ; OK

Why this?

A line of a table gets typically saved as follows:
Code: [Select]
\pard\intbl\nowidctlpar\cf2\i0 #column1#\cell #column2#\cell #column3#\cell\row\trowd\trgaph70\trleft-30\trpaddl70\trpaddr70\trpaddfl3\trpaddfr3
The interesting part is
Code: [Select]
\cell #column2#\cell #column3#After the replacing of tags, it becomes
Code: [Select]
\cell Second column\cell Third column
Perfect :t

But it fails with the Office12 and Office14 versions of RichEd20.dll because these DLLs save the template as follows:
Code: [Select]
[code]\cell#column2#\cell#column3#
No blank after the RTF tag! It's probably a feature 8), and it will hit you as a bug only in very exotic situations like the one outlined above: words starting with # in cells of a table. Same for words starting with $, btw, and maybe others.

Workaround: Use + instead of # or $.

Here is a list of tested delimiters. OK means even the buggy DLLs insert a space after the rtf tag, bad means they don't.

OK   +/-:@[^?
bad   $\#§*"'&|

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 10113
  • Assembler is fun ;-)
    • MasmBasic
RichEdit extremely slow on EM_STREAMIN
« Reply #2 on: January 19, 2020, 01:03:53 AM »
Here is a little program that loads text and rtf files into a RichEdit control when you click into the listbox (source & exe attached; extract the exe to a folder that contains asm and/or rtf files):

GuiParas equ "Dynamic Layout Demo", y100, w900, h600, m5, bGrey        ; y at 100px, width 900px, h600px, margins 5px, grey background
GuiMenu equ @File, &Open, &Save, -, E&xit, @Whatever, Добро пожаловать, مرحبا بكم, Functions not implemented   ; creates a menu -> Event Menu
include \masm32\MasmBasic\Res\MbGui.asm
  GetFiles *.as?|*.rc|*.rtf     ; collect asm, asc & rc sources, plus rich text files
  SortFiles date       ; most recent first
  GuiControl MyList, "listbox", Files$(), x0+288, w1000-288, h0+100    ; right-aligned, height 100px
  GuiControl MyLink, "syslink", "Download the MasmBasic library", w0+200, y0+100, h0+20
  GuiGroup "Groupbox (functions not implemented):", w0+266, h0+75, bcol LiteYellow
    GuiControl StatFind, "static", "Find:",        h0+22, w0+50            ; general syntax:
    GuiControl StatRepl, "static", "Replace:",         h0+22, w0+50, y0+32             ; guicontrol ID, "class", args "text", x, y, w, h, style
    GuiControl EditFind, "edit", "Gui", x0+62, w0+100, h0+22   ; args have a variable part plus an optional fixed one, example:
    GuiControl EditRepl, "edit", x0+62, w0+100, h0+22, y 0+30  ; x1000-90 means "at right border, i.e. 100.0%, minus 90 pixels"
    GuiControl Cis, "button", BS_AUTOCHECKBOX, h0+22, x0+170, w0+60, "Case"    ; args may appear in no particular order, e.g. "Case" at the end
    GuiControl Fw, "button", "Full word", h0+22, x0+170, w0+64, y0+28, BS_AUTOCHECKBOX
  GuiGroup end
  GuiControl BigEdit, "RichEdit", y0+120, h1000-120, bcol RgbCol(222, 255, 255), font -14
  GuiControl MySBar, "statusbar", "Добро пожаловать", parts=290/160      ; all GuiControls understand Unicode
  SetStatus$ ComCtl32$("Common controls version %3f"), 1                ; test if the manifest works
  SetStatus$ RichEditUsed, 2
Event Menu
  SetWin$ hMySBar=Str$("You clicked menu #%i", MenuID)
Event Notify
  If_ word ptr wParam_==MyLink && NotifyCode==NM_CLICK Then <ShEx "http://masm32.com/board/index.php?topic=94.0">
Event Command
  If_ word ptr wParam_==MyList && LbSel>=0 Then <SetWin$ hBigEdit=FileRead$(LbSel$)>
GuiEnd


It works fine but I noticed that some bigger files loaded extremely slowly. It took me a while to chase down the culprit, it's actually the EM_STREAMIN message. If the control has already content, it may take ages to replace that content with new one. With "ages" I mean 8 seconds and more for a file that normally loads in 100 milliseconds. Yes, it's a bug, and it is present in all versions tested.

Thanks to well over 10 years of experience with RichEdit bugs, I found a workaround (and it will be added to MasmBasic's SetWin$="..." today): clear the control before streaming in new text, and all is good  :cool:

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 10113
  • Assembler is fun ;-)
    • MasmBasic
EM_GETTEXTLENGTHEX fails miserably
« Reply #3 on: February 12, 2020, 02:58:24 AM »
One more for the record: EM_GETTEXTLENGTHEX fails completely but not predictably if the control is in another process. In contrast, WM_GETTEXTLENGTH works fine, and has a non-documented feature: There is no 64kB limit for this message.

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 10113
  • Assembler is fun ;-)
    • MasmBasic
Re: RichEd20.DLL bugs
« Reply #4 on: February 15, 2020, 05:40:20 AM »
RichEdit bugs are a never ending story, here is the latest chapter about line numbering :biggrin: