Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабы IT / ЛабаDelphi10.doc
Скачиваний:
54
Добавлен:
06.02.2015
Размер:
259.58 Кб
Скачать

Лабораторная работа №10. Работа в DELPHI.

Сообщения и их обработка

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

Само сообщение представляет из себя запись типа TMessage, содержащую поля. ПолеMsgнаиболее важное и содержит информацию о самом сообщении, о его виде. Оно идентифицирует сообщение.

Остальные параметры также несут информацию о данном сообщении, а поле Resultнесет информацию об обработке приложением полученного сообщения.

TMessage = packed record

Msg: Cardinal;

case Integer of

0: (

WParam: Longint;

LParam: Longint;

Result: Longint);

1: (

WParamLo: Word;

WParamHi: Word;

LParamLo: Word;

LParamHi: Word;

ResultLo: Word;

ResultHi: Word);

end;

В DelphiСтандартные оконные приложения являются потомками классаTWinControlиTControl, и когда они создаются, они регистрируются вWindowsполучая уникальный идентификатор – дескриптор (Handle).

Сначала при запуске программы на выполнение, в оперативной памяти компьютера создаётся объект ApplicationклассаTApplication(TApplication=class(TComponent)), а затем уже он своим методом Application.CreateForm(TForm1, Form1) создаёт в памяти объектForm1. Однако более точно будет сказать, что он (объектApplication) активирует метод-конструкторCreateклассаTForm, поэтому объект классаTFormв памяти создаётся своим методом-конструкторомCreate.

procedure TApplication.CreateForm(InstanceClass: TComponentClass; var Reference);

varInstance: TComponent;

begin

Instance := TComponent(InstanceClass.NewInstance);

TComponent(Reference) := Instance;

try

Instance.Create(Self);{для класса TForm вызовется родной метод-конструктор}

except

TComponent(Reference) := nil;

raise;

end;

if (FMainForm = nil) and (Instance is TForm) then

begin

TForm(Instance).HandleNeeded; {получение дескриптора Формой}

FMainForm := TForm(Instance);

end;

end;

Класс TForm1 является наследником классаTFormи перенимает все методы, свойства и поля классаTForm(это записывается инструкциейForm1=class(TForm)), а классTFormявляется наследникомTCustomFormи т.д. Каждый класс наследник дополнят своими возможностями класс потомок.

Приведем иерархию наследования классов в виде диаграммы классов:

Класс TFormтаким образом является наследником классаTWinControlиTControlив момент когда объект класса TControl или TWinControl(в данном случаеForm1)сформирован в памяти и зарегистрировался в операционной системе получив уникальный дескриптор – Handle, сразу же в операционной системе регистрируетсяспециальная для данного объекта –оконная процедура (window procedure).

Оконная процедура – это подпрограмма, которая обрабатывает сообщения для окна или другого объекта класса TWinControl или TControl.

В большинстве случаев оконная процедура содержит оператор выбора для большого колическтва сообщений, которые она должна обработать.

То есть ОС получает указатель на процедуру в памяти, которая автоматически будет вызываться, когда формой или любым другим объектом класса TWinControl или TControl будет получено сообщение. И уже эта процедура будет отвечать за обработку конкретного сообщения. Эта процедура называется MainWndProc.

Нужно отметить, что наследниками классов TWinControlи соответственноTControlявляется не только формаForm1, но и достаточно большое количество компонентовDelphiнапример классTButton, TRichEdit, TProgressBar,TRichEdit,TMemo,TListBox,TRadioButton,TCheckBoxи др.

Таким образом, для каждого компонента–объекта наследника класса TWinControlилиTControlкоторый создаётся в памяти, будет своя оконная процедураWndow Procedure.

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

Например, когда окном получено конкретное сообщение, например “закрыть” WM_CLOSE и вы желайте обработать данное сообщение, то создаёте для него специальный обработчик, в этом же приложении, затем пишите разные инструкции и т.д. которые выполнятся как только приложение получит это сообщение, но после того как вы описали реакцию вашего приложения на данное сообщение, далее желательно положиться на унаследованный стандартный метод для обработки данного конкретного сообщения и вызвать этот метод прямо из вашего написанного вами обработчика директивой inherited.

Данная директива, написанная в методе данного класса вызывает метод с тем же именем, но класса–предка (вызывает родительский метод).

Все компоненты Delphi постоянно находятся в Библиотеке Компонентов, которая включает Visual Component Library (VCL) – Визуальную Библиотеку Компонентов и Библиотеку Компонентов для разработки кросс – платформенных (CLX) приложений.

VCL регистрирует метод MainWndProc как оконную процедуру вызываемую для каждого типа компонента в приложении.

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

Таким образом, именно виртуальный метод WndProc вызываемый из MainWndProc отвечает за обработку сообщений, и программист, для каждого объекта (компонента) наследника-класса TControl может его (метод WndProc) перегрузить (то есть переопределить, изменить его) исходя из надобности.

Метод WndProc состоит в основном из условных операторов if и case анализирующих идентификатор полученного сообщения Message содержащийся в поле Msg. Прототипметода WndProc следующий:

procedure TControl.WndProc(var Message: TMessage);

Также благодаря методу WndProc можно отлавливать нежелательные сообщения

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

клавиатуры, и таким образом метод WndProc класса TWinControl будет пропускать события клавиатуры, только если компонент не перетаскивают.

Фактически метод WndProc получает и обрабатывает поступившие сообщения, шныряющие по Windows.

В конце концов, WndProc вызывает невиртуальный метод Dispatch

procedure TObject.Dispatch(var Message) унаследованный от прародителя всех классов класса TObject, определяет какой метод вызывать, чтобы обработать конкретное полученное сообщение.

Метод Dispatch использует поле Msg структуры сообщения, чтобы определить, как послано специфическое сообщение.

Если в компоненте определен обработчик для специфического сообщения, то метод Dispatch вызывает данный метод обработки этого сообщения иначе метод Dispatch вызывает обработчик по умолчанию DefaultHandler.

Таким образом, в общем случае обработка сообщений идет по следующей схеме:

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

Если данное сообщение вообще не предусмотрено в обработчике компонента, нужно перегрузить (переопределить) метод WndProc и там описать реакцию объекта на это сообщение.

Соседние файлы в папке Лабы IT