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

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

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

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

____________________________________________________________________

LCLProc; type

{ TForm1 }

TForm1 = class(TForm)

Button1: TButton;

Edit1: TEdit;

Label1: TLabel;

Memo1: TMemo;

procedure Button1Click(Sender: TObject); procedure Edit1KeyPress(Sender: TObject; var Key: char);

procedure CyrillicSearch;

procedure FormShow(Sender: TObject); private

{private declarations } public

{public declarations } end;

var

Form1: TForm1; implementation { TForm1 }

procedure TForm1.CyrillicSearch; var

k: integer;

text_UTF8, str_UTF8: string; begin

Edit1.SetFocus;

581

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

____________________________________________________________________

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;

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}

582

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

____________________________________________________________________

Memo1.Lines.Add(str);

tfile.Free;

Edit1.SetFocus;

end;

procedure TForm1.Button1Click(Sender: TObject); begin

CyrillicSearch;

end;

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: char);

begin

if Key = #13 then begin

Key:= #0;

CyrillicSearch;

end;

end; initialization

{$I unit1.lrs} end.

При такой реализации наша программа находит лишь первое вхождение искомой подстроки. Чтобы найти все вхождения будем "скармливать" функции

Pos строку каждый раз без последней найденной подстроки. Для этого исполь-

зуем свойства SelStart и SelLength Memo1 и функцию UTF8Copy таким образом:

583

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

____________________________________________________________________

text_UTF8:=UTF8Copy(UTF8Decode(Memo1.Text),

Memo1.SelStart + 1 + Memo1.SelLength,

Length(UTF8Decode(Memo1.Text)) -

Memo1.SelStart - Memo1.SelLength);

Функцию UTF8Copy мы рассматривали в 3.3.1.4. Чтобы выделить в

Memo1 следующую найденную подстроку оператор

Memo1.SelStart:= k - 1;

надо заменить на

Memo1.SelStart:=Memo1.SelStart +

Memo1.SelLength + k - 1;

Теперь программа находит все вхождения заданной подстроки в Memo1.

Для нахождения следующего вхождения нужно нажимать на кнопку "Найти".

Нажимать на клавишу Enter нельзя, так как фокус находится в Memo1. Чтобы продолжить поиск нажатием Enter надо клавишей Tab или мышью устано-

вить фокус на Edit1. Появляется некоторое неудобство в работе. Если же мы в программе сразу после нахождения подстроки и его выделения передадим фо-

кус Edit1, то с найденного фрагмента выделение будет снято. Что тоже нехо-

рошо.

Можно добавить обработчик Memo1KeyPress, чтобы только при нажа-

тии Enter передать фокус Edit1. Итак, код улучшенной программы (предва-

рительно установите в Memo1 свойство WantReturns= false):

unit Unit1;

{$mode objfpc}{$H+}

interface

584

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

____________________________________________________________________

uses

Classes, SysUtils, FileUtil, LResources, Forms,

Controls, Graphics, Dialogs, StdCtrls, LconvEncoding,

LCLProc;

type

{ TForm1 }

TForm1 = class(TForm)

Button1: TButton;

Edit1: TEdit;

Label1: TLabel;

Memo1: TMemo;

procedure Button1Click(Sender: TObject); procedure Edit1KeyPress(Sender: TObject; var Key: char);

procedure CyrillicSearch;

procedure FormShow(Sender: TObject); procedure Memo1KeyPress(Sender: TObject;

var Key: char);

private

{private declarations } public

{public declarations } end;

var

Form1: TForm1; implementation { TForm1 }

585

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

____________________________________________________________________

procedure TForm1.CyrillicSearch; var

k: integer;

text_UTF8, str_UTF8: string; begin

Edit1.SetFocus;

if Edit1.Text= '' then begin

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

end;

text_UTF8:= UTF8Copy(UTF8Decode(Memo1.Text),

Memo1.SelStart + 1 + Memo1.SelLength,

UTF8Length(UTF8Decode(Memo1.Text)) -

Memo1.SelStart - Memo1.SelLength);

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

begin Memo1.SetFocus;

Memo1.SelStart:= Memo1.SelStart +

Memo1.SelLength + k - 1;

Memo1.SelLength:= UTF8Length(str_UTF8); end

else begin

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

Memo1.SelStart:= 0;

Memo1.SelLength:= 0;

586

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

____________________________________________________________________

end;

end;

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); Memo1.SelStart:= 0; Memo1.SelLength:= 0; tfile.Free; Edit1.SetFocus;

end;

procedure TForm1.Memo1KeyPress(Sender: TObject; var Key: char);

begin

if Key = #13 then Edit1.SetFocus; CyrillicSearch;

end;

587

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

____________________________________________________________________

procedure TForm1.Button1Click(Sender: TObject); begin

CyrillicSearch;

end;

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: char);

begin

if Key = #13 then begin

Key:= #0;

CyrillicSearch;

end;

end; initialization

{$I unit1.lrs} end.

Практически во всех текстовых редакторах функцию поиска можно запус-

тить, используя сочетание клавиш Ctrl+F. А продолжение поиска нажатием клавиши F3. Возьмите, например, Word, "Блокнот" или "Редактор исходного кода" Lazarus.

Давайте и мы реализуем такой же вызов поиска в TMemo. Заодно научимся использовать в программе несколько форм. Создайте новый проект. Поместите на форму компонент TMemo, рис. 6.53.

588

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

____________________________________________________________________

Рис. 6.53. Главная форма приложения

В меню "Файл" выберите пункт "Создать форму". В окне редактора исход-

ного кода появится новая пустая форма и соответствующий ей модуль с именем

Unit2. Поместите на вторую форму надпись, TEdit и кнопку, рис. 6.54.

Рис. 6.54. Вторая форма приложения

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

те Shift+F12 и в появившемся окне выберите нужную вам форму, рис. 6.55.

Рис. 6.55. Окно выбора формы

589

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

____________________________________________________________________

В Unit1 после ключевого слова implementation поместите

uses Unit2;

А в Unit2 после ключевого слова implementation поместите

uses Unit1;

Ранее, для распознавания нажатого символа мы использовали обработчик события OnKeyPress, однако при этом событии нельзя распознать нажатие функциональных и служебных клавиш. Для их распознавания подходит собы-

тие OnKeyDown.

Заголовок обработчика события OnKeyDown имеет следующий вид:

procedure TForm1.Memo1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);

Параметр Key определяет нажатую в момент события клавишу. Так же как и для события OnKeyPress он определен как var, т.е. может изменяться в об-

работчике события. Но, обратите внимание, что это целое число, а не символ.

Коды клавиш можно указывать в десятичном или шестнадцатеричном виде.

Для некоторых клавиш введены также именованные константы, которые облег-

чают написание программы, поскольку не требуют помнить численные коды клавиш. Например, вместо

if (Key = 13) then ... ;

можно записать

if (Key = VK_RETURN) then ... ;

590