![](/user_photo/_userpic.png)
Мансуров. Основы программирования в среде Lazarus. 2010
.pdfГлава 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
![](/html/66936/286/html_e6jHPkGZZp.5LuV/htmlconvd-udfP_F572x1.jpg)
6.3 Визуальное программирование в среде Lazarus
____________________________________________________________________
Рис. 6.49. Стандартный диалог сохранения файла в Windows.
Рис. 6.50. Стандартный диалог сохранения файла в Linux.
Так, загружать файлы в TMemo и сохранять мы научились. Теперь давайте посмотрим, какие манипуляции со строками можно будет делать.
Во-первых, можно сортировать. Если набор строк содержит только симво-
572
![](/html/66936/286/html_e6jHPkGZZp.5LuV/htmlconvd-udfP_F573x1.jpg)
Глава 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
![](/html/66936/286/html_e6jHPkGZZp.5LuV/htmlconvd-udfP_F577x1.jpg)
Глава 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