Denis Dresse 1 Posted August 26, 2022 Hello, We just installed the Delphi 11.1. But there is a problem with the TRichEdit. When we add a line including formatting characters as "alt 205" or "alt179" or "alt196", with the "Courier New" font, then the police changes to an other police (Segoe UI Symbol) and the result is ugly. We uses the following instruction for adding this line : myRichEdit.SelText := myString. This way of reporting was used for years without problem in many places of our application. Is it a documented bug, are there any turnarounds ? Any help would be appreciated, Denis Dresse Share this post Link to post
Remy Lebeau 1436 Posted August 26, 2022 Can you show the actual code that is populating the TRichEdit and the formatting of its lines? Share this post Link to post
PeterBelow 239 Posted August 26, 2022 1 hour ago, Denis Dresse said: Hello, We just installed the Delphi 11.1. But there is a problem with the TRichEdit. When we add a line including formatting characters as "alt 205" or "alt179" or "alt196", with the "Courier New" font, then the police changes to an other police (Segoe UI Symbol) and the result is ugly. We uses the following instruction for adding this line : myRichEdit.SelText := myString. This way of reporting was used for years without problem in many places of our application. Is it a documented bug, are there any turnarounds ? Are you setting up SelAttributes correctly before assigning text to SelText? D11.1 uses a newer version of the rich edit common control (4.x), which has more capabilities than the old 2.x version used by prior Delphi versions. 1 Share this post Link to post
Denis Dresse 1 Posted August 29, 2022 Hello, Here is a little sample program. - When the line "DDD════DDD" is added, the letters DDD remain well in Courier New, but the ════ text (characters alt 205) is in "Segoe UI Symbol". - And the same for the line "───────────" (characters alt 196). So the alignment is not uniform. Denis Unit1.pas Unit1.dfm Share this post Link to post
rvk 44 Posted August 29, 2022 Yikes. Mixing UTF8 (from direct source code) and Unicode is asking for trouble. And Alt+205... what is that? You need to work with exact correct encoding. Doing Alt+205 might insert a complete other character in the code editor. When I open your Unit1.pas, I get a square with a line through it for your "alt 205" character. Try this: add('DDD' + Widechar(#$2550) + Widechar(#$2550) + Widechar(#$2550) + Widechar(#$2550) + Widechar(#$2550) + 'DDD'); Share this post Link to post
Denis Dresse 1 Posted August 29, 2022 Hello, Thanks for your answer. We added the line as you suggested, but the result is the same. In the "selText", the special characters seem not to be available in "Courier New", so it switches to the other font. It was not the case in Delphi 10.4.2 Share this post Link to post
Denis Dresse 1 Posted August 29, 2022 On 8/26/2022 at 8:40 PM, PeterBelow said: Are you setting up SelAttributes correctly before assigning text to SelText? D11.1 uses a newer version of the rich edit common control (4.x), which has more capabilities than the old 2.x version used by prior Delphi versions. Hello, Have you a link to the specs/docs of this new version of rich edit common control (4.x) ? Share this post Link to post
rvk 44 Posted August 29, 2022 Have you tried this in BBInitClick RE.DefAttributes.name := 'Courier New'; RE.DefAttributes.size := 8; And alternatively this in add() RE.SelAttributes.name := 'Courier New'; RE.SelAttributes.size := 8; RE.SelText := myText; Sometimes SelAttributes are not hold after you have set SelText. Share this post Link to post
PeterBelow 239 Posted August 30, 2022 21 hours ago, Denis Dresse said: Hello, Have you a link to the specs/docs of this new version of rich edit common control (4.x) ? https://docwiki.embarcadero.com/Libraries/Alexandria/en/Vcl.ComCtrls.TRichEdit https://docwiki.embarcadero.com/RADStudio/Alexandria/en/What's_New#TRichEdit_Component_updated_to_RichEdit_4.1_.28MSFTEDIT.dll.29 There are new events, e.g. OnLinkClick and extensions to the TTextAttribute type used by SelAttributes. Share this post Link to post
Denis Dresse 1 Posted August 30, 2022 19 hours ago, rvk said: Have you tried this in BBInitClick RE.DefAttributes.name := 'Courier New'; RE.DefAttributes.size := 8; And alternatively this in add() RE.SelAttributes.name := 'Courier New'; RE.SelAttributes.size := 8; RE.SelText := myText; Sometimes SelAttributes are not hold after you have set SelText. We had exactly the same lines in our program : And the proposition with "DefAttributes" do not work either. Share this post Link to post
Denis Dresse 1 Posted August 30, 2022 (edited) 4 hours ago, PeterBelow said: https://docwiki.embarcadero.com/Libraries/Alexandria/en/Vcl.ComCtrls.TRichEdit https://docwiki.embarcadero.com/RADStudio/Alexandria/en/What's_New#TRichEdit_Component_updated_to_RichEdit_4.1_.28MSFTEDIT.dll.29 There are new events, e.g. OnLinkClick and extensions to the TTextAttribute type used by SelAttributes. Thanks for this links, but it do not adress the TRichEdit.SelText problematic, which transforms the "Courier New" font, when some special characters are given to SelText (ex : ═ alt 205 et ─ alt 196...) Denis Edited August 30, 2022 by Denis Dresse Share this post Link to post
Lajos Juhász 295 Posted August 30, 2022 27 minutes ago, Denis Dresse said: Thanks for this links, but it do not adresses the TRichEdit.SelText problematic, which transform the "Courier New" font, when some special characters are given to SelText (ex : ═ alt 205 et ─ alt 196...) Denis I quick google search returned this one: https://devblogs.microsoft.com/math-in-office/richedit-font-binding/ I have to warn you that this is a bug in MS Richedit implementation. I've entered into Microsoft Word using Courier New 11 ──────────────────────────────. No problem there, then copied to the clipboard and pasted to Wordpad.exe the result wordpad changed the font to Segoe UI Symbol 11. Share this post Link to post
timfrost 79 Posted August 30, 2022 That Microsoft link brought back some memories! Murray Sargent, who wrote the article, is the author of the PMATE text editor, which I used as a programming editor over 30 years ago; some of its keyboard shortcuts I still configure in the editors I use today. And he had many other careers before joining Microsoft and becoming a RichEdit guru. Share this post Link to post
rvk 44 Posted August 30, 2022 40 minutes ago, Lajos Juhász said: I have to warn you that this is a bug in MS Richedit implementation. I've entered into Microsoft Word using Courier New 11 ──────────────────────────────. No problem there, then copied to the clipboard and pasted to Wordpad.exe the result wordpad changed the font to Segoe UI Symbol 11. Pff. It's one of the reasons I still ship a RICHED20.DLL with my program. Although not advised (and even not allowed), the many versions of riched20.dll all have their own problems. If it's not alignment issues (resetting back to left align-tab after a right alignment tab) then it's some font issue (and there are lots of other issues). I was so fed up with it (I never knew which one was shipped with Windows and which one was loaded at the client) that I took one for which I knew what issues there were and could program against that. Share this post Link to post
PeterBelow 239 Posted August 30, 2022 2 hours ago, Denis Dresse said: Thanks for this links, but it do not adress the TRichEdit.SelText problematic, which transforms the "Courier New" font, when some special characters are given to SelText (ex : ═ alt 205 et ─ alt 196...) Denis Have you tried to use the correct UTF16 code points instead, e.g. #$2012 etc.? Check the proper codes to use in the Windows Charmap application. Share this post Link to post
Denis Dresse 1 Posted September 1, 2022 Hello, My colleague found a turnaround (without using the problematic SetText procedure) 0- As before, we add the lines with 'Courier New' and special characters. Result is ugly as shown before. But for each line of the memo, we store the font color and the size (in a memory object ALineSpecial). 1- At the end of the addings I place : RE.font.Name := 'Courier New'; All the text is now well aligned, but we lost the colors and the size. 2- I parse all the lines, and when needed, set the color and the size of the concerned line : myLineIndex := ALineSpecial.getInt1(i); // get the index of the line RE.SelStart := Perform(EM_LINEINDEX, myLineIndex, 0); // set start position of the selection RE.SelLength := length(Lines[myLineIndex]); // set lenght of the selection (the line) myColor := TColor(ALineSpecial.getO(i)); // get the color to apply (it comes from the memory object) RE.SelAttributes.Color := myColor; // apply the color to the selection And the result is OK Many thanks for your contributions, Denis 1 Share this post Link to post
Remy Lebeau 1436 Posted September 1, 2022 10 hours ago, Denis Dresse said: 2- I parse all the lines, and when needed, set the color and the size of the concerned line : myLineIndex := ALineSpecial.getInt1(i); // get the index of the line RE.SelStart := Perform(EM_LINEINDEX, myLineIndex, 0); // set start position of the selection RE.SelLength := length(Lines[myLineIndex]); // set lenght of the selection (the line) myColor := TColor(ALineSpecial.getO(i)); // get the color to apply (it comes from the memory object) RE.SelAttributes.Color := myColor; // apply the color to the selection Just a small nitpick - you can change this: RE.SelStart := Perform(EM_LINEINDEX, myLineIndex, 0); RE.SelLength := length(Lines[myLineIndex]); To this instead: var myLineStart: Integer; myLineStart := Perform(EM_LINEINDEX, myLineIndex, 0); RE.SelStart := myLineStart; RE.SelLength := Perform(EM_LINELENGTH, myLineStart, 0); That will avoid a memory allocation trying to retrieve the actual String of the line in question. The RichEdit already knows how many characters are on the line without needing to access the actual characters. An then to can be optimized further by using EM_EXSETSEL directly instead of the SelStart/Length properties: var rng: CHARRANGE; rng.cpMin := Perform(EM_LINEINDEX, myLineIndex, 0); rng.cpMax := rng.cpMin + Perform(EM_LINELENGTH, rng.cpMin, 0); Perform(EM_EXSETSEL, 0, LParam(@rng)); Further speed optimizations can be accomplished using EM_SETCHARFORMAT/2 and EM_SETEVENTMASK messages, see Faster Rich Edit Syntax Highlighting for details. Share this post Link to post
Denis Dresse 1 Posted September 2, 2022 19 hours ago, Remy Lebeau said: Just a small nitpick - you can change this: RE.SelStart := Perform(EM_LINEINDEX, myLineIndex, 0); RE.SelLength := length(Lines[myLineIndex]); To this instead: var myLineStart: Integer; myLineStart := Perform(EM_LINEINDEX, myLineIndex, 0); RE.SelStart := myLineStart; RE.SelLength := Perform(EM_LINELENGTH, myLineStart, 0); That will avoid a memory allocation trying to retrieve the actual String of the line in question. The RichEdit already knows how many characters are on the line without needing to access the actual characters. An then to can be optimized further by using EM_EXSETSEL directly instead of the SelStart/Length properties: var rng: CHARRANGE; rng.cpMin := Perform(EM_LINEINDEX, myLineIndex, 0); rng.cpMax := rng.cpMin + Perform(EM_LINELENGTH, rng.cpMin, 0); Perform(EM_EXSETSEL, 0, LParam(@rng)); Further speed optimizations can be accomplished using EM_SETCHARFORMAT/2 and EM_SETEVENTMASK messages, see Faster Rich Edit Syntax Highlighting for details. Thanks for this new optimisations Denis Share this post Link to post