Написание своих компонентов для Delphi. Часть 4. Простейший визуальный компонент

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

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

Немного теории

Как это ни странно прозвучит, но основное и, пожалуй, единственное отличие визуальных компонентов от не визуальных состоит в том, что:

  • Их можно увидеть на экране компьютера в окне приложения;
  • Визуальные компоненты могут взаимодействовать с устройствами ввода.

Однако, если первое отличие является очевидным и свойственно для всех визуальных компонентов, то со вторым всё значительно сложнее.

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

В качестве базовых классов при создании визуального компонента с нуля чаще всего используются:

  • TWinControl – базовый класс для всех «оконных» элементов управления (кнопки, календари, тестовые поля и т.д.). Обеспечивает наиболее широкий функционал, включая поддержку ввода с клавиатуры, размещение внутри себя других компонентов и т.д.;
  • TGraphicControl – этот класс служит основой для «графических» компонентов. Такие компоненты способны только отображать информацию на экране или обрабатывать простейшие события, связанные с мышью, изменением размера и т.п.

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

Использовать TControl в прикладной разработке не рекомендуется так как алгоритмы работы, связанные с реализацией собственных «оконных» или «графических» компонентов, приходится переопределять крайне редко (обычно при написании собственных библиотек, и то в исключительных случаях). Обычно возможности стандартных TWinControl и TGraphicControl вполне достаточны для решения самых различных задач.

Класс TControl является наследником класса TComponent. Следовательно, всё, что было рассмотрено во второй и третьей частях относительно не визуальных компонентов также справедливо и для визуальных. Потому мы не станем рассматривать вопросы создания компонентов как таковых и обработки событий, а сразу перейдём к визуализации и взаимодействию с устройствами ввода.

Важно отметить, что возможности базовых классов для визуальных компонентов в целом весьма широки. Поэтому в статьях, посвящённых их написанию возможно привести лишь основные принципы разработки на простых примерах.

Для более глубокого изучения рекомендуется документация Embarcadero и подробные руководства по программированию на Delphi рассчитанные на профессиональную разработку (в частности книги Д.Осипова).

Простейший визуальный компонент

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

Цвет «индикатора» определяется при помощи свойства Color, которое имеет тип данных TColor. Пусть по умолчанию цвет «индикатора» будет зелёный.

Так как функционал компонента минимален, реализуем его на основе класса TGraphicControl. В работе мы будем использовать следующие члены этого класса:

  • Canvas (тип TCanvas) – свойство ответственное за канву для рисования;
  • Paint – метод который выполняет непосредственно отображение компонента на экране (отрисовку);
  • Refresh – метод который выполняет обновление компонента, включая его повторную отрисовку (в ходе выполнения вызывается метод Paint);

Зададим в конструкторе начальные значения ширины, высоты и цвета.

Далее создадим метод, который будет осуществлять отрисовку.

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

Поэтому нам придётся полностью реализовать отображение «индикатора» на экране. В данном случае нам потребуется при помощи свойства Canvas, нарисовать прямоугольник и заполнить его цветом.

У компонентов на основе TGraphicControl отрисовка производится при вызове метода Paint. Поэтому вызов только что созданного метода отрисовки в метод Paint.

Обратите внимание, что в метод отрисовки передаётся значение цвета из поля fColor, которое хранит значение свойства Color. Таким образом, для того чтобы перекрасить «индикатор» в новый цвет достаточно просто перерисовать компонент при помощи метода Refresh.

Для того чтобы это осуществить значение свойства Color устанавливается посредством метода SetColor:

В этом методе вначале присваивается новое значение цвета компонента, а затем вызывается его обновление.

В завершение добавим поддержку события OnClick.

Как уже говорилось выше, непосредственно поддержка событий мыши реализована в классе TControl, но свойства ответственные за эти события в нём объявлены как защищённые (protected). Это избавляет классы наследники от поддержки «лишних» событий, но требует некоторых дополнительных действий при реализации.

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

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

Пример использования

Посмотрим на созданный нами визуальный компонент в действии.

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

Компонент будем создавать при отображении формы:

При создании компонента для его события OnClick сразу же назначается обработчик, в котором «индикатор» будет перекрашиваться в красный цвет:

Так выглядит компонент после создания:

Компонент на форме

А, так он выглядит после клика на нём левой кнопкой мыши.

Компонент на форме перекрашеный

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

Один комментарий

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *