C++Builder中如何在TRichEdit实现文本搜索并高亮匹配内容?
TRichEdit文本搜索高亮功能异常修复(C++Builder)
在CBuilder环境开发C程序时,实现TRichEdit内文本搜索并高亮匹配内容的代码运行异常,出现分支“断开”类显示问题。以下是原异常代码:
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); } }
问题分析
原代码核心问题在于:
- 截取
allText子串进行搜索,破坏了与TRichEdit实际内容的偏移对应关系,导致SelStart定位错误,引发显示错乱 - 使用
Text属性获取内容会忽略TRichEdit中的格式信息,长度计算可能与实际控件内容不符 - 字符串索引逻辑易出错,尤其是处理重复匹配文本时,会出现偏移叠加错误
修复后的代码
void __fastcall TForm1::btnSearchClick(TObject* Sender) { String searchText = SearchText->Text; if (searchText.IsEmpty()) return; // 清除所有已有高亮 RichEditText->SelStart = 0; RichEditText->SelLength = RichEditText->GetTextLen(); RichEditText->SelAttributes->Color = clWindowText; int currentPos = 0; const int textLen = RichEditText->GetTextLen(); const int searchLen = searchText.Length(); while (currentPos <= textLen - searchLen) { // 调用TRichEdit自带方法搜索文本,支持大小写匹配控制 int foundPos = RichEditText->FindText(searchText, currentPos, textLen, TSearchTypes() << stMatchCase); if (foundPos == -1) break; // 高亮匹配内容 RichEditText->SelStart = foundPos; RichEditText->SelLength = searchLen; RichEditText->SelAttributes->Color = clRed; // 移动到下一个搜索起始位置,避免重复匹配同一内容 currentPos = foundPos + searchLen; } }
修复说明
- 采用TRichEdit原生
FindText方法直接在控件内搜索,避免字符串截取带来的偏移错误 - 使用
GetTextLen()获取控件实际文本长度,替代Text.Length(),确保长度计算准确 - 循环中更新搜索起始位置为匹配结束位置,防止重复匹配同一文本片段
- 增加空搜索文本判断,避免无效执行
内容的提问来源于stack exchange,提问作者Maxim Drobot
相关产品推荐
相关产品推荐

