Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ПЯВУ.docx
Скачиваний:
2
Добавлен:
23.04.2019
Размер:
210.36 Кб
Скачать

35.События клавиатуры. Фокус ввода.

События клавиатурыСобытия мыши возникают в любом потомке класса TControl. В отличие от этого события клавиатуры возникают только в некоторых оконных компонентах (в потомках класса TWinControl). Обработка событий связана со следующими свойствами этих компонентов:

TShiftState = set of (ssShift, ssAlt, ssCtrl, ssLeft, ssRight, ssMiddle, ssDouble);

TKeyEvent = procedure (Sender: TObject; var Key: Word; Shift: TShiftState) of object;

property OnKeyDown: TKeyEvent read FOnKeyDown write FOnKeyDown;

property OnKeyPress: TKeyPressEvent read FOnKeyPress write FOnKeyPress;

property OnKeyUp: TKeyEvent read FOnKeyUp write FOnKeyUp;

Параметр как и в обработчиках событий от мыши, содержит уточняющие признаки. Параметр Key в обработчиках TKeyEvent содержит виртуальный код клавиши, а в обработчике TKeyPressEvent — ASII-символ. Обработчики OnKeyDown и OnKeyUp перехватывают нажатие большинства клавиш клавиатуры, в то время как OnKeyPress — только нажатие алфавитно-цифровых клавиш. Получаемый ими символ Key учитывает выбранный язык и нажатую клавишу Shift.

Виртуальные коды клавиш определены константами vk_XXX в файле Source\Rtl\Win\Windows.pas, которые представляют уникальные числовые идентификаторы клавиш. Для буквенно-цифровых символов, с некоторыми исключениями, этот код совпадает со значением, возвращаемым функцией ord(‘x’.

Поскольку параметр Key в каждом обработчике определен как параметр-переменная программист может изменить фактический ввод клавиши, например для фильтрации каких-либо клавиш. При этом подмена должна осуществляться в обработчике формы, чтобы в оконный элемент поступал уже измененный код. Чтобы форма получила сообщение от клавиатуры до передачи его в элемент с фокусом ввода, следует установить свойство формы KeyPreview в true

Например, закрытие формы по нажатию клавиш Alt+X:

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

begin

if (key = ord (‘X’)) and (ssAlt in Shift) then Close

end;

Фокус вводаПоскольку клавиатура одна, а элементов, использующих ее — много, необходимо выделять элемент, которому передается клавиатурный ввод. Это достигается передачей элементу фокуса ввода через его метод:

procedure SetFocus;

Компонент с фокусом ввода имеет значение true в своем свойстве:

property Focused: Boolean;

Если элемент недоступен или невидим, его свойство CanFocus имеет значение false:

procedure CanFocus: Boolean;

Фокус ввода передается элементу после щелчка на нем мышью или в порядке выбора его клавишей Tab. Чтобы элемент можно было выбирать с помощью это клавиши, следует установить следующее его свойство в True:

property TabStop: Boolean;

Порядок выбора элемента определяется свойством:

Property TabOrder: Integer;

Delphi следит за уникальностью и непрерывностью всех помещенных на форму доступных и видимых компонентов. С помощью следующего метода можно получить список всех дочерних компонентов, выбираемых клавишей Tab.

procedure GetTabOrderList (List: TList);

36. Механизм перетаскивания Drag&Drop, механизм причаливания Drag&Dock.

Операционная система Windows широко использует прием Drag&Drop — перетащи и отпусти. Этот механизм позволяет, нажав и удерживая левую клавишу мыши на определенном месте экрана «зафиксировать» некоторую информацию («груз»), и потом, не отпуская клавишу мыши перетащить этот «груз» в другое место экрана. Отпускание клавиши мыши обозначает место- приемник «груза».

В Delphi реализован свой механизм Drag&Drop, позволяющий компонентам обмениваться информацией при помощи мыши. Этот механизм определяется двумя свойствами и тремя событиями, определенными для каждого видимого компонента.

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

TDragMode = (dmManual, dmAutomatic);

property DragMode: TDragMode;

dmManual - вручную (все необходимые события генерируются программой);и dmAutomatic – автоматически (события инициируются методами компонентов).

Свойство DragCursor определяет вид указателя мыши в момент, когда на компоненте оказываются перетаскиваемые данные. Если компонент готов принять данные, он устанавливает в это свойство значение crDrag, в противном случае — crNoDrag. Установка этих свойств осуществляется автоматически, если

DragMode=dmAutomatic.

property DragCursor: TCursor;

В механизме Drag&Drop участвуют три события, два из них вызываются для компонента над которым происходят движения груза, это события OnDragOver и OnDragDrop. Событие OnEndDrag вызывается для того компонента от которого началось перетаскивание груза.

Событие OnDragOver возникает, когда указатель мыши «с грузом» оказывается на компоненте:

TDragState = (dsDragEnter, dsDragLeave, dsDragMove);

TDragOverEvent = procedure (Sender, Source: TObject; X, Y : Integer; State: TDragState; var Accept : Boolean) of object;

property OnDragOver: TDragOverEvent;

Параметры:

Sender — компонент, который генерирует событие (обычно имеет значение Self, т.е. сам компонент-получатель, но при программном управлении механизмом это может быть. и не так);

Source — компонент-отправитель;

X, Y — текущие координаты указателя мыши;

State: dsDragEnter — въехал на компонент; dsDragLeave — покинул компонент; dsDragMove — перемещается на компоненте.

Accept - в этом параметре-переменной обработчик должен сообщить, готов ли компонент принять данные(.true — готов).

Событие OnDragDrop вызывается, если пользователь «бросил» данные на компонент. Параметры события аналогичны событию OnDragOver:

TDragDropEvent = procedure (Sender, Source: TObject; X, Y : Integer) of object;

property OnDragDrop: TDragDropEvent;

Наконец, при завершении перетаскивания возникает событие OnEndDrag:

TEndDragEvent = procedure (Sender, Target: TObject; X, Y : Integer) of object;

Property OnEndDrag: TEndDragEvent;

где Sender — отправитель, Target — указатель на объект-получатель или Nill, если перенос закончился неудачно; X, Y — координаты курсора в момент отпускания клавиши мыши.

Механизм причаливанияВ Delphi введена поддержка спец.механизма Drack&Dock(перетащи и причаль),посредством которого можно причалить мышкой компонент в новое место. В механизме Drack&Dock участвуют два компонента:принимающий компонент(всегда потоком TWnControl) и причаливаемый компонент(потомок класса TControl). Принимающий (оконный) компонент имеет св-во DockSite, установленное в True, оно делает компонент контейнером-приемником в рассматриваемом механизме.

Поскольку причаливание является частью более общего механизма перетаскивания, в класс TControl введено дополнительное св-во,благодаря которому различаются способы использования мыши. В компонентах, которые могут выступать клиентами в механизме Drack&Dock,надо установить св-во Drack&Kind в dkDock.

TDragKind – (dkDrag, dkDock);

Property DragKind: TDragKind read FDragKind writeFDragKind default DkDrag;

Количество установленных на форме причаливаемых компонентов(у которых DragKind= dkDock. И DockSite=false) определяется св-ом DockClientCount,а их список хранится в св-ве массиве DockClientS.

Для реализации причаливания в класс TControl ввдены следующие св-ва.

Св-во AutoSize разрешается (true) или запрещается оконному компоненту менять свои размеры в зависимости от количесвта и размеров содержащихся в нем дочерних компонентов.

Property AutoSize:Boolean read FAutoSize write SetAutoSize default false;

Неоконные компоненты могут не только причаливаться к оконным элементам, но и покидать их. После «отчаливания» неоконные элементы автоматически оказываются в окне, тип которого содержит св-во FloatingDockSiteClass. По умолчанию это окно содержит уменьшенный по высоте заголовок и системную кнопку закрытия.

Property FloatingDockSiteSizeClass:TWinControlClass read GetFloatingDockSiteClass write FFloatingDockSiteClass;

В св-ве DockOrientation можно установить (получить)ориентацию),которую будет иметь «причаливаемый» компонент в окне родителя

TDockOrientation=(doNoOrient, doHorizontal,doVertical);

Property DockOrientation:TDockOrientation read FDockOrientation writeFDockOrientation;

doNoOtient-сохр исходная ориентация перемещаемого компонента

doHoizontal-компонент будет иметь горизонтальную ориентацию

doVertical-компонет будеть иметь вертикальную ориентацию.

С помощью св-в LRDockWidth и TBDockHeight можно соответственно получить ширину последнего перемещения компонента,расположившегося горизонтально, или высоту последнего перемещения компонента, расположившегося вертикально.

Property LRDockWidth: Integer read GetLRDockWidth write FLRDockWidth;

Property TBDockHeight: integer read GetTBDockHeigh wtite FTBDockHeigh;

Св-ва UndockHeigt и UndockWidth определяют высоту и ширину последнего «отчалившего» компонента.

Property UndockHeigе: Integer read GetUndockHeigе write FUndockHeigе;

Property UndockWidth: integer read Get UndockWidth wtite FUndockWidth;

Св-ва Contraints с помощью TSizeConstraints накладывают ограничения на возможные размеры причаливаемого компонента.

Property Contraints: TSizeConstraints read FContraints write Set Contraints;

Механизм Drack&Dock обслуживается следующими событиями. Для принимающего компонента:

1событие OnGetSiteInfo возникает в момент начала перетаскивания и повторяется непрерывно в процессе перетаскивания. Обработчик этого события должен сообщить объекту TDragDockObject, который автом связывается с причаливаемым объекотм,некоторую дополнительную информ(размеры,которые будет иметь этот объект,будет ли он погружен в плавающее окно и.т.п)

2событие OnDockOver возникает и повторяется ,когда компонент-клиент пермещается над компонентом-приемником. Возвращает параметр Accept установленный в False, определяет, что данный оконный компонент не принимает перетаскиваемый компонент.

3событие OnDockDrop аналогично OnDragDrop,возникает в момент окончания перетаскивания клиента над приемником. Этот обработчик разместить клиент Sourse тем или иным образом, в зависимости от его имени, типа, местоположения.

4событие OnUnDock возникает при отчаливание компонент. Обработчик этого события должен поместить в св-во Allow значение true, если компонент может покинуть границы своего владельца Sender.

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

37. Реализация механизма исключений в Delphi. Иерархия классов-исключений. Понятие механизма исключений.При работе программы могут возникать различного рода ошибки: переполнение, деление на нуль, попытка открыть несуществующий файл и т.д. Традиционно обработка ошибок осуществлялась следующим образом: в одной области кода устанавливались флаги, а во второй области выполнялась соответствующая проверка и ответные действия. Например, при попытке открытия несуществующего файла устанавливался определенный флаг, а другой участок кода проверял этот флаг и реагировал на ошибку.

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

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

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

1. Исключения позволяют отделить код обработки ошибок от основного кода, избегая его засорения многочисленными проверками, не имеющими прямого отношения к главной цели.

2. Исключения создают единый универсальный механизм сообщений об ошибках, который используется как библиотеками Delphi, так и самой средой Delphi.

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

1. Ключевое слово try указывает начало защищенного блока кода.

2. Ключевое слово ехсерt указывает на конец защищенного блока кода и предшествует операторам обработки исключительных ситуаций, имеющим следующий синтаксис:

on <тип исключительной ситуации>do <оператор>

3. Ключевое слово finally используется для указания начала блока кода, который должен исполняться всегда, даже если возникнет исключительная ситуация.

4. Оператор raise используется для генерации исключительной ситуации. Большинство исключительных ситуаций, которые встречаются при программировании на Delphi, генерируются системой. Однако можно самостоятельно создавать исключительные ситуации, например, при обнаружении некорректных или противоречивых данных, чтобы автоматически вызвалась процедура обработки такой ошибки.

При возникновении исключительной ситуации Delphi создает объект одного из классов исключений, определенных в системе. Все эти классы имеют общего предка класс Ехсерtion.

Иерархия классов-исключений представлена:

Ехсерtion(базовый класс всех исключений);

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

EAbstractError(попытка вызвать абстрактный метод);

EAccessViolation(ошибочный доступ к памяти);

EArrayError(использование ошибочного индекса элемента массива,добавление слишком болльшого числа элементов в массив фиксированной длины,попытка вставки элемента в отсортированный массив);

EDatabaseError(ошибка работы с базой данных);

EPrinter(ошибка печати,например приложение пытается использовать принтер,которого нет или задание по какой-то причине не м.б послано на принтер);

ERеgistryException(ошибка при обращение к реестру);

EFOpenError(ошибка отркытия файла);

EWriteError(невозможно записать заданное число байтов);

EWin32Error(ошибка windows).

38. Описание обработчика исключений в блоке (tгу..ехсерt)Последовательность обработки исключений. Основным способом реализации исключений является их обработка с помощью блоков trу..ехсерt. Синтаксис этих блоков следующий:

Try

{исполняемы код}

ехсерt

{код исполняемый в случае генерации исключения}

End;

В случае возникновения исключения в блоке обработки можно предпринять определенные действия известить пользователя о возникшей проблеме, подсказать ему пути ее решения, принять какие-то меры к исправлению ошибки и т.д. В разделе ехсерt можно определить тип сгенерированного исключения и дифференцированно реагировать на различные исключительные ситуации. Это делается с помощью оператора:

on <класс исключения> do <оператор>

Рассмотрим пример. Пусть в программе содержится следующий код:

С:=StrToInt (Еdit1.Техt);

А:= В div С;

Его детальное рассмотрение показывает, что этот код является потенциально опасным по следующим причинам:

• введенная пользователем строка в поле Edit1 может оказаться не числом;

• Введенная пользователем строка в поле Еdit1 может оказаться нулем;

• при выполнении деления потенциально может возникнуть ошибка переполнения.

Поэтому данный код необходимо заключить в блок обработки исключений.

Пример:

Try

С:=StrToInt (Еdit1.Техt);

А:= В/С;

ехсерt

on ЕСonvertError do

MessageDlg(‘Вы ввели ошибочное число; повторите ввод’, mtWarning, [mbOk],0);

On EDivByZero do

MessageDlg(‘Вы ввели ноль; повторите ввод’, mtWarning, [mbOk],0);

On EIntOverFlow do

If (В*С) >=0 then A:=32767 else A:=-32766;

End;

В рассматриваемом примере некоторые исключения имеют дополнительные поля (свойства), уточняющие вид ошибки. Например, это относится к исключению файлового ввода-вывода ЕInОutError, которое имеет свойство ErrorCode типа integer. Это свойство содержит стандартный для ОР номер ошибки файлового ввода/вывода. Для использования полей исключения, оператор оn записывается в виде:

оn <имя>: <класс исключения> do

<операторы с конструкциями <имя>.<имя поля>>;

Содержащееся в операторе оn имя имеет локальную область видимости, нигде не определяется и используется для ссылки на поле по имени объекта исключения.

Можно перехватывать не только отдельные исключения, но и группы родственных исключений, обрабатывая определенный уровень иерархии. Например, чтобы перехватить исключения всех классов, порожденных от Error:

on EIntError do

MessageDlg(‘Ошибка целочисленной операции’, mtWarning, [mbOk],0)

В раздел ехсерt могут включаться или только оператор оп или только какие-то другие операторы. Помимо оператора оn, обрабатывающего заданные классы исключений, в раздел ехсерt может быть включен оператор еlsе, в котором выполняется обработка всех, не перехваченных ранее исключений, т.е. происходит обработка по умолчанию:

except

on…

on…

else <обработчик всех не перехваченных ранее событий>;

Оператор else должен идти последним, иначе все обработчики будут перехвачены уже в этом операторе. Внутри обработчика по умолчанию можно получить доступ к объекту исключения с помощью функции ЕхсерtObject. Использовать обработку исключений по умолчанию следует осторожно, поскольку перехват всех исключений способен замаскировать какие-то непредвиденные ошибки в программе, что затруднит их поиск в снизит надежность работы.