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

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

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

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

____________________________________________________________________

AutoSelect = true

EditMask = #9999;0;

TabOrder = 1

свойство Text оставьте пустым.

Установите символ заполнитель такой же, что и для MaskEdit1.

В LabeledEdit3 и BitBtn1 свойству TabStop присвойте значение

false.

Обработчики событий запишите в виде:

procedure TForm1.FormShow(Sender: TObject); begin

MaskEdit1.SetFocus;

end;

procedure TForm1.SpeedButton1Click(Sender: TObject); begin

LabeledEdit3.Text:= IntToStr(StrToInt(MaskEdit1.Text)

+ StrToInt(MaskEdit2.Text));

StatusBar1.SimpleText:= 'Сложение';

MaskEdit1.SetFocus;

MaskEdit1.SelectAll;

end;

procedure TForm1.SpeedButton2Click(Sender: TObject); begin

LabeledEdit3.Text:= IntToStr(StrToInt(MaskEdit1.Text)

- StrToInt(MaskEdit2.Text));

StatusBar1.SimpleText:= 'Вычитание';

MaskEdit1.SetFocus;

MaskEdit1.SelectAll;

end;

531

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

____________________________________________________________________

procedure TForm1.SpeedButton3Click(Sender: TObject); begin

LabeledEdit3.Text:= IntToStr(StrToInt(MaskEdit1.Text)

* StrToInt(MaskEdit2.Text));

StatusBar1.SimpleText:= 'Умножение';

MaskEdit1.SetFocus;

MaskEdit1.SelectAll;

end;

procedure TForm1.SpeedButton4Click(Sender: TObject); begin

try

LabeledEdit3.Text:= IntToStr(StrToInt(MaskEdit1.Text)

div StrToInt(MaskEdit2.Text));

except

on EDivByZero do

ShowMessage('Ошибка! Произошло деление на ноль.' + ' Вероятно Вы ошиблись при вводе второго числа');

end;

StatusBar1.SimpleText:= 'Деление нацело';

MaskEdit1.SetFocus;

MaskEdit1.SelectAll;

end;

Как видите, обработку исключений на возможные ошибки преобразования типов мы убрали, поскольку MaskEdit не позволит пользователю ввести не-

допустимые символы. Но в обработчике операции деления исключение, возни-

кающее при попытке деления на ноль мы, естественно, оставили.

Переход от MaskEdit1 к MaskEdit2 и обратно осуществляйте кла-

вишей Tab.

532

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

____________________________________________________________________

Впрочем, можете добавить обработчик OnKeyPress для MaskEdit1:

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

begin

if Key = #13 then begin

MaskEdit2.SetFocus; SpeedButton1.Down:= false; SpeedButton2.Down:= false; SpeedButton3.Down:= false; SpeedButton4.Down:= false; exit;

end;

end;

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

нента TLabeledEdit. Реализуем полный контроль ввода целых чисел с уче-

том знака. Для этого создадим простое приложение. Поместите на форму два компонента TLabeledEdit и одну кнопку TButton, рис. 6.34.

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

Установите свойство TabOrder=0 и TabStop=true

для

533

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

____________________________________________________________________

LabeledEdit1, и TabOrder=1, TabStop=true для TButton1, а для

LabeledEdit2 свойство TabStop=false. Это для того, чтобы при нажатии клавиши Tab фокус автоматически перемещался с LabeledEdit1 на кнопку

иобратно. Кроме того, установите свойство AutoSelect для

LabeledEdit1 равным true.

Будем вводить числа в окне LabeledEdit1, затем введенное число про-

сто выведем в LabeledEdit2, но не "сразу"! Сначала преобразуем его во внутреннее представление целого числа для того, чтобы "выловить" ошибки.

Если будут ошибки при вводе, то естественно, преобразования не произойдет и возникнет исключение EConvertError. Для отладки и тестирования нашего приложения нам хватит и стандартной реакции системы, поэтому обработку исключения мы делать не будем. Добавьте лишь исключение

EConvertError в список игнора через меню

Окружение->Параметры>Отладчик->Исключения языка, чтобы удоб-

нее было запускать наше приложение из среды Lazarus.

Итак, с чего начнем? Задача вполне ясная. Необходимо обеспечить ввод пользователем только цифр от 0 до 9 и знака минус (-) (знак плюс (+) перед числом обычно не ставится). Для этого проще всего воспользоваться опреде-

ленным в Паскаль типом – множество и оператором in для определения при-

надлежности символа к допустимым.

В LabeledEdit1 для события OnKeyPress напишите следующий об-

работчик:

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

begin

{разрешаем только цифры, знак минус и кл. BackSpace } if not (Key in ['0' .. '9', '-' , #8])

534

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

____________________________________________________________________

then Key:= #0;

end;

В операторе if если пользователь нажимает на клавиши отличные от цифр, клавиши BackSpace и знака (-) параметру Key присваивается нулевой символ.

Для события OnClick кнопки напишите следующий обработчик:

procedure TForm1.Button1Click(Sender: TObject);

begin

LabeledEdit1.SetFocus;

n:= StrToInt(LabeledEdit1.Text);

LabeledEdit2.Text:= IntToStr(n);

end;

Не забудьте объявить переменную n целого типа:

var

Form1: TForm1;

n: integer;

Запустите приложение. Попробуйте ввести символы, отличные от цифр и знака минус. Вы видите, что недопустимые символы просто не появляются в окне ввода. И что? Задача решена? К сожалению, нет!

Введите несколько цифр, а затем знак минус. Например, "2010-". Если нажать на кнопку, получите сообщение об ошибке. Потому что знак числа ста-

вится перед первой значащей цифрой. Или введите сначала два или более знака

(-), затем цифры, например, "--2010". Опять получите ошибку.

Вы скажете, ну не может быть, чтобы пользователь допускал такие ошиб-

ки! Не настолько же пользователь глуп и туп! И вы правы! Речь может идти о случайных ошибках. Мы на протяжении этой книги не раз говорили об этом.

Программа должна быть защищена от любых случайных и непреднамеренных

535

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

____________________________________________________________________

ошибок пользователя!

Значит после ввода цифр, знак (-) тоже должен быть запрещен. Кроме того,

необходимо разрешить ввод знака числа только один раз, причем вначале чис-

ла! Для этого введем логическую переменную, назовем ее sign. Первоначаль-

но ее значение будет равно false. Как только пользователь нажал на хотя бы один допустимый символ, включая знак числа, переменной sign присваиваем значение true.

Обработчик для LabeledEdit1 переписываем в следующем виде, заод-

но разрешим пользователю заканчивать ввод нажатием клавиши Enter:

procedure TForm1.LabeledEdit1KeyPress(Sender: TObject;

var Key: char);

begin

if Key = #13 then

begin

sign:= false;

n:= StrToInt(LabeledEdit1.Text);

LabeledEdit2.Text:= IntToStr(n);

end;

{разрешаем только цифры, знак минус и кл. BackSpace } if not (Key in ['0' .. '9', '-' , #8]) then

begin Key:= #0; exit;

end;

if (Key = '-') and (sign) then Key:= #0;

sign:= true;

536

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

____________________________________________________________________

end;

Оператор

if (Key = '-') and (sign)

then Key:= #0;

не позволит пользователю ввести знак числа после значащих цифр и, кроме то-

го, дважды ввести знак (-).

Теперь, кажется все. Но нет, еще не все! Представьте ситуацию – пользо-

ватель хотел ввести отрицательное число, но забыл ввести знак минус, а цифры уже ввел. Попробуйте ввести несколько цифр, затем вернуть курсор на начало строки и попытайтесь ввести (-). У вас не получится! Даже если вы удалите введенные цифры клавишей Delete или BackSpace. Потому что sign имеет значение true. Ситуация не столь проста, как кажется. Чтобы ввести отрица-

тельное число нужно сначала нажать на кнопку "Ввод" или на клавишу Enter,

т.е. пользователь будет вынужден ввести число, которое не хотел вводить!

Придется контролировать положение курсора. У компонента есть свойство

SelStart, которое указывает на текущее положение курсора. Используя это свойство и функцию Pos, перепишем обработчик следующим образом:

procedure TForm1.LabeledEdit1KeyPress(Sender: TObject;

var Key: char);

begin

if Key = #13 then

begin

sign:= false;

n:= StrToInt(LabeledEdit1.Text);

LabeledEdit2.Text:= IntToStr(n);

exit;

537

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

____________________________________________________________________

end;

{разрешаем только цифры, знак минус и кл. BackSpace } if not (Key in ['0' .. '9', '-' , #8]) then

begin Key:= #0; exit;

end;

if (Key = '-') and (sign) then

begin

if (LabeledEdit1.SelStart <> 0) then

begin Key:= #0; exit;

end else

if (Pos('-', LabeledEdit1.Text) <> 0) then Key:= #0;

end;

sign:= true; end;

Обработчик работает следующим образом – если текущий символ знак (-)

и цифры введены, то проверяем позицию курсора. Если курсор установлен на начало и минуса нет, то разрешаем ввод знака.

Уф! Наконец-то должно все заработать как надо. Но есть нюанс!

Попробуйте ввести только один знак (-) и больше ничего. Опять получите

538

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

____________________________________________________________________

ошибку. Но это уже слишком, воскликнете вы! Кому придет в голову вводить один только минус. Ну, а вдруг, чисто случайно? И еще. А что если, пользова-

тель ничего не введя, опять же случайно, нажмет кнопку или Enter, т.е. будет введена пустая строка?

У вас не возникает ощущения, что мы пишем программу для американцев? (Как говорил М. Задорнов – "Ну, тупые…!).

Сделаем так, если длина строки равна единице и это знак (-), то запрещаем ввод.

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

begin

if Key = #13 then begin

sign:= false;

if Length(LabeledEdit1.Text) = 0 // если пустая строка then exit;

if (Length(LabeledEdit1.Text) = 1) and (LabeledEdit1.Text = '-')

then exit;

n:= StrToInt(LabeledEdit1.Text); LabeledEdit2.Text:= IntToStr(n); exit;

end;

{разрешаем только цифры, знак минус и кл. BackSpace } if not (Key in ['0' .. '9', '-' , #8]) then

begin Key:= #0;

539

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

____________________________________________________________________

exit;

end;

if (Key = '-') and (sign) then

begin

if (LabeledEdit1.SelStart <> 0) then

begin Key:= #0; exit;

end else

if (Pos('-', LabeledEdit1.Text) <> 0) then Key:= #0;

end;

sign:= true; end;

procedure TForm1.Button1Click(Sender: TObject); begin

LabeledEdit1.SetFocus; sign:= false;

if Length(LabeledEdit1.Text) = 0 // если пустая строка then exit;

if (Length(LabeledEdit1.Text) = 1)and (LabeledEdit1.Text = '-')

then exit else

n:= StrToInt(LabeledEdit1.Text);

540