Обработка событий
Событиям программист ставит в соответствие коды обработчиков событий, выполняющиеся всякий раз, когда соответствующее событие происходит. Некоторым событиям в Инспекторе объектов предписаны выпадающие списки, содержащие опции стандартных функций обработки событий, объявления и вызов которых C++Builder генерирует автоматически.
Рис. 6.5 показывает вкладку Events Инспектора объектов с выбранным событием OnClick компоненты TButton. Это событие возникает при нажатии кнопки Button 1. Если дважды щелкнуть мышью на поле события, C++Builder автоматически сгенерирует соответствующее объявление метода в файле объявлений Unitl.h, и Редактор кода переведет вас в нужную позицию в кодовом файле Unitl.cpp, где вы сможете написать код, реализующий этот метод.
Нижеследующий пример иллюстрирует процесс создания кода обработчика события OnClick (Нажата кнопка Button 1) для компоненты TButton.
Опытному программисту уже стало понятно, что событие будет содержать указатель функции обработки этого события.
Чтобы связать ваш собственный обработчик с событием OnClick компоненты TButton воремя выполнения программы, вы должны сначала создать метод для обслуживания этого события. Как и любой метод, он должен принадлежать существующему объекту — форме, которая владеет компонентой TButton и на которой она размещена.
Рис. 6.6 показывает окно Редактора кода с файлами Unitl.h и Unintl.cpp программного модуля, реализующего обработку события OnClick. Объявленный метод становится обработчиком события, когда событию Buttonl->OnClick присваивается указатель некоторого метода MyOnClickEvent.
Указанное присваивание можно также сделать динамически при работе программы в обработчике события OnCreate вашей формы. Результат будет таким же, как и при создании обработчика событий с помощью Инспектора объектов на этапе проектирования, за исключением того, что в этом случае C++Builder сохраняет связь события с его обработчиком в ресурсном файле с расширением .dfm. При запуске приложения VCL считывает форму из ресурсного файла и динамически присваивает значения свойств и событий компонент, размещенных на форме.
Рис. 6.6. Определение метода обработки события OnClick.
Когда вы определяете методы для обработчиков событий, эти методы должны быть того же типа, что и типы свойства и членов данных, на которые ссылается свойство. Например, событие OnClick ссылается на внутренний член данных FOnClick функционального типа TNotifyEvent.
Методы
Компонентные методы ничем не отличаются от других объектных функции-членов. Хотя C++Builder не вводит никаких специальных ограничении на оформление компонентных методов, имеется ряд правил, которых стоит придерживаться:
1. Минимизируйте число методов, которые вызывает прикладной программист, чтобы использовать вашу компоненту. Многое из того, что вы намеревались реализовать в виде методов, вероятно, лучше инкапсулировать в свойства компоненты. В отличие от свойств, методы работают только во время исполнения программы.
2. Избегайте взаимной зависимости методов, максимально изолируя методы друг от друга. Нельзя требовать, чтобы методы выполнялись в определенном порядке. Никакой метод не должен переводить компоненту в такое состояние, когда вызовы других методов станут запрещенными, т.к. смогут нарушить нормальное функционирование компоненты.
3. Придерживайтесь соглашения об именах методов. Названия должны быть описательными, т.е. включать глагол действия и отражать возвращаемое значение (например, метод PasteFromClipboard передает в компоненту данные из доски объявлений, а метод GetHorizontalPosition возвращает горизонтальную позицию некоторой величины).
4. Правильно защищайте методы. Все методы (включая конструкторы и .деструкторы), к которым имеют право обращаться пользователи вашей компоненты, следует объявлять какpublic. Все методы, к которым имеют право обращаться производные объекты вашей компоненты, следует объявлять как protected, что запрещает пользователям преждевременно вызывать методы, данные для которых еще не созданы. Только те методы, которые реализуют доступ к свойствам компоненты, должны быть объявлены какprivate, поскольку пользователи оперируют со значениями свойств напрямую.
5. Объявляйте методы виртуальными, когда хотите обеспечить полиморфное поведение переопределенных версий в разных классах.