Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Мансуров. Основы программирования в среде Lazarus. 2010

.pdf
Скачиваний:
45
Добавлен:
27.04.2021
Размер:
6.3 Mб
Скачать

Глава 6 Программирование приложений с графическим интерфейсом

____________________________________________________________________

му. Обратите внимание на оператор

fname:= UTF8ToSys(fname);

Если имя файла, а также путь содержит кириллицу, то необходимо строку с именем файла и путем преобразовать в системную кодировку.

Для вызова диалога сохранения файла необходимо написать следующий

код:

procedure TForm1.Button2Click(Sender: TObject); var

fname, str: string; tfile: TStringList;

begin

tfile:= TStringList.Create; // создание списка строк str:=Memo1.Text;

{$IFDEF WINDOWS}

str:= UTF8ToSys(str);// преобразование в системную кодировку

{$ENDIF} tfile.Add(str);

SaveDialogl.FileName:= fname; if SaveDialogl.Execute

then fname:= SaveDialogl.FileName;

// преобразование в системную кодировку

fname:= UTF8ToSys(fname);

tfile.SaveToFile(fname);

tfile.Free;

end;

При нажатии кнопки Button2 будет открыт стандартный диалог сохране-

ния файла, рис. 6.49, 6.50.

571

6.3 Визуальное программирование в среде Lazarus

____________________________________________________________________

Рис. 6.49. Стандартный диалог сохранения файла в Windows.

Рис. 6.50. Стандартный диалог сохранения файла в Linux.

Так, загружать файлы в TMemo и сохранять мы научились. Теперь давайте посмотрим, какие манипуляции со строками можно будет делать.

Во-первых, можно сортировать. Если набор строк содержит только симво-

572

Глава 6 Программирование приложений с графическим интерфейсом

____________________________________________________________________

лы латиницы, организовать сортировку достаточно тривиально. Можно устано-

вить просто свойство Sorted: true в TStringList и строки будут отсор-

тированы по алфавиту автоматически. Можно применить метод Sort.

Создайте новый проект. Спроектируйте окно будущего приложения на форме так, как показано на рис. 6.51.

Рис. 6.51. Форма приложения

В обработчике нажатия кнопки введите код:

procedure TForm1.Button1Click(Sender: TObject);

var

strList: TStringList;

begin

strList:= TStringList.Create;

strList.Duplicates:= dupAccept;

strList.AddStrings(Memo1.Lines);

strList.Sort;

Memo2.Clear;

573

6.3 Визуальное программирование в среде Lazarus

____________________________________________________________________

Memo2.Lines.AddStrings(strList);

strList.Free;

end;

В Memo1 введите несколько строк латиницей. При нажатии кнопки "Сортиро-

вать" в Memo2 выведутся строки, отсортированные в алфавитном порядке.

Однако этот код не работает для строк, содержащих кириллицу. Происхо-

дит это, опять же, из-за кодировки UTF-8. По умолчанию TStringList ис-

пользует следующую функцию, которая работает с ANSI строками:

function TStringList.DoCompareText(const s1,s2 : string)

: PtrInt;

begin

if FCaseSensitive then

result:= AnsiCompareStr(s1,s2)

else

result:= AnsiCompareText(s1,s2);

end;

К счастью, среди методов класса TStringList имеется метод

CustomSort. Его объявление в классе имеет вид:

type

TStringListSortCompare = function(List: TStringList; Indexl, Index2: integer): integer;

procedure CustomSort(CompareFn: TStringListSortCompare);

Можно воспользоваться методом CustomSort передав ему в качестве па-

раметра свою функцию сравнения. Чтобы отсортировать список, построим функцию сравнения двух элементов S1 и S2 с индексами indexl и index2

574

Глава 6 Программирование приложений с графическим интерфейсом

____________________________________________________________________

соответственно, которая должна возвращать:

<0 — если, S1 < S2;

0 — если, S1 = S2;

> 0 — если, S1 > S2;

Функция имеет вид:

function ListSortRus(List: TStringList; Index1, Index2:

integer): integer;

begin

Result:= WideCompareText(UTF8Decode(List[Index1]),

UTF8Decode(List[Index2]));

end;

Здесь используется функция:

function WideCompareText(const S1: WideString; const S2:

WideString): integer;

Она работает со строками WideString. Тип WideString представляет собой динамически размещаемые в памяти строки, длина которых ограничена только объемом свободной памяти. Каждый символ строки типа WideString

является Unicode-символом. Функция возвращает результат:

<0 — если, S1 < S2;

0 — если, S1 = S2;

> 0 — если, S1 > S2;

Это как раз то, что нам нужно! В разделе implementation добавьте описание функции

575

6.3 Визуальное программирование в среде Lazarus

____________________________________________________________________

function ListSortRus(List: TStringList; Index1, Index2: integer): integer;

begin

Result:= WideCompareText(UTF8Decode(List[Index1]),

UTF8Decode(List[Index2]));

end;

Функция

UTF8Decode(const S: UTF8String): WideString - преобразует

строку формата UTF-8 к строке формата Unicode.

Перепишите обработчик OnClick кнопки:

procedure TForm1.Button1Click(Sender: TObject); var

strList: TStringList; begin

strList:= TStringList.Create; strList.Duplicates:= dupAccept; strList.AddStrings(Memo1.Lines); strList.CustomSort(@ListSortRus); Memo2.Clear; Memo2.Lines.AddStrings(strList); strList.Free;

end;

В обработчике изменилась только одна строка. Вместо метода Sort вы-

зывается CustomSort(@ListSortRus). Как видите, чтобы передать функ-

цию как параметр, надо перед именем функции поставить знак @.

576

Глава 6 Программирование приложений с графическим интерфейсом

____________________________________________________________________

Теперь сортировка будет правильно работать как для латиницы, так и для кириллицы.

Во-вторых, довольно часто необходимо осуществлять поиск. Причем не только отдельных строк целиком, но и некоторой части строки (говорят еще подстроки). Если говорить о тексте, то необходимо найти слово, фразу или предложение, причем предложение может занимать несколько строк.

Для поиска удобно использовать свойство Text компонента TMemo в ко-

тором весь набор строк представляется в виде одной длинной строки и функ-

цию Pos, которую мы изучали в 3.3. Составим программу поиска слов в тек-

стовом файле. Создайте новый проект. Поместите на форму компоненты как показано на рис. 6.52.

Рис. 6.52. Форма приложения

Введите следующий код:

procedure TForm1.FormShow(Sender: TObject);

begin

Memo1.Lines.LoadFromFile('File in English.txt');

Edit1.SetFocus;

577

6.3 Визуальное программирование в среде Lazarus

____________________________________________________________________

end;

procedure TForm1.Button1Click(Sender: TObject); var

k: integer; begin

Edit1.SetFocus;

Edit1.SelectAll;

if Edit1.Text= '' then begin

ShowMessage('Введите строку для поиска'); exit;

end;

k:= Pos(Edit1.Text, Memo1.Text); if k > 0 then

begin Memo1.SetFocus;

Memo1.SelStart:= k - 1 ;

Memo1.SelLength:= Length(Edit1.Text);

end else

ShowMessage('Строка не найдена'); end;

Во время создания окна программы в Memo1 загружается текстовый файл.

В обработчике нажатия кнопки осуществляется поиск фрагмента текста, вве-

денного пользователем в поле ввода Edit1. Для выделения найденного фраг-

мента используется свойство Memo1.SelStart и Memo1.SelLength. Что-

бы найденный текст был выделен необходимо, чтобы фокус был установлен в

578

Глава 6 Программирование приложений с графическим интерфейсом

____________________________________________________________________

Memo1. В этом примере мы осуществляли поиск в текстовом файле, в котором содержится только английские буквы. Для текста, содержащего кириллицу,

наша программа работать корректно не будет.

Поэтому нам придется видоизменить программу для поиска в текстовых файлах, содержащих кириллицу. В обработчике OnCreate формы загружаем кириллический текст в Memo1, предварительно преобразовав его в UTF-8 (для

Windows). В обработчике OnClick мы используем уже знакомую нам функ-

цию UTF8Decode, а также функции UTF8Pos и UTF8Length. Не забудьте включить модуль LCLProc в объявление uses.

procedure TForm1.FormShow(Sender: TObject); var

tfile: TStringList; str: string;

begin

tfile:= TStringList.Create; tfile.LoadFromFile('File in Russian.txt'); str:= tfile.Text;

{$IFDEF WINDOWS}

str:= SysToUTF8(str); // преобразование в кодировку UTF-8

{$ENDIF} Memo1.Lines.Add(str); tfile.Free;

end;

procedure TForm1.Button1Click(Sender: TObject); var

k: integer;

text_UTF8, str_UTF8: string; begin

579

6.3 Визуальное программирование в среде Lazarus

____________________________________________________________________

Edit1.SetFocus;

if Edit1.Text= '' then

begin

ShowMessage('Введите строку для поиска'); exit;

end;

text_UTF8:= UTF8Decode(Memo1.Text); str_UTF8:= UTF8Decode(Edit1.Text); k:= UTF8Pos(str_UTF8, text_UTF8); if k > 0 then

begin Memo1.SetFocus;

Memo1.SelStart:= k - 1;

Memo1.SelLength:= UTF8Length(str_UTF8);

end else

ShowMessage('Строка не найдена'); end;

Позволим пользователю заканчивать ввод в Edit1 нажатием клавиши

Enter. Чтобы избежать дублирования кода, создадим процедуру

CyrillicSearch и в обработчиках будем вызывать эту процедуру:

unit Unit1;

{$mode objfpc}{$H+} interface

uses

Classes, SysUtils, FileUtil, LResources, Forms,

Controls, Graphics, Dialogs, StdCtrls, LconvEncoding,

580