[Solved] Possible to set next characters background/foreground Windows RichEdit? lazarus / 34-Windows ---------------------------------------------------------------------- Ozz_Nixon · 2023-04-12 02:31 Basically, I am trying to do things like, set bgcolor to Blue, and fgcolor to Yellow, then add the next character from the file to the screen. Thus, allowing me to render ANSI text files to GUI, then I will snapshop the Canvas to PNG. (Delphi7 Application) Can someone help with how to preset the background/foreground color before I append the next character? Below is the result of my last attempt - but it changes the whole line to clMaroon. ``` procedure TForm1.SpeedButton1Click(Sender: TObject); var    Format:CharFormat2;    Index,SizeOfFormat:Longint;    Ws:String; begin   RichEdit1.Clear;   RichEdit1.SelAttributes.Color := clAqua; //  RichEdit1.SelAttributes.Style := [fsBold];   RichEdit1.SelText := '32bit GUI ';   RichEdit1.SelAttributes.Color := clYellow;   RichEdit1.SelText := 'A';   RichEdit1.SelAttributes.Color := clRed;   RichEdit1.SelText := 'N';   RichEdit1.SelAttributes.Color := clWhite;   RichEdit1.SelText := 'S';   RichEdit1.SelAttributes.Color := clLime;   RichEdit1.SelText := 'I ';   RichEdit1.SelAttributes.Color := clAqua;   RichEdit1.SelText := 'Terminal';   RichEdit1.SelAttributes.Color := clRed;   RichEdit1.SelAttributes.Style := [fsItalic];   // try to turn on clMaroon background for this next string   // however, ends up changing whole line to clMaroon. I actually   // need to achieve this character by character...   Ws:=#32'(c) 2023 by Ozz Nixon';   Index:=Length(RichEdit1.Lines.Text);   RichEdit1.SelStart  := Index;   RichEdit1.SelLength := Length(Ws);   RichEdit1.SelText := Ws;   SizeOfFormat:=SizeOf(Format);   FillChar(Format, SizeOfFormat, 0);   Format.cbSize := SizeOfFormat;   Format.dwMask := CFM_BACKCOLOR;   Format.crBackColor := clMaroon;   RichEdit1.Perform(EM_SETCHARFORMAT, $0004 {SCF_SELECTION}, Longint(@Format)); end; ``` ---------------------------------------------------------------------- Remy Lebeau · 2023-04-12 16:54 Quote from: ozznixon on April 12, 2023, 04:31:40 amCan someone help with how to preset the background/foreground color before I append the next character? Below is the result of my last attempt - but it changes the whole line to clMaroon. You are on the right track. However, you are setting the WPARAM parameter of EM_SETCHARFORMAT to $0004 (aka SCF_ALL) when you should be setting it to $0001 (aka SCF_SELECTION) instead. Also, make sure you are setting up the correct selection before you change the background color.  For instance, make sure that Length(RichEdit1.Lines.Text) is not returning 0 unexpectedly.  Try using RichEdit1.GetTextLen() instead. Also, since you are trying to place the SelStart at the end of the text, you should be setting the SelLength to 0 instead of Length(Ws), and that you set the background color before you assign the SelText rather than after, like you do with the other attributes. Try this: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TForm1.SpeedButton1Click(Sender: TObject);var  Format: CharFormat2;begin  RichEdit1.Clear;   RichEdit1.SelStart := RichEdit1.GetTextLen();  RichEdit1.SelLength := 0;  RichEdit1.SelAttributes.Color := clAqua;  //RichEdit1.SelAttributes.Style := [fsBold];  RichEdit1.SelText := '32bit GUI';   RichEdit1.SelStart := RichEdit1.GetTextLen();  RichEdit1.SelLength := 0;  RichEdit1.SelAttributes.Color := clWindowText;  //RichEdit1.SelAttributes.Style := [];  RichEdit1.SelText := ' ';   RichEdit1.SelStart := RichEdit1.GetTextLen();  RichEdit1.SelLength := 0;  RichEdit1.SelAttributes.Color := clYellow;  RichEdit1.SelText := 'A';   RichEdit1.SelStart := RichEdit1.GetTextLen();  RichEdit1.SelLength := 0;  RichEdit1.SelAttributes.Color := clRed;  RichEdit1.SelText := 'N';   RichEdit1.SelStart := RichEdit1.GetTextLen();  RichEdit1.SelLength := 0;  RichEdit1.SelAttributes.Color := clWhite;  RichEdit1.SelText := 'S';   RichEdit1.SelStart := RichEdit1.GetTextLen();  RichEdit1.SelLength := 0;  RichEdit1.SelAttributes.Color := clLime;  RichEdit1.SelText := 'I';   RichEdit1.SelStart := RichEdit1.GetTextLen();  RichEdit1.SelLength := 0;  RichEdit1.SelAttributes.Color := clWindowText;  RichEdit1.SelText := ' ';   RichEdit1.SelStart := RichEdit1.GetTextLen();  RichEdit1.SelLength := 0;  RichEdit1.SelAttributes.Color := clAqua;  RichEdit1.SelText := 'Terminal';   RichEdit1.SelStart := RichEdit1.GetTextLen();  RichEdit1.SelLength := 0;  RichEdit1.SelAttributes.Color := clWindowText;  RichEdit1.SelText := ' ';   RichEdit1.SelStart := RichEdit1.GetTextLen();  RichEdit1.SelLength := 0;  RichEdit1.SelAttributes.Color := clRed;  RichEdit1.SelAttributes.Style := [fsItalic];  FillChar(Format, SizeOf(Format), 0);  Format.cbSize := SizeOf(Format);  Format.dwMask := CFM_BACKCOLOR;  Format.crBackColor := clMaroon;  RichEdit1.Perform(EM_SETCHARFORMAT, WPARAM(SCF_SELECTION), LPARAM(@Format));  RichEdit1.SelText := '(c) 2023 by Ozz Nixon';   RichEdit1.SelStart := RichEdit1.GetTextLen();  RichEdit1.SelLength := 0;end; I would suggest then taking that a step further by wrapping the repeated code into a helper procedure, eg: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TForm1.SpeedButton1Click(Sender: TObject);   procedure AppendText(const S: string; TextColor: TColor = clWindowText; Style: TFontStyles = []; BackColor: TColor = clWindow);  var    CharRange: TCharRange;    Format: CharFormat2;  begin    // RichEdit1.SelStart := RichEdit1.GetTextLen();    // RichEdit1.SelLength := 0;    CharRange.cpMin := RichEdit1.GetTextLen();    CharRange.cpMax := CharRange.cpMin + 0;    RichEdit1.Perform(EM_EXSETSEL, 0, LPARAM(@CharRange));    //RichEdit1.Perform(EM_SCROLLCARET, 0, 0);   FillChar(Format, SizeOf(Format), 0);    Format.cbSize := SizeOf(Format);     //RichEdit1.SelAttributes.Color := TextColor;    Format.dwMask := Format.dwMask or CFM_COLOR;    if (TextColor = clWindowText) {$IFNDEF FPC}or (TextColor = clDefault){$ENDIF} then begin      Format.dwEffects := CFE_AUTOCOLOR;    end    else begin    {$IFDEF FPC}if TextColor = clDefault then TextColor := RichEdit1.GetDefaultColor(dctfont);{$ENDIF}      Format.crTextColor := ColorToRGB(TextColor);    end;     //RichEdit1.SelAttributes.Style := Style;    Format.dwMask := Format.dwMask or CFM_BOLD or CFM_ITALIC or CFM_UNDERLINE or CFM_STRIKEOUT;    if fsBold in Style then Format.dwEffects := Format.dwEffects or CFE_BOLD;    if fsItalic in Style then Format.dwEffects := Format.dwEffects or CFE_ITALIC;    if fsUnderline in Style then Format.dwEffects := Format.dwEffects or CFE_UNDERLINE;    if fsStrikeOut in Style then Format.dwEffects := Format.dwEffects or CFE_STRIKEOUT;     Format.dwMask := Format.dwMask or CFM_BACKCOLOR;    if (BackColor = clWindow) {$IFNDEF FPC}or (BackColor = clDefault){$ENDIF} then begin      Format.dwEffects := Format.dwEffects or CFE_AUTOBACKCOLOR;    end    else begin      {$IFDEF FPC}if BackColor = clDefault then BackColor := RichEdit1.GetDefaultColor(dctbrush);{$ENDIF}      Format.crBackColor := ColorToRGB(BackColor);    end;     RichEdit1.Perform(EM_SETCHARFORMAT, WPARAM(SCF_SELECTION), LPARAM(@Format));     RichEdit1.SelText := S;  end; begin  RichEdit1.Clear;   AppendText('32bit GUI', clAqua {, [fsBold]});  AppendText(' ');  AppendText('A', clYellow);  AppendText('N', clRed);  AppendText('S', clWhite);  AppendText('I', clLime);  AppendText(' ');  AppendText('Terminal', clAqua);  AppendText(' ');  AppendText('(c) 2023 by Ozz Nixon', clRed, [fsItalic], clMaroon);   RichEdit1.SelStart := RichEdit1.GetTextLen();  RichEdit1.SelLength := 0;end; ---------------------------------------------------------------------- Ozz_Nixon · 2023-04-12 21:24 Quote from: Remy Lebeau on April 12, 2023, 06:54:23 pmQuote from: ozznixon on April 12, 2023, 04:31:40 amCan someone help with how to preset the background/foreground color before I append the next character? Below is the result of my last attempt - but it changes the whole line to clMaroon. You are on the right track.  Just make sure you are setting up the correct selection before you change the background color.  For instance, make sure that Length(RichEdit1.Lines.Text) is not returning 0 unexpectedly.  Try using RichEdit1.GetTextLen() instead. Thank you Remy for your attempt. Neither work - copy your code right into my project, compile, run, and I get clMaroon as the background to the whole line. :-( - I will keep tinkering with your design to see if I can figure out why SelStart is always going to 0 (zero)... ---------------------------------------------------------------------- KodeZwerg · 2023-04-13 06:05 There is one error in your code @Remy and because of that of course your code color all change this Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i RichEdit1.Perform(EM_SETCHARFORMAT, $0004 {SCF_SELECTION}, Longint(@Format));to that Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i   RichEdit1.Perform(EM_SETCHARFORMAT, WPARAM(SCF_SELECTION), LPARAM(@Format)); Quote  SCF_SELECTION       = $0001;   SCF_ALL             = $0004; Now it prints like in attachment ---------------------------------------------------------------------- KodeZwerg · 2023-04-13 06:17 Quote from: Remy Lebeau on April 12, 2023, 06:54:23 pmCode: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i         TextColor := RichEdit1.GetDefaultColor(dctfont);This method neither my Turbo Delphi 2006 nor my Delphi Alexandria does understand. Can you explain it please? ---------------------------------------------------------------------- Remy Lebeau · 2023-04-13 16:50 Quote from: KodeZwerg on April 13, 2023, 08:05:52 amThere is one error in your code @Remy and because of that of course your code color all Quote  SCF_SELECTION       = $0001;   SCF_ALL             = $0004; Good catch. But that was an error in the original author's code.  I just didn't catch it, since I didn't look up the defined value of SCF_SELECTION. I have updated my earlier code examples accordingly. ---------------------------------------------------------------------- Remy Lebeau · 2023-04-13 17:00 Quote from: KodeZwerg on April 13, 2023, 08:17:14 amThis method neither my Turbo Delphi 2006 nor my Delphi Alexandria does understand. Correct, because TControl.GetDefaultColor() does not exist in Delphi, only in FreePascal.  This question was posted in a FreePascal forum, after all.  It should have posted in a Delphi forum instead. Just ignore GetDefaultColor() in Delphi: eg: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i ...//RichEdit1.SelAttributes.Color := TextColor;Format.dwMask := Format.dwMask or CFM_COLOR;if (TextColor = clWindowText) or (TextColor = clDefault) then begin  Format.dwEffects := CFE_AUTOCOLORelse  Format.crTextColor := ColorToRGB(TextColor); ... Format.dwMask := Format.dwMask or CFM_BACKCOLOR;if (BackColor = clWindow) or (BackColor = clDefault) then begin  Format.dwEffects := Format.dwEffects or CFE_AUTOBACKCOLORelse  Format.crBackColor := ColorToRGB(BackColor); I have updated my earlier code examples accordingly. ---------------------------------------------------------------------- KodeZwerg · 2023-04-13 19:06 Quote from: Remy Lebeau on April 13, 2023, 07:00:58 pmYou did post this question in a FreePascal forum, after all.  You should have posted in a Delphi forum instead.It was not me my friendly WinAPI Guru I just copied your post to find out why OP is telling that, since I know you are an absolute WinAPI expert.  Quote from: ozznixon on April 12, 2023, 04:31:40 amDelphi7 ApplicationAnd I do admit, his code I skipped to read since he not uses any code tags, so yes, his fault not yours. But now I am extra curious because I did not find any working RichEdit for FreePascal, RichMemo and RichView are the only ones I found, is your RichEdit component somewhere available please? Thank you for your time and code examples! ---------------------------------------------------------------------- Remy Lebeau · 2023-04-14 16:47 Quote from: KodeZwerg on April 13, 2023, 09:06:31 pmBut now I am extra curious because I did not find any working RichEdit for FreePascal, RichMemo and RichView are the only ones I found Correct, there is no native TRichEdit in FreePascal/Lazarus.  There are plenty of past discussions in this forum on that topic. Quote from: KodeZwerg on April 13, 2023, 09:06:31 pmis your RichEdit component somewhere available please? It is not my component.  TRichEdit is a native component in Delphi's VCL.