Delphi — это совершенно новый инструмент разработки программирования для WINDOWS, предоставляемый Borland. Поскольку он использует гибкий и многократно используемый объектно-ориентированный язык Pascal (объектно-ориентированный паскаль) и имеет мощный механизм базы данных (BDE), быстрый код. Компилятор также предоставляет множество превосходных средств. Компоненты. Его предпочитает большинство программистов. Он выделяется среди многих языков программирования (таких как VB, PowerBuilder, Powerpoint и т. д.).
Одним из преимуществ DELPHI перед другими языками программирования (такими как VB4.0) является то, что сообщения можно настраивать в DELPHI и обрабатывать напрямую. Это для тех, кто хочет писать свои собственные компоненты (Компоненты). или тех, кто хочет перехватывать и фильтровать сообщения. Это важно для пользователей, поскольку написание компонентов обычно требует обработки соответствующих сообщений. Ниже приводится введение в механизм обработки сообщений в Delphi.
1. Доставка сообщений в DELPHI VCL.
Каждый компонент VCL (библиотека визуальных компонентов) (например, Tbutton, Tedit и т. д.) в Delphi имеет встроенный механизм обработки сообщений. Суть в том, что класс компонента получает определенные сообщения и отправляет их соответствующему методу обработки, если таковой имеется. нет конкретного метода обработки, вызывается дескриптор обработки сообщения по умолчанию. Среди них mainwndPROc — статический метод, определенный в классе Twincontrol, и его нельзя перегрузить (переопределить). Он не обрабатывает сообщение напрямую, а оставляет его для обработки методу wndproc и предоставляет модуль обработки исключений для метода wndproc. Метод Mainwndproc объявляется следующим образом:
процедура MainWndProc (вар Сообщение: TMessage);
Wndproc — это виртуальный метод, определенный в классе Tcontrol, который вызывает метод диспетчеризации для распространения сообщений. Метод wndproc объявляется следующим образом:
процедура WndProc (вар Сообщение: TMessage virtual);
Метод отправки определен в корневом классе Tobject и объявлен следующим образом:
процедура Tobject.dispatch(var Message); Параметр сообщения, передаваемый в диспетчеризацию, должен быть типом записи, а первая точка входа в этой записи должна быть полем (полем) кардинального типа, которое содержит сообщение сообщения, подлежащего распространению. Число . Например:
тип
Tmessage=запись
Сообщение: кардинал;
впарам: Слово;
лпарам: лонгинт;
результат: лонгинт;
конец;
Метод Dispatch вызовет метод handle класса последнего поколения компонента, который обрабатывает это сообщение, на основе номера сообщения. Если в этом компоненте и его родительском классе нет обработчика, соответствующего этому сообщению, метод Dispatch вызовет Defaulthandler. Метод Defaulthandler. Виртуальный метод, определенный в Tobject, объявляется следующим образом:
процедура Defaulthandler(var Message);виртуальный;
Метод Defaulthandler в классе Tobject реализует только простой возврат без какой-либо обработки сообщения. Мы можем реализовать обработку сообщения по умолчанию в подклассе, перегрузив этот виртуальный метод. Для компонентов в VCL его метод Defaulthandler запустит окна. Функция API Defwindowproc для обработки сообщения.
2. Дескриптор обработки сообщений в DELPHI
В DELPHI пользователи могут настраивать сообщения и дескрипторы обработки сообщений. Определение дескрипторов обработки сообщений основано на следующих принципах:
Метод дескриптора обработки сообщения должен быть процедурой и может передавать только один параметр переменной типа Tmessage.
За объявлением метода должна следовать команда сообщения, за которой следует метка сообщения (целочисленная константа) от 0 до 32767.
Методу обработчика сообщений не требуется использовать команду переопределения, чтобы явно указать переопределение обработчика сообщения предка. Кроме того, он обычно объявляется в защищенной или частной области компонента.
В дескрипторе обработки сообщения пользователь обычно сначала обрабатывает сообщение и, наконец, использует унаследованную команду для вызова дескриптора обработки, соответствующего этому сообщению в классе-предке (в некоторых случаях это может быть наоборот, поскольку дескриптор обработки). это сообщение в классе-предке может быть Имя и тип параметра неясны, и вызов команды inherited может избежать этой проблемы. Аналогично, если в классе-предке нет обработчика, соответствующего этому сообщению, inherited автоматически вызовет метод Defaulthandler. (Конечно, если вы хотите заблокировать это сообщение, Нет необходимости использовать унаследованную команду).
Метод обработчика сообщений объявлен как:
процедура Mymsgmethod (вар сообщение: Tmessage сообщение Msgtype);
Аналогично, пользователи также могут определять свои собственные сообщения. Пользовательские сообщения должны начинаться с WM_USER.
Ниже приведены примеры пользовательских сообщений и дескрипторов обработки сообщений:
const my_paint=Wm_user+1;
тип
Tmypaint=запись
msgid:кардинал;
мразмер: слово;
mcolor: лонгинт;
msgresult: Лонгинт;
конец;
тип
Tmycontrol=класс(TCustomControl)
защищенный
изменение процедуры (вар сообщение: Tmypaint); сообщение my_paint;
.....
конец;
...
процедура Tmycontrol.change(var message:Tmypaint);
начинать
size:=message.msize {Установить атрибут размера Tmybutton}
color:=message.mcolor; {Установить атрибут цвета Tmybutton}
{сделай что-нибудь ещё}
унаследовано {Передано Tcustomcontrol}
конец;
3. Фильтровать сообщения
Фильтрация сообщений также называется ловушкой сообщений. При определенных обстоятельствах пользователям может потребоваться заблокировать определенные сообщения или перехватить определенные сообщения для обработки. Из приведенного выше введения мы видим, что обычно существует три способа фильтрации сообщений: (1) Перегрузить виртуальный метод wndproc, унаследованный компонентом (2). Перегрузить виртуальный метод Defhandler, унаследованный компонентом, в котором обрабатываются сообщения. Наиболее часто используемым методом является метод (2), который был представлен в предыдущем разделе. Метод (1) аналогичен методу (3). Здесь мы лишь кратко представим метод (1).
Общий процесс перегрузки виртуального метода wndproc выглядит следующим образом:
процедура Tmyobject.wndproc(var message:Tmessage);
начинать
{... Определите, следует ли обрабатывать это сообщение..}
унаследовал wndproc(сообщение);
{Необработанные сообщения обрабатываются родительским методом wndproc}
конец;
Из этого видно, что преимущество обработки сообщений в методе wndproc заключается в том, что он может фильтровать весь диапазон сообщений без необходимости указывать дескриптор обработки для каждого сообщения. Фактически он используется в компоненте Tcontrol для фильтрации и. обрабатывать все сообщения мыши (от WM_mousefirst до WM_mouselast, как показано в следующем коде). Его также можно использовать для предотвращения отправки определенных сообщений обработчику.
процедура TControl.WndProc(var Сообщение: TMessage);
начинать
если (Message.Msg>=WM_MOUSEFIRST) и
(Сообщение.Msg <= WM_MOUSELAST)
затем
если перетаскивание, то {Обработать событие перетаскивания}
DragMouseMsg(TWMMouse(Сообщение))
еще
... {обработка других сообщений мыши}
конец;
Отправка (Сообщение);
{Иначе отправьте сообщение как обычно}
конец;
Следующий пример представляет собой простой пример пользовательского компонента:
Класс Tmyedit — это новый класс, производный от класса Tedit. Его особенностью является то, что он не может получить фокус во время работы и не может вводиться с клавиатуры (что-то похожее на компонент Tlabel). В нем можно фильтровать сообщения WM_setfocus и WM_mousemove. wndproc и выполните его. Для достижения вышеуказанных требований исходная программа выглядит следующим образом:
модуль myedit;
интерфейс
использует
Windows, сообщения, SysUtils, классы, графика,
Элементы управления, формы, диалоги,
Стдктрлс;
тип
Tmyedit = класс(TEdit)
частный
{Частные заявления}
защищенный
{ Защищенные объявления }
{другие поля и методы}
процедура wndproc (вар сообщение: Tmessage); переопределить;
общественный
{Публичные заявления}
опубликовано
{ Опубликованные декларации }
конец;
процедура Регистр;
выполнение
процедура Регистр;
начинать
RegisterComponents('Samples', [Tmyedit]);
конец;
процедура Tmyedit.wndproc(var message:tmessage);
начинать
если message.msg=wm_mousemove тогда
начинать
курсор: = ворона;
{Установите курсор на crarrow вместо курсора crBeam по умолчанию}
Выход;
конец;
если message.msg=wm_SetFocus, то выходим;
{Защищайте сообщение WM_setfocus и не позволяйте элементу управления Tmyedit получить фокус ввода}
унаследовал wndproc(сообщение);
{Остальные сообщения передаются родительскому wndproc для обработки}
конец;
конец.
Вы можете добавить Tmyedit в палитру компонентов, чтобы проверить его производительность.
Как видно из приведенного выше введения, только поняв механизм обработки сообщений в Delphi VCL, освоив методы и сроки обработки различных сообщений (с использованием при необходимости различных инструментов, таких как winsight32, spy и т. д.), и совместив характеристики языка ООП, мы можем скомпилировать высококачественные компоненты. Это, конечно, требует от читателей постоянного изучения и накопления опыта на практике.