Ракитин Р.Ю. ООП в Turbo Delphi
.PDF61
Рассмотрим приложение, в котором при нажатии
на переключатель RadioGroup в объекте Label отображается название этой кнопки. При этом в зависимости от нажатого переключателя, гарнитура шрифта в метке меняется. Обработаем событие
OnClick.
procedure TForm1.RadioGroup1Click(Sender: TObject); begin
Label1.Caption:='нажата "'+ RadioGroup1.Items.Strings[RadioGroup1.ItemIndex]+ '" кнопка';
case RadioGroup1.ItemIndex of
0:Label1.Font.Name:='Times New Roman';
1:Label1.Font.Name:='Arial';
2:Label1.Font.Name:='Courier New Cyr'; end;
end;
События формы
Рассмотрим описание большинства событий, которые может обрабатывать главная форма приложения. Общее число событий не ограничивается стандартными, они могут быть дополнены обработчиками созданными программистом. Ниже будут рассмотрены события, которые наиболее часто используются в Delphi. События, которые может обработать компонент можно увидеть на вкладке Events (события) инспектора объектов.
OnActivate – генерируется когда приложение стало активным;
OnCanResize – это событие генерируется перед тем, как изменить размер окна. Здесь можно запретить какие-либо изменения или производить какие-то подготовительные действия;
OnClick – генерируется, когда пользователь щелкнул по форме (одинарное нажатие левой кнопкой мыши);
OnClose – генерируется, когда окно закрывается;
OnCloseQuery – генерируется до закрытия окна. В этом обработчике происходит запрос на закрытие, поэтому из этого обработчика можно вывести окно, которое будет запрашивать подтверждение на закрытие;
OnCreate – генерируется, когда окно создается;
OnDblClick – генерируется, когда пользователь дважды щелкнул по окну; OnDeactivate – генерируется, когда окно деактивируется;
OnDestroy – когда окно уничтожается;
ОnHide – генерируется, когда окно исчезает из виду. Событие генерируется даже тогда, когда память, выделенная для окна, не уничтожается;
OnKeyDown – генерируется, когда нажата клавиша на клавиатуре;
62
OnKeyPress – генерируется, когда нажата и отпущена клавиша на клавиатуре; OnKeyUp – генерируется, когда отпущена клавиша на клавиатуре; OnMouseDown – генерируется, когда нажата кнопка мыши;
OnMouseMove – генерируется, когда двигается мышка; OnMouseUp – генерируется, когда отпускается кнопка мыши; OnMouseWheel – генерируется колесиком мыши;
OnMouseWheelDown – генерируется, когда колесико мыши прокручено вниз; OnMouseWheelUp – генерируется, когда колесико мыши прокручено вверх; OnPaint – генерируется, когда надо перерисовать окно;
OnResize – генерируется, когда надо изменить размеры окна; OnShortCut – когда нажата горячая клавиша;
OnShow – когда показывается окно, но его прорисовки ещё не произошло. В этот момент окно уже создано и готово к отображению, но еще не прорисовалось на экране.
Каждое из стандартных событий связано с методами, в которые могут передаваться различные параметры, например код нажатой клавиши, состояние служебных клавиш, координаты мыши т.д. Более подробно основные события и связанные с ними обработчики будут рассмотрены ниже.
Обработка щелчка мыши
Управление большинством программ Windows осуществляется с помощью мыши. Помимо стандартных действий с элементами управления мышь также используется для самых разных дополнительных операций (например, для вызова контекстного меню при щелчке правой кнопкой). В системе Delphi имеется возможность обработки фактического щелчка мышкой на объекте. Такая возможность используется, когда важно просто среагировать на щелчок, не анализируя координаты указателя. Для этого обрабатывают событие OnClick, пример использования данного события был подробно рассмотрен выше.
Такой подход далеко не всегда устраивает разработчика, поэтому в Delphi имеются события: OnMouseDown (при нажатии кнопки мыши) и OnMouseUp (при отпускании кнопки мыши). Они содержат подробную информацию о параметрах щелчка: координаты указателя в рамках клиентской области объекта, на котором был выполнен щелчок, тип щелчка (одинарный или двойной), какая кнопка мыши была нажата/отпущена и в каком состоянии системные клавиши SHIFT, ALT, CTRL.
Обработчики этих событий отличаются только названиями, списки их параметров полностью совпадают. Например, для события OnMouseDown обработчик имеет вид:
63
Procedure TMyForm.ButtonlMouseDown (Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
Параметр Sender определяет, какой объект программы вызывает данную подпрограмму. Тип TMouseButton является перечислимым типом и содержит три значения: mbLeft, mbRight, mbMiddle (признаки использования, соответственно, левой, правой и средней кнопок мыши). Тип TShiftState представляет собой множество системных клавиш и клавиш мыши:
type
TShiftState = set of (ssShift, ssAlt, ssCtrl, ssLeft, ssRight, ssMiddle, ssDouble);
то есть допускается одновременная обработка нескольких клавиш.
Для демонстрации возможностей события создадим следующее приложение. На форме разместим компоненты: Button, BitBtn, CheckBox и RadioButton, а также Label для вывода результата работы. Выделим объект Button и перейдем в окно
Object Inspector (Инспектор объектов) на вкладке Events
создадим обработчик для события OnMouseDown – для
этого перейдем на нужную строку и в правой части два раза щелкнем мышкой. Автоматически создастся заготовка для обработчика события. В обработчике запишем:
procedure TForm1.Button1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer); begin
//приводим тип и выводим его имя
Label1.Caption := 'щелчок на ' + (Sender as TComponent).Name;
{проверяем какая кнопка мыши была нажата и добавляем соответствующую надпись} case Button of
mbMiddle: Label1.Caption:= Label1.Caption+ ' средней кнопкой';
mbLeft: Label1.Caption:= Label1.Caption+
'левой кнопкой'; mbRight:Label1.Caption:= Label1.Caption+
'правой кнопкой';
end;
{проверяем какая служебная кнопка была нажата и добавляем соответствующую надпись}
if ssShift in Shift then
Label1.Caption:= Label1.Caption+' с Shift';
64
if ssAlt in Shift then
Label1.Caption:= Label1.Caption+' с Alt'; end;
Теперь остальным объектам присвоим этот обработчик, для этого выделяем нужный объект
(BitBtn, CheckBox или RadioButton) и, перейдя на вкладку Events, возле события OnMouseDown, выбираем ранее созданный обработчик для Button1. Таким образом, в полученном приложении будет выводиться строка с именем объекта, на который нажали, название клавиши мыши и имя той системной клавиши, которая при этом удерживается.
Обработка нажатия клавиатуры
Помимо событий мыши, необходимо обрабатывать события, возникающие при нажатии различных клавиш на клавиатуре. В оконных компонентах Delphi определены три события, связанные с клавиатурой:
OnKeyDown – событие наступает при нажатии пользователем любой клавиши. Можно распознать нажатые клавиши, включая функциональные клавиши,
икнопки мыши, но нельзя распознать символ нажатой клавиши; OnKeyPress – событие наступает при нажатии пользователем клавиши
символа. Можно распознать только нажатую клавишу символа, различить символ в верхнем и нижнем регистре, различить символы кириллические и латинские, но нельзя распознать функциональные клавиши и кнопки;
OnKeyUp – событие наступает при отпускании пользователем любой клавиши. Можно распознать нажатые клавиши, включая функциональные клавиши
икнопки мыши, но нельзя распознать символ отпускаемой клавиши. Рассмотрим подробнее стандартные обработчики данных событий.
Создадим приложение, в котором разместим три объекта Метка – LbDown, LbUp, LbPress, в них будем выводить случайные числа при наступлении соответствующих событий – OnKeyDown, OnKeyUp, OnKeyPress. Примерный вид приложения показан на рисунке.
Каждый из обработчиков имеет параметр Key, возвращающий код клавиши, которая была нажата на активном объекте. Подробнее о значениях кодов клавиш клавиатуры смотрите в приложении. Так же для обработчиков OnKeyDown, OnKeyUp существует дополнительный параметр Shift, характеризующий состояние служебных клавиш. Данный параметр был рассмотрен ранее.
+ Тип параметра Key зависит от обрабатываемого события. Для
событий OnKeyDown и OnKeyUp он целый, для OnKeyPress –
символьный, поэтому записывается со знаком # или в кавычках.
Создадим обработчики данных событий для формы.
65
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
//срабатывает если нажат Enter и удерживается Shift if (Key=13)and (Shift=[ssShift]) then
LbDown.Caption:=FormatFloat('0.00',random) end;
procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
//срабатывает если отпущен Enter if Key=13 then
LbUp.Caption:=FormatFloat('0.00',random)
end;
procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
begin
//срабатывает если нажат Space if Key=#32 then
LbPress.Caption:=FormatFloat('0.00',random)
end;
Как видно из приведенного примера, необходимые действия связываются с нажатием определенной клавиши. Такой подход позволяет в одном обработчике описывать действия, происходящие при нажатии нескольких клавиш на клавиатуре.
Часто возникает необходимость запретить пользователю вводить определенные символы в объектах ввода текстовой информации. Рассмотрим приложение, в
котором при вводе символов с клавиатуры в объекте Edit разрешается ввод только чисел и запятой. Примерный вид
окна показан на рисунке. После нажатия Ввода введенное значение передается в объект Label. Для доступа к текстовому полю объект Edit имеет свойство Text. Остальные свойства данного компонента будут рассмотрены позднее.
Обработчик события OnKeyPress компонента TEdit запишем следующим образом.
procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
const
{задаем допустимые символы из цифр,
запятой, клавиш Backspace и Enter} MyChar = ['0'..'9',',', #8, #13];
begin
//допустимый разделитель «запятая» if Key = '.' then Key:=',';
66
{если введенный символ не в допустимом наборе, то он стирается}
if not (Key in MyChar) then Key:=#0;
//если нажат Ввод, то проводим необходимые действия if Key = #13 then begin
...
Label1.Caption:=Edit1.Text;
...
end; end;
В приложении дополнительно предусмотрена замена разделителя «точка» на разделитель «запятая». Для возможности стирания введенных символов в качестве допустимого символа также добавим код клавиши Backspace (#8). К допустимым относится код клавиши Enter (#13), что позволяет обработать ее нажатие и выполнить перенос введенных текстовых данных из Edit в Label.
Процедуры и функции вызова диалоговых окон
В Windows работа приложений носит диалоговый характер. В Delphi имеются специальные компоненты вызова стандартных диалоговых окон (см. Главу 11). Часто пользователю необходимо уведомить пользователя о работе программы, запросить выбор некоторого варианта дальнейшего действия, запросить ввод некоторых параметров. Для всех этих целей используются диалоговые окна. Вызов таких окон осуществляется с помощью специальных методов, описанных в модуле Dialogs, рассмотрим их подробнее:
∙ Показывает простое диалоговое окно с кнопкой ОК, содержащее заданную
строку
procedure ShowMessage (const Text: string);
Данная процедура используется, чтобы
сообщить |
пользователю |
какую-либо |
|
информацию |
– без |
необходимости |
|
принимать |
решение. |
Для |
вывода |
многострочного сообщения, необходимо в
переменную Text вставить символы возврата каретки и переноса строки (#13#10).
∙ Показывает строку в простом диалоговом окне, размещенном в заданном
месте
procedure ShowMessagePos (const Text: string; const XPos, YPos: Integer);
Левый верхний угол диалога располагается в заданных (в пикселях) экранных координатах (XPos, YPos). В остальном он аналогичен диалогу
ShowMessage.
67
∙Отображает сообщение, значок и выбираемые кнопки
function MessageDlg (const Message: string; DialogType: TMsgDlgType; Buttons: TMsgDlgButtons; HelpContext : longint): integer;
Функция используется для отображения сообщений пользователю. Эти сообщения могут быть информационными, предупреждающими или другого типа. Можно определить перечень отображаемых на диалоге кнопок.
Вид отображения окна задается параметром DialogType.
Значение |
Описание |
mtWarning |
Окно замечаний |
mtError |
Окно ошибок |
mtInformation |
Информационное окно |
mtConfirmation |
Окно подтверждения |
mtCustom |
Заказное окно без рисунка |
Параметр Buttons определяет, какие кнопки будут присутствовать в окне.
Значение |
Надпись на кнопке |
mbYes |
Yes |
mbNo |
No |
mbOk |
Ok |
mbCancel |
Cancel |
mbHelp |
Help |
mbAbort |
Abort |
mbRetry |
Retry |
mbIgnore |
Ignore |
mbAll |
All |
mbNoToAll |
NoToAll |
mbYesToAll |
YesToAll |
Также определены константы, соответствующие часто используемым
сочетанием кнопок
Значение |
Надпись на кнопках |
mbYesNoCancel |
Входят кнопки Yes, No, Cancel |
mbOkCancel |
Входят кнопки Ok, Cancel |
mbAbortRetryIgnore |
Входят кнопки Abort, Retry, Ignore |
mbYesAllNoAllCancel |
Входят кнопки Yes, YesToAll, No, NoToAll, Cancel |
68
Функция возвращает значение, соответствующее нажатой кнопке диалога:
Значение |
Нажатая кнопка |
mrYes = 6 |
Yes |
mrNo = 7 |
No |
mrOk = 1 |
Ok |
mrCancel = 2 |
Cancel |
mrAbort = 3 |
Abort |
mrRetry = 4 |
Retry |
mrIgnore = 5 |
Ignore |
mrAll = 8 |
All |
mrNoToAll = 9 |
NoToAll |
mrYesToAll = 10 |
YesToAll |
Например, процедура
MessageDlg('Диалоговое окно MessageDlg', MtWarning, [MbYes, MbNo, MbCancel, MbAll, MbHelp],0) создаст окно вида:
∙ Предоставляет форматирование множества простых типов данных,
которые показываются один за другим в строку
procedure ShowMessageFmt (const Formatting: string; const Data: array of const);
Процедура показывает пользователю диалоговое окно, содержащее кнопку ОК. Строка Formatting может состоять из набора обычных символов и из символов форматирования данных.
Каждая подстрока форматирования данных начинается со знака «процент» (%) и заканчивается указателем на тип данных: d – десятичный (целый); e – научный; f – фиксированный; g – общий; m – денежный; n – число (с плавающей запятой); p – указатель; s – строка; u – без знаковое целое; x – шестнадцатеричное. Более подробно данное форматирование будет рассмотрено в Главе 6.
Например, следующий код
a:='Hello'; b:=256; c:=455.6565665; ShowMessageFmt('В строку можно добавить'+ #13#10 +
'строку: %s'+ #13#10+'число: %d'+ #13#10+ 'или еще число: %e', [a,b,c]);
69
покажет диалоговое окно вида
∙Отображает диалог, который просит пользователя о вводе текста
function InputQuery (const Caption, Prompt: string; var UserValue: string): boolean;
Функция отображает простое диалоговое окно с данным заголовком (Caption), подсказкой (Prompt) и полем ввода. В нём необходимо ввести данные. Если пользователь нажал OK, то введенные данные сохраняются в переменной UserValue, и возвращаемое значение будет True. В противном случае возвращаемое значение будет False.
Например, в следующем примере будет выведено окно с запросом имени, значение которого сохранится в случае нажатия Ok в переменной value.
InputQuery('Test program', 'Пожалуйста, укажите своё имя', value)
∙ Отображает диалог, который просит пользователя о вводе текста. Также определяется значение текста по умолчанию.
function InputBox (const Caption, Prompt, Default: string): string;
Функция отображает простое диалоговое окно с заданным заголовком (Caption) и подсказкой (Prompt). Оно просит, чтобы пользователь ввел данные в текстовое поле на диалоговом окне и возвращает его. Значение по умолчании (Default) отображено в текстовом поле.
Подтверждение закрытия программы
После завершения работы любого приложения возникает необходимость в выполнении определенных действий, предшествующих закрытию основной формы. К таким действиям, например, можно отнести сохранение данных открытого приложения. Рассмотрим способы корректного завершения работы приложения.
70
Закрытие приложения можно организовать, используя один из следующих способов:
∙нажатие крестика на главном окне;
∙вызов метода приложения Application.Terminate;
∙вызов метода Close для главной формы.
При закрытии приложения генерируются события OnClose и OnCloseQuery. Используя соответствующие методы данных событий, можно вывести диалоговые окна, сигнализирующие пользователю о необходимости проведения некоторых действий. Например, организуем запрос подтверждения выхода из приложения.
Создадим обработчик события OnClose для главной формы. procedure TForm1.FormClose(Sender: TObject;
var Action: TCloseAction); begin
if MessageDlg('Вы уверены что приложение нужно закрыть?', mtWarning,[mbYes, mbNo],0)=mrNo
then Action:=caNone; end;
В данном случае при нажатии «No» (Нет) на диалоговом окне в свойство Action основной формы запишем значение caNone (нет действия для объекта), вместо текущего caClose (то есть действие закрытия формы). В случае если нажата кнопка «Yes» (Да), процесс закрытия продолжится. Аналогичного результата можно добиться, обработав событие формы OnCloseQuery:
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
if MessageDlg('Вы уверены что приложение
нужно закрыть?', mtWarning,[mbYes, mbNo],0)=mrNo then CanClose:=false;
end;
Переменная CanClose при закрытии приложения принимает значение True, для того, чтобы отменить закрытие, изменим значение на False.