цветной текст в richedit. Борланд с++
Нашел способ разукрашивания текста в richedit по ключевым словам. Все работает но процесс перерисовки в случае большего размера файла и большего количества ключевых слов происходит довольно медленно. Хотел узнать если способ делать перерисовку быстрее.
// структура форматирования
struct THiLt
{
TColor FontColor;
TFontStyles FontStyle;
};
//
struct THiLtEx // универсальная структура форматирования со списком слов/символов
{
THiLt* Format; // указатель на объект THiLt
TStringList* KeyWords; // список
bool ByWords; // если TRUE, поиск будет по словам, если FALSE - по символам
};typedef THiLtEx* pHiLtEx;
// и наконец, вектор, куда можно добавлять группы
std::vector<THiLtEx*> vGroups;
***
// Функция HighLight для парсинга от заданной позиции до конца текста
void __fastcall TFEditor::HighLight(TRichEdit *REdit, int pos, bool dynamic)
{
// получаем маску событий
int eventMask = ::SendMessage(REdit->Handle, EM_SETEVENTMASK, 0, 0);
// отключаем перерисовку
::SendMessage(REdit->Handle, WM_SETREDRAW, false, 0);
// запоминаем выделение
CHARRANGE chrgSave, chrgNew;
::SendMessage(REdit->Handle, EM_EXGETSEL, 0, (LPARAM) &chrgSave);
int startat, toend, foundat, caretpos, slth;
// сброс форматирования
chrgNew.cpMin = pos;
chrgNew.cpMax = -1;
::SendMessage(REdit->Handle, EM_EXSETSEL, 0, (LPARAM) &chrgNew);
REdit->SelAttributes->Color = REdit->Font->Color;
REdit->SelAttributes->Style = REdit->Font->Style;
foundat = -1;
// опции поиска - по словам
TSearchTypes sOpts = TSearchTypes();
//--------------------------------------------------------------------------
pHiLtEx Gr = nullptr;
std::vector<pHiLtEx>::iterator it;
TPoint cp;
GetCaretPos(&cp);
for ( it=vGroups.begin(); it < vGroups.end(); it++ )
{ // цикл по вектору
Gr = *it;
if (Gr->ByWords) sOpts = TSearchTypes() << stWholeWord; // опции поиска - по словам
else sOpts = TSearchTypes(); // опции поиска - по символам
// ищем по списку ключевых символов...
for (int i=0; i<Gr->KeyWords->Count; i++)
{
startat = pos;
toend = REdit->Text.Length();
// если найдено следующее совпадение...
while (0 <= (foundat = REdit->FindText(Gr->KeyWords->Strings[i], startat, toend, sOpts)))
{
// выделяем текст
chrgNew.cpMin = foundat;
chrgNew.cpMax = foundat + Gr->KeyWords->Strings[i].Length();
::SendMessage(REdit->Handle, EM_EXSETSEL, 0, (LPARAM) &chrgNew);
// и применяем формат
REdit->SelAttributes->Color =Gr->Format->FontColor;
REdit->SelAttributes->Style =Gr->Format->FontStyle;
if(!dynamic){ }
// обновляем переменные для поиска
startat += Gr->KeyWords->Strings[i].Length();
toend = REdit->Text.Length() - startat;
}
}
}
TRect r;//прямоугольник который будем перерисовывать
r.Right=REdit->ClientWidth;
r.Top=cp.y-30;//с небольшим запасом на всякий)
r.Bottom=cp.y+30;
//--------------------------------------------------------------------------
// восстанавливаем положение каретки / выделение
::SendMessage(REdit->Handle, EM_EXSETSEL, 0, (LPARAM) &chrgSave);
// восстанавливаем перерисовку
::SendMessage(REdit->Handle, WM_SETREDRAW, true, 0);
if(!dynamic) ::InvalidateRect(REdit->Handle, 0, true); else ::InvalidateRect(REdit->Handle, &r, true);
// восстанавливаем маску событий
::SendMessage(REdit->Handle, EM_SETEVENTMASK, 0, eventMask);
}
// Перегруженная функция Highlight для парсинга всего текста:
void __fastcall TFEditor::HighLight(TRichEdit *REdit)
{
HighLight(REdit, 0, false); // всего и делов :)
}
// Функция HighlightDynamic для динамического парсинга текста при наборе:
void __fastcall TFEditor::HighLightDynamic(TRichEdit *REdit)
{
// сдвигаемся на 2 слова назад
int pos = ::SendMessage(REdit->Handle, EM_FINDWORDBREAK, WB_MOVEWORDLEFT, REdit->SelStart);
pos = ::SendMessage(REdit->Handle, EM_FINDWORDBREAK, WB_MOVEWORDLEFT, pos);
HighLight(REdit, pos, true);
}