Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Л11.doc
Скачиваний:
11
Добавлен:
30.10.2018
Размер:
154.11 Кб
Скачать
  1. Діалоги пошуку і заміни тексту — компоненти FindDialog і ReplaceDialog

Компоненти FindDialog і ReplaceDialog, що викликають діалоги пошуку і заміни фрагментів тексту, дуже схожі і мають однакові властивості, окрім однієї, яка задає замінюючий текст в компоненті ReplaceDialog. Така схожість не диво, оскільки ReplaceDialog — похідний клас від FindDialog.

Самі по собі компоненти FindDialog і ReplaceDialog не здійснюють ні пошуку, ні заміни. Вони тільки забезпечують інтерфейс з користувачем. А пошук і заміну треба здійснювати програмно. Для цього можна користуватися подією OnFind, що відбувається, коли користувач натиснув в діалозі кнопку Знайти далі, і подією OnReplace, що виникає, якщо користувач натиснув кнопку Замінити або Замінити все. У події OnReplace дізнатися, яку саме кнопку натиснув користувач, можна по значеннях прапорів frReplace і frReplaceAll.

Пошук заданого фрагмента в компоненті RichEdit легко проводити, використовуючи його метод FindText, оголошений таким чином:

int fastcall FindText(const System::AnsiString SearchStr,

int StartPos, int Length, TSearchTypes Options);

Цей метод шукає в тексті RichEdit фрагмент, заданий параметром SearchStr.

Пошук проводиться, починаючи з позиції StartPos (позиція першого символу тексту вважається нульовою), впродовж Length символів. Параметр Options є множиною, яка може містити елементи stWholeWord (пошук тільки цілого слова) і stMatchCase (пошук з урахуванням регістра). Метод повертає позицію знайденого входження. Якщо заданий фрагмент не знайдений, повертається -1.

Нижче приведений код, що здійснює пошук заданого фрагмента в тексті компоненту RichEdit1. Викликати діалог пошуку можна операторами:

/*початкове значення тексту пошуку - текст, виділений в RichEdit1*/

FindDialog1->FindText = RichEdit1->SelText;

FindDialogl->Execute();

Вони задають як початкове значення для пошуку текст, виділений у вікні RichEdit1, і потім викликають діалог пошуку FindDialog1.

Обробник події OnFind компоненту FindDialogl може мати вигляд:

void fastcall TForm1::FindDialog1Find(TObject *Sender)

{

int FoundAt, StartPos, ToEnd;

TSearchTypes Option;

//якщо текст було виділено, то пошук йде,

//починаючи з його останнього символу, інакше - з позиції курсору

StartPos = RichEdit1->SelStart;

if (RichEdit1->SelLength)

StartPos += RichEdit1->SelLength;

// ToEnd - довжина тексту, починаючи з першої позиції пошуку і до кінця

ToEnd = RichEdit1->Text.Length() - StartPos;

//пошук цілого слова чи ні залежно від параметрів користувача

if (FindDialog1->Options.Contains(frWholeWord))

Option << stWholeWord;

else Option >> stWholeWord;

//пошук з урахуванням або без урахування регістра залежно від

//параметрів користувача

if (FindDialog1->Options.Contains(frMatchCase))

Option << stMatchCase;

else Option >> stMatchCase;

FoundAt=RichEdit1->FindText(FindDialog1->FindText,StartPos,ToEnd,Option);

if (FoundAt != -1) // якщо знайдено

{

RichEdit1->SetFocus();

RichEdit1->SelStart = FoundAt;

RichEdit1->SelLength = FindDialog1->FindText.Length();

}

else ShowMessage("Текст ' " + FindDialog1->FindText + " 'не знайдений" ) ;

}

Функція FindDialog1Find спрацьовує, коли користувач натиснув в діалозі кнопку Знайти далі. Коментарі в тексті цієї функції пояснюють етапи пошуку. Спочатку проводиться установка області тексту (змінні StartPos і ToEnd), в якій проводиться пошук. Потім встановлюються атрибути пошуку — формується множина Option залежно від встановлених користувачем опцій. Потім методом FindText проводиться сам пошук. Якщо нового входження шуканого тексту не знайдено (метод FindText повернув -1), то користувачу видається повідомлення про це за допомогою функції ShowMessage.

Приведений приклад відносився до пошуку в компоненті RichEdit. Для організації пошуку в тексті компоненту Memo зручно використовувати метод Pos класу AnsiString, який оголошений таким чином:

int_fastcall Pos(const AnsiString & subStr) const;

Метод повертає індекс першого символу першого входження підрядка subStr в рядок, до якого застосовується цей метод. Індекси починаються з 1. Якщо subStr не міститься в рядку, то повертається 0.

Для організації пошуку буде потрібно ще дві функції класу AnsiString: Substring і LowerCase. Перша з них визначена як:

AnsiString_fastcall Substring(int index, int count) const;

Вона повертає підрядок, що починається з символу у позиції index і що містить count символів.

Функція LowerCase, визначена як

AnsiString_fastcall LowerCase()const;

повертає рядок символів S, переведений в нижній регістр.

Тепер ми можемо розглянути приклад організації пошуку. Хай у вашому застосуванні є компонент Memo1 і при виборі розділу меню MFind ви хочете організувати пошук в тексті, що міститься в Memo1. Для спрощення завдання виключимо опцію пошуку тільки цілих слів і опцію пошуку вгору від положення курсорe.

Програма, що реалізовує пошук, може мати наступний вигляд:

void_fastcall TForm1::MFindClick(TObject *Sender)

{

//початкове значення тексту пошуку - текст, виділений в Memo1

FindDialog1->FindText = Memo1->SelText;

FindDialog1->Execute();

}

void_fastcall TForm1::FindDialog1Find(TObject *Sender)

{

int FoundAt, StartPos, ToEnd;

//якщо було виділення, то пошук йде, починаючи з його останнього символу, інакше - з позиції курсору

StartPos = Memo1->SelStart;

if {Memo1->SelLength)

StartPos += Memo1->SelLength;

//ToEnd - довжина тексту, починаючи з першої позиції пошуку і до кінця

ToEnd = Memo1->Text.Length()- StartPos;

//пошук з урахуванням або без урахування регістра залежно від //параметрів користувача

if (FindDialog1->Options.Contains(frMatchCase))

FoundAt = StartPos + Memo1->Text.Substring(StartPos + 1,ToEnd) .Pos(FindDialog1->FindText);

else FoundAt = StartPos + Memo1->Text.Substring(StartPos+1, ToEnd) .LowerCase().Pos(FindDialogl->FindText.LowerCase());

if(FoundAt != StartPos) // якщо знайдено

{

Memo1->SetFocus();

Memo1->SelStart = FoundAt-1;

Memo1->SelLength = FindDialog1->FindText.Length();

}

else ShowMessage("Текст '" + FindDialog1->FindText + "' не знайдений");

}

Програма аналогічна до приведеної раніше для компоненту RiehEdit і відрізняється тільки декількома операторами, що здійснюють безпосередньо пошук.

Контрольні питання:

  1. ?

  2. ?

  3. ?

  4. ?

  5. ?

  6. ?

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]