I have a problem. It is necessary to organize a search in the text and highlight the found elements. I can't figure out why the problem is that the branch "comes off" or something like that. C++ program, C++Builder environment.
I used ChatGPT, but it don't help me. I can't figure out why the problem is that the branch "comes off" or something like that.
Here's my code (it doesn't work correctly):
void __fastcall TForm1::btnSearchClick(TObject* Sender)
{
String searchTextStr = SearchText->Text;
String allText = RichEditText->Text;
RichEditText->SelStart = 0;
RichEditText->SelLength = allText.Length();
RichEditText->SelAttributes->Color = clWindowText;
int foundPos = allText.Pos(searchTextStr);
int searchOffset = 0;
while (foundPos > 0) {
RichEditText->SelStart = searchOffset + foundPos - 1;
RichEditText->SelLength = searchTextStr.Length();
RichEditText->SelAttributes->Color = clRed;
searchOffset += foundPos;
allText = allText.SubString(foundPos + searchTextStr.Length(), allText.Length() - foundPos - searchTextStr.Length() + 1);
foundPos = allText.Pos(searchTextStr);
}
}
This is my problem:
You are not taking into account that line breaks used inside the RichEdit may be different than the line breaks that the Text
property returns. That affects the offsets you can use with the SelStart
property. They need to be actual character offsets within the RichEdit's internal text.
Also, you are not adjusting the searchOffset
and allText
correctly after each search result is found.
This fixed code works for me:
void __fastcall TForm1::btnSearchClick(TObject* Sender)
{
String searchTextStr = SearchText->Text;
String allText = AdjustLineBreaks(RichEditText->Text, tlbsLF);
RichEditText->SelStart = 0;
RichEditText->SelLength = allText.Length();
RichEditText->SelAttributes->Color = clWindowText;
int foundPos = allText.Pos(searchTextStr);
int searchOffset = 0;
while (foundPos > 0) {
RichEditText->SelStart = searchOffset + foundPos - 1;
RichEditText->SelLength = searchTextStr.Length();
RichEditText->SelAttributes->Color = clRed;
searchOffset += (foundPos + searchTextStr.Length());
allText = allText.Delete(1, foundPos + searchTextStr.Length());
foundPos = allText.Pos(searchTextStr);
}
}
That being said, you really should use the TRichEdit::FindText()
method instead. There is no need to touch the RichEdit's Text
property at all, eg:
void __fastcall TForm1::btnSearchClick(TObject* Sender)
{
String searchTextStr = SearchText->Text;
int allTextLen = RichEditText->GetTextLen();
RichEditText->SelStart = 0;
RichEditText->SelLength = allTextLen;
RichEditText->SelAttributes->Color = clWindowText;
TSearchTypes options;
int foundPos = RichEditText->FindText(searchTextStr, 0, allTextLen, options);
while (foundPos >= 0) {
RichEditText->SelStart = foundPos;
RichEditText->SelLength = searchTextStr.Length();
RichEditText->SelAttributes->Color = clRed;
foundPos += searchTextStr.Length();
foundPos = RichEditText->FindText(searchTextStr, foundPos, allTextLen-foundPos, options);
}
}