WPCubed Product Support

Get / Set color from characters

I need to loop through all the text of a document and change font color depending on a certain condition.

I tried a lot of different alternatives, some worked, some didn't.

Tha alternatives that worked use CPAtt which I understand is deprecated. None of the alternatives that use GetCharAttr worked.

Now my interest is to know how to use an alternative that doesn’t need a deprecated method, CPAttr.

How and when can I use?:

  • TextCursor.CurrentCharAttr.AGet
  • TextCursor.CurrentCharAttr.ASetColor
  • CurrentCharAttr.GetColor / GetColorNR
  • CurrentCharAttr.SetColor / SetColorNR
  • CurrentCharAttr.SetBGColor

How can I evaluate and get the font color of a certain char, using TextCursor.CurrentCharAttr or CurrentCharAttr?

When do I have to use TextCursor.CurrentCharAttr and when just CurrentCharAttr ?

I would like to know why the code I wrote that doesn’t work, doesn’t work?

The alternatives I used are:

var  par   : TParagraph;  i     : integer;  a     : TWPCharAttr;  props : TWPRTFProps;  col   : integer;  bgCol : Integer;begin // Change colors   // Works   with WPRichText do begin     CPPosition := 0;     col        := CurrAttr.ColorToNr(clBlack, false);     bgCol      := 0;     BeginUpdate;     repeat       if ( CPAttr.Color <> col ) then begin          CPAttr.Color := col;          CPAttr.IncludeStyle(afsBold);       end; // if ...       if ( CPAttr.BGColor <> bgCol ) then begin          CPAttr.BGColor := bgCol;          CPAttr.IncludeStyle(afsBold);          CPAttr.IncludeStyle(afsUnderline);          // CPAttr.Style   := CPAttr.Style + [afsBold] + [afsUnderline]; // Working alternative          // CurrAttr.AddStyle([afsBold, afsUnderline]); // Working alternative       end; // if ...     until not ( CPMoveNext );     EndUpdate;   end; // with ...      // Works, but is slower than the last method   with WPRichText do begin     CPPosition := 0;     col        := CurrAttr.ColorToNr(clBlack, false);     repeat       if ( TextCursor.CPAttr.Color <> col ) then begin          TextCursor.CPAttr.Color := col;          TextCursor.CPAttr.IncludeStyle(afsBold);          // TextCursor.CPAttr.Style := TextCursor.CPAttr.Style + [afsBold]; // Working alternative       end; // if ...     until not ( CPMoveNext );   end; // with ...   // Works   col                   := WPRichText.CurrAttr.ColorToNr(clBlack, false);   WPRichText.CPPosition := 0;   par                   := WPRichText.FirstPar;   props                 := WPRichText.ActiveText.RTFProps;   WPRichText.BeginUpdate;   while ( par <> nil ) do begin     for i := 0 to par.CharCount-1 do begin       if ( WPRichText.CPAttr.Color <> col ) then begin          props.Attributes.GetCharAttr(par.CharAttr[i], a);          props.AttrInterface.SetColor(a, clRed);          props.AttrInterface.IncludeStyle(a, afsBold);          props.Attributes.SetCharAttr(par.CharAttr[i], a);       end; // if ...        WPRichText.CPMoveNext;     end; // for ...     par := par.next;     WPRichText.CPMoveNext;   end; // while ...   WPRichText.EndUpdate;   WPRichText.Refresh;   // Doesn’t work   col   := WPRichText.CurrAttr.ColorToNr(clBlack, false);   par   := WPRichText.FirstPar;   props := WPRichText.ActiveText.RTFProps;   WPRichText.BeginUpdate;   while ( par <> nil ) do begin     for i := 0 to par.CharCount-1 do begin       props.Attributes.GetCharAttr(par.CharAttr[i], a);       // if not ( props.AttrInterface.GetColor(a, col) ) then begin // Doesn’t compile       if not ( props.AttrInterface.GetColorNR(a, col) ) then begin          props.Attributes.GetCharAttr(par.CharAttr[i], a);          props.AttrInterface.SetColor(a, clRed);          props.AttrInterface.IncludeStyle(a, afsBold);          props.Attributes.SetCharAttr(par.CharAttr[i], a);       end;     end;     par := par.next;   end;   WPRichText.EndUpdate;   WPRichText.Refresh;   // Doesn’t work   with WPRichText do begin     CPPosition := 0;     col        := CurrAttr.ColorToNr(clBlack, false);     BeginUpdate;     repeat       if not ( TextCursor.CurrentCharAttr.AGet(WPAT_CharColor, col) ) then begin       // if not ( TextCursor.CurrentCharAttr.AGet(WPAT_CharColor, clBlack) ) then begin // Doesn’t compile          TextCursor.CurrentCharAttr.ASetColor(WPAT_CharColor, col);          TextCursor.CurrentCharAttr.ASetAdd(WPAT_CharStyleON, WPSTY_BOLD);       end; // if ...     until not ( CPMoveNext );     EndUpdate;   end; // with ...      // Doesn’t work   with WPRichText do begin     col        := CurrAttr.ColorToNr(clBlack, false);     CPPosition := 0;     repeat       // if not ( CurrentCharAttr.GetColor(clBlack) ) then begin // Doesn’t compile       // if not ( CurrentCharAttr.GetColorNr(clBlack) ) then begin // Doesn’t compile       // if not ( CurrentCharAttr.GetColor(col) ) then begin // Doesn’t compile       if not ( CurrentCharAttr.GetColorNR(col) ) then begin          CurrentCharAttr.BeginUpdate;          CurrentCharAttr.SetColor(clBlack);          CurrentCharAttr.IncludeStyles([afsBold]);          CurrentCharAttr.EndUpdate;       end; // if ...     until not ( CPMoveNext );   end; // if ...   // Doesn’t work   with WPRichText do begin     CPPosition := 0;     col        := CurrAttr.ColorToNr(clBlack, false);     BeginUpdate;     repeat       if ( CurrAttr.GetColorEx(WPAT_CharColor) <> col ) then begin          CPAttr.Color := col;          CPAttr.IncludeStyle(afsBold);       end; // if ...     until not ( CPMoveNext );     EndUpdate;   end; // with ...   // Doesn’t work   with WPRichText do begin     CPPosition := 0;     col        := CurrAttr.ColorToNr(clBlack, false);     bgCol      := 0;     BeginUpdate;     repeat       if ( CurrAttr.Color <> col ) then begin          CurrAttr.Color := col;          CurrAttr.AddStyle([afsBold]);       end; // if ...       if ( CurrAttr.BKColor <> bgCol ) then begin          CurrAttr.BKColor := bgCol;          CurrAttr.AddStyle([afsBold, afsUnderline]);       end; // if ...     until not ( CPMoveNext );     EndUpdate;   end; // with ...   // Doesn’t work   with WPRichText do begin     CPPosition := 0;     col        := CurrAttr.ColorToNr(clBlack, false);     bgCol      := 0;     BeginUpdate;     repeat       if ( CPAttr.Color <> col ) then begin          CurrAttr.Color := col;          CurrAttr.AddStyle([afsBold]);       end; // if ...       if ( CPAttr.BGColor <> bgCol ) then begin          CurrAttr.BKColor := bgCol;          CurrAttr.AddStyle([afsBold, afsUnderline]);       end; // if ...     until not ( CPMoveNext );     EndUpdate;   end; // with ...   // Strange results, doesn’t work   with WPRichText do begin     CPPosition := 0;     col        := CurrAttr.ColorToNr(clBlack, false);     bgCol      := 0;     BeginUpdate;     repeat      if ( CurrAttr.Color <> col ) then begin       // if ( CurrAttr.Color <> clBlack ) then begin // This alternative compiles          CPAttr.Color := col;          CPAttr.IncludeStyle(afsBold);       end; // if ...       if ( CurrAttr.BKColor <> bgCol ) then begin          CPAttr.BGColor := bgCol;          CPAttr.IncludeStyle(afsBold);          CPAttr.IncludeStyle(afsUnderline);       end; // if ...     until not ( CPMoveNext );     EndUpdate;   end; // with ...end; // Change colors

I also used:

for i := 0 to WPRichText.TextColorCount - 1 do
  WPRichText.TextColors[i] := clBlack;

This code led me to paragraphs unreadable, with black background.

I understand I can also use styles, but as I am exporting the text to an RTF file that can be read by Microsoft Word, I didn't use styles.

Kind regards,

Carlos Borrero

#1 ♥ 0
4k Views 2 users read 6 min
support

Moving the cursor is usually not a good idea.

That code looks best:

col                   := WPRichText.CurrAttr.ColorToNr(clBlack, false);    WPRichText.CPPosition := 0;    par                   := WPRichText.FirstPar;    props                 := WPRichText.ActiveText.RTFProps;    WPRichText.BeginUpdate;    while ( par <> nil ) do begin      for i := 0 to par.CharCount-1 do begin        if ( WPRichText.CPAttr.Color <> col ) then begin           props.Attributes.GetCharAttr(par.CharAttr[i], a);           props.AttrInterface.SetColor(a, clRed);           props.AttrInterface.IncludeStyle(a, afsBold);           props.Attributes.SetCharAttr(par.CharAttr[i], a);        end; // if ...        WPRichText.CPMoveNext;      end; // for ...      par := par.next;      WPRichText.CPMoveNext;    end; // while ...    WPRichText.EndUpdate;    WPRichText.Refresh;

But You can do it without moving the cursor. The following code will make all red text blue:

procedure TForm1.Button2Click(Sender: TObject);var par : TParagraph;    i,IsRed,c : Integer;begin    par := WPRichText1.RTFData.FirstPar;    IsRed := WPRichText1.CurrAttr.ColorToNr(clRed, false);    while par<>nil do    begin      for i:=0 to par.CharCount-1 do      begin        WPRichText1.AttrHelper.CharAttr := par.CharAttr[i];        if WPRichText1.AttrHelper.GetColorNr( c ) and (c=IsRed) then        begin           WPRichText1.AttrHelper.SetColor( clBlue );           par.CharAttr[i] := WPRichText1.AttrHelper.CharAttr;        end;      end;      par := par.globalnext;    end;    WPRichText1.ReformatAll(false, true);end;

Please note, that black is usually not assigned. This means text text is black if GetColorNr returns false. So you can make all black text blue using this code:

procedure TForm1.Button2Click(Sender: TObject);
var par : TParagraph;
    i,IsBlack,c : Integer;
begin
    par := WPRichText1.RTFData.FirstPar;
    IsBlack := WPRichText1.CurrAttr.ColorToNr(clBlack, false);

    while par<>nil do
    begin
      for i:=0 to par.CharCount-1 do
      begin
        WPRichText1.AttrHelper.CharAttr := par.CharAttr[i];
        if not WPRichText1.AttrHelper.GetColorNr( c ) or (c=IsBlack) then
        begin
           WPRichText1.AttrHelper.SetColor( clBlue );
           par.CharAttr[i] := WPRichText1.AttrHelper.CharAttr;
        end;
      end;
      par := par.globalnext;
    end;
    WPRichText1.ReformatAll(false, true);
end;
#2 ♥ 0
This category is archived. No new posts are possible.