Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C++ Builder > Выделение жирным всех известных проге слов


Автор: mr.Anderson 23.6.2006, 17:02
Помогите кто-нибудь...

Хочу сделать у себя в блокноте выделение жирным шрифтом всех ключевых слов в C++. И не надо отсылать меня к SynHighlighter или еще куда! Мне самому хочется сделать... и не только потому, что просто хочется. У меня есть на то причины....

Для решения задачи поместил на форму TRichEdit с именем RichEdit1.

Сверху объявляю глобальный AnsiString - массив, содержащий все известные программе слова. Пока для краткости сделал только 2 слова:
Код

const int BASESIZE = 2;
const AnsiString BASE[ BASESIZE ] = { "int", "float" };

Теперь создаю событие OnChange у RichEdit'а, пишу в нем вот такое:
Код

 int curpos = 1; //Метка, откуда начинать поиск
 int cursor = RichEdit1->SelStart;
 TSearchTypes opt;
 opt << stMatchCase;

 for( int x=0; x < BASESIZE; x++ ) //Перебираем всю базу слов
 {
  if( ! RichEdit1->FindTextA( BASE[ x ], curpos, RichEdit1->Text.Length(), opt) ) return;

  curpos = RichEdit1->FindTextA( BASE[ x ], curpos, RichEdit1->Text.Length(), opt) + BASE[ x ].Length(); //Устанавливаем новое значение метки (позиция после найденного слова)

  //Выделяем найденное слово
  RichEdit1->SelStart = curpos - BASE[ x ].Length() - 1;
  RichEdit1->SelLength = BASE[ x ].Length();
  RichEdit1->SelAttributes->Style = RichEdit1->SelAttributes->Style << fsBold;

  //Снимаем выделение с остальной части текста (после слова и до слова)
  RichEdit1->SelStart = curpos;
  RichEdit1->SelLength = RichEdit1->Text.Length();
  RichEdit1->SelAttributes->Style = RichEdit1->SelAttributes->Style >> fsBold;

  RichEdit1->SelStart = 0;
  RichEdit1->SelLength = curpos - BASE[ x ].Length() - 1;
  RichEdit1->SelAttributes->Style = RichEdit1->SelAttributes->Style >> fsBold;
 }

 RichEdit1->SelStart = cursor;

Но пишу что-нить - в тексте вообще ничего не выделяется. Только текст помаргивает во время набора. Что такое? Объясните, где я ошибся... 

Автор: mr.Anderson 23.6.2006, 18:09
Так... Нашел пару ошибок, немного поправил, но работает снова не так, как надо...
Код

static int curpos = 1; //Óêàçûâàåò ïîçèöèþ, ñ êîòîðîé íà÷èíàòü ïîèñê
 int cursor = RichEdit1->SelStart;
 TSearchTypes opt;
 opt << stMatchCase;

 for( int x=0; x < BASESIZE; x++ ) //ïåðåáèðàåì âñå ñëîâà â áàçå
 {
  if( ! (RichEdit1->Text.Delete(1, curpos)).Pos( BASE [ x ] ) )
   continue;

  curpos = RichEdit1->FindTextA( BASE[ x ], curpos, RichEdit1->Text.Length()-curpos, opt) + BASE[ x ].Length(); //Ìåíÿåì ìåòêó
  ShowMessage("Òåêóùàÿ ïîçèöèÿ êóðñîðà: "+IntToStr(curpos));

  //Âûäåëÿåì ýòî ñëîâî
  RichEdit1->SelStart = curpos - BASE[ x ].Length();
  ShowMessage("Òåêóùàÿ ïîçèöèÿ íà÷àëà âûäåëåíèÿ ñëîâà: "+IntToStr(RichEdit1->SelStart));

  RichEdit1->SelLength = BASE[ x ].Length();
  RichEdit1->SelAttributes->Style = RichEdit1->SelAttributes->Style << fsBold;

  //Ñíèìàåì âûäåëåíèå ñ îñòàëüíîé ÷àñòè òåêñòà ïîñëå ñëîâà
  RichEdit1->SelStart = curpos;
  ShowMessage("Òåêóùàÿ ïîçèöèÿ íà÷àëà âûäåëåíèÿ äëÿ óáèðàíèÿ æèðíîñòè ïîñëå ñëîâà: "+IntToStr(RichEdit1->SelStart));
  RichEdit1->SelLength = RichEdit1->Text.Length()-curpos;
  RichEdit1->SelAttributes->Style = RichEdit1->SelAttributes->Style >> fsBold;
  //Ñíèìàåì âûäåëåíèå ñ îñòàëüíîé ÷àñòè òåêñòà äî ñëîâà
  RichEdit1->SelStart = 0;
  RichEdit1->SelLength = curpos - BASE[ x ].Length();
  RichEdit1->SelAttributes->Style = RichEdit1->SelAttributes->Style >> fsBold;
 }

 RichEdit1->SelStart = cursor;

На Юникод плиз внимания не обращайте, просто времени нет его исправлять... Суть в том, что выделяет слово, но выделение с остального текста не снимает - весь текст получается жирным. Плюс второе слово из массива вообще не находит. 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)