Search code examples
delphiformattingstring-formattingrichedit

Delphi 7: Formatting changes after using delete procedure


I was working on my text editor, which I have completed, but I still have this one problem I'm trying to solve.

My problem is, that I want to delete specific symbols on the end of lines, which were created by pressing the speedbutton (button is down). So when I click button again (button is up), I'd like to delete them, which works, but I have problem with text formatting.

Text is formatted through property RichEdit1.SelAttributes.

If I change formatting of first character in RichEdit and then I use this function, whole text changes to same format as this character.

You can see it here:

screenshot

If I change formatting of characters somewhere in text and then I use this function, formated characters change back to previous formatting.

You can see it here:

screenshot

if (Button.Down=false) and (length(RichEdit1.Text)<>0) then begin                  
  for i:=0 to length(RichEdit1.text) do begin

  if RichEdit1.Text[i] = '¶' then begin                                               
    txt:=RichEdit1.text;
    delete(txt, i, 1);
    RichEdit1.Text:=txt;
  end;
  end;
RichEdit1.SelStart:=length(RichEdit1.Text);

I've thought, that problem could be with variable txt, but if I take away delete procedure, formatting works fine, so problem should be there.

This work is already completed, so I don't want to make any changes in code, I just would like to know why is this happening and what could be possible solution.


Solution

  • You extract the entire text, using the Text property, modify that string, and then replace the entire text. When you do that all the new text is given the selected formatting attributes.

    You need to select just the text that you wish to delete, and then delete it, all within the rich edit control. That avoids losing any specific local formatting. Do so in this manner.

    RichEdit1.SelStart := i;
    RichEdit1.SelLength := 1;
    RichEdit1.ClearSelection;
    

    Do beware that RichEdit1.Text[i] is very expensive. That code extracts the entire content of the rich edit contol and then picks out a single character. It is more efficient to use SelStart and SelLength and SelText to extract sub-strings.

    Valid string indices are 1 to Length(s) inclusive. You index outside that range.

    It is also worth noting that as you move through the text deleting characters, you change the length of the text. It's easy therefore to access beyond the end of the text. As indeed your current code does. The compiler range checking option would have found that error in your code.