Чтение онлайн

на главную

Жанры

О чём не пишут в книгах по Delphi

Григорьев Антон Борисович

Шрифт:

procedure <Name>(var Message: <TMsgType>); message <MsgNumber>;

<MsgNumber>
— это номер сообщения, для обработки которого предназначен метод. Имя метода может быть любым, но традиционно оно совпадает с именем константы сообщения за исключением того, что в нем выбран более удобный регистр символов и отсутствует символ "_" (например, метод для обработки
WM_SIZE
будет называться
WMSize
).

В качестве типа параметра

<TMsgType>
компилятор разрешает любой тип, но на практике имеет смысл только использование типа
TMessage
или "совместимого" с ним. Тип
TMessage
описан в листинге 1.14.

Листинг 1.14.
Описание типа
TMessage

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;

Поле Msg содержит номер сообщения, поля

WParam
и
LParam
— значение одноименных параметров сообщения. Поле
Result
— выходное: метод, осуществляющий окончательную обработку сообщения, заносит в него то значение, которое должна вернуть оконная процедура. Поля с суффиксами
Lo
и
Hi
позволяют обращаться отдельно к младшему и старшему словам соответствующих полей, что может быть очень полезно, когда эти параметры содержат пару 16-разрядных значений. Например, у сообщения
WM_MOUSEREMOVE
младшее слово параметра
LParam
содержит X-координату мыши, старшее — Y-координату. В случае обработки этого сообщения поле
LParamLo
будет содержать X-координату,
LParamHi
— Y-координату.

"Совместимыми" с

TMessage
можно назвать структуры, которые имеют такой же размер, а также параметр
Msg
, задающий сообщение. Эти структуры учитывают специфику конкретного сообщения. Их имена образуются из имени сообщения путем отбрасывания символа и добавления префикса
T
. Для уже упоминавшегося сообщения
WM_MOUSEMOVE
соответствующий тип выглядит, как показано в листинге 1.15.

Листинг 1.15. Тип
TWMNCMouseMove

TWMNCMouseMove = packed record

 Msg: Cardinal;

 HitTest: LongInt;

 XCursor: SmallInt;

 YCursor: SmallInt;

 Result: LongInt;

end;

Параметр

WParam
переименован в
HitTest
, что лучше отражает его смысл в данном случае, а параметр
LParam
разбит на две 16-разрядных части:
XCursor
и
YCursor
.

Параметр метода для обработки сообщения имеет тип, соответствующий обрабатываемому сообщению (при необходимости можно описать свой тип), или тип

TMessage
. Таким образом, обработчик сообщения
WM_MOUSEMOVE
будет выглядеть так, как показано в листинге 1.16.

Листинг 1.16. Объявление и реализация метода для обработки сообщения
WM_MOUSEMOVE

type

 TSomeForm = class(TForm)

 ...............

 procedure WMNCMouseMove(var Message: TWMNCMouseMove); message WM_NCMOUSEMOVE;

 ................

end;

procedure TSomeForm.WMNCMouseMove(var Message: TWMNCMouseMove);

begin

 ...............

 inherited; //
Возможно, этот вызов не будет нужен

end;

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

inherited
позволяет вызвать унаследованный обработчик для данного сообщения. Таким образом, может образовываться целая цепочка вызовов унаследованных обработчиков одного и того же сообщения, каждый из которых выполняет свою часть обработки. Если у предков класса нет обработчика данного сообщения, директива
inherited
передает управление методу
TObject.DetaultHandler
. Вернемся к методу
Dispatch
. Он ищет среди обработчиков сообщения класса (собственных или унаследованных) метод для обработки сообщения, заданного полем
Msg
параметра
Message
и, если находит, передает управление ему. Если ни сам класс, ни его предки не содержат обработчика данного сообщения, то обработка передаётся методу
DefaultHandler
.

Метод

DefaultHandler
виртуальный, в классе
TObject
он не выполняет никаких действий, но наследники его переопределяют. Впервые он переопределяется в классе
TControl
для обработки сообщений, связанных с получением и установкой заголовка окна —
WM_GETTEXT
,
WM_GETTEXTLENGTH
и
WM_SETTEXT
. Напомним, что класс TControl является предком для всех визуальных компонентов, а не только оконных, и появление обработчика системных сообщений в этом классе — часть той имитации обработки сообщений неоконными компонентами, о которой мы уже говорили.

В классе

TWinControl
метод
DefaultHandler
также переопределен. Помимо передачи некоторых сообщений дочерним окнам (об этом мы будем подробнее говорить чуть позже) и обработки некоторых внутренних сообщений он вызывает оконную процедуру, адрес которой хранится в свойстве
DefWndProc
. Это свойство содержит адрес, который был присвоен полю
WindowClass.lpfnWndProc
структуры
TCreateParams
в методе
CreateParams
. По умолчанию это поле содержит адрес стандартной оконной процедуры
DefWindowProc
. Как было сказано ранее, обработка сообщений при использовании API обычно завершается вызовом этой процедуры. В классе
TCustomForm
метод
DefaultHandler
также переопределен, если форма является MDI-формой, сообщения, присланные ей, передаются в процедуру
DefFrameProc
(за исключением
WM_SIZE
, которое передается в
DefWindowProc
) независимо от того, какое значение имеет свойство
DefWindowProc
. Для всех остальных типов форм вызывается унаследованный от
TWinControl DefaultHandler
.

Повторим еще раз всю цепочку обработки сообщений оконными компонентами VCL (рис. 1.7). Для каждого компонента создается уникальная оконная процедура, которая передает управление методу

MainWndProc
.
MainWndProc
передает управление методу, указатель на который хранится в свойстве
WindowProc
. По умолчанию это метод компонента
WndProc
. Он осуществляет обработку некоторых сообщений, но в большинстве случаев передает управление методу
Dispatch
, который ищет среди методов компонента или его предков обработчик данного сообщения. Если обработчик не найден, управление получает метод
DefaultHandler
(он может также получить управление и в том случае, если обработчик найден, но он вызывает
inherited
).
DefaultHandler
самостоятельно обрабатывает некоторые сообщения, но большинство из них передаётся оконной процедуре, адрес хранится в свойстве
DefWndProc
(по умолчанию это стандартная функция Windows API
DefWindowProc
).

Поделиться:
Популярные книги

На границе тучи ходят хмуро...

Кулаков Алексей Иванович
1. Александр Агренев
Фантастика:
альтернативная история
9.28
рейтинг книги
На границе тучи ходят хмуро...

Кодекс Охотника. Книга III

Винокуров Юрий
3. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
7.00
рейтинг книги
Кодекс Охотника. Книга III

Последний попаданец 11. Финал. Часть 1

Зубов Константин
11. Последний попаданец
Фантастика:
фэнтези
юмористическое фэнтези
рпг
5.00
рейтинг книги
Последний попаданец 11. Финал. Часть 1

Книга пяти колец

Зайцев Константин
1. Книга пяти колец
Фантастика:
фэнтези
6.00
рейтинг книги
Книга пяти колец

Поступь Империи

Ланцов Михаил Алексеевич
7. Сын Петра
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Поступь Империи

Купидон с топором

Юнина Наталья
Любовные романы:
современные любовные романы
7.67
рейтинг книги
Купидон с топором

Наследник в Зеркальной Маске

Тарс Элиан
8. Десять Принцев Российской Империи
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Наследник в Зеркальной Маске

Совок 5

Агарев Вадим
5. Совок
Фантастика:
детективная фантастика
попаданцы
альтернативная история
6.20
рейтинг книги
Совок 5

Аномальный наследник. Том 1 и Том 2

Тарс Элиан
1. Аномальный наследник
Фантастика:
боевая фантастика
альтернативная история
8.50
рейтинг книги
Аномальный наследник. Том 1 и Том 2

Теневой путь. Шаг в тень

Мазуров Дмитрий
1. Теневой путь
Фантастика:
фэнтези
6.71
рейтинг книги
Теневой путь. Шаг в тень

Попаданка в академии драконов 2

Свадьбина Любовь
2. Попаданка в академии драконов
Любовные романы:
любовно-фантастические романы
6.95
рейтинг книги
Попаданка в академии драконов 2

Гром над Империей. Часть 2

Машуков Тимур
6. Гром над миром
Фантастика:
фэнтези
попаданцы
5.25
рейтинг книги
Гром над Империей. Часть 2

Ритуал для призыва профессора

Лунёва Мария
Любовные романы:
любовно-фантастические романы
7.00
рейтинг книги
Ритуал для призыва профессора

Измена. Осколки чувств

Верди Алиса
2. Измены
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Измена. Осколки чувств