Я работаю над компонентом, который размещается в каждой форме моего проекта. Возможно ли, чтобы во время выполнения компонент включал код в обработчик событий OnClose формы владельца. Другими словами, форма будет запускать собственный обработчик события OnClose, но компонент также будет включать дополнительный код обработчика событий для запуска в событии OnClose формы-владельца. (Это то, что называется заменой вектора?) Спасибо.
Может ли компонент заменить событие формы владельца (OnClose) своим собственным обработчиком?
Ответы (1)
Вам нужно заставить компонент объявить поле для хранения исходного OnClose
формы. Затем вы можете сделать в конструкторе компонента:
FOriginalFormClose := (Owner as TForm).OnClose;
(Owner as TForm).OnClose := FormClose;
Тогда FormClose
компонента будет читать:
TMyComponent.FormClose(Sender: TObject; var Action: TCloseAction);
begin
// do stuff for this component
if Assigned(FOriginalFormClose) then
FOriginalFormClose(Sender, Action);
end;
Естественно, приведение as
связывает этот компонент с тем, что он принадлежит формам, но если вам нужна большая гибкость, вы можете легко удовлетворить это.
Это прямой ответ на вопрос, который вы задали, но с моей стороны было бы упущением не подвергнуть сомнению ваш общий дизайн. Если вы хотите, чтобы компонент работал в каждой форме вашего приложения, вам, безусловно, следует создать подкласс TForm
, содержащий ваши настройки. Затем сделайте так, чтобы каждая форма в вашем приложении основывалась на этом общем базовом классе формы.
Такой подход имеет много других преимуществ. Например, @LachlanG добавляет следующий очень меткий комментарий, с которым я полностью согласен:
Наличие компонента, вмешивающегося в его форму владения, нежелательно. Подавляющее большинство компонентов должны быть автономными объектами, изменение владельца компонента нарушает ожидаемый контракт компонента Delphi.
Подход с общей базовой формой решает эту проблему, помещая код, который работает с формой, внутрь формы.
Если вы идете по пути создания общей базовой формы, вам следует переопределить DoClose
, а не использовать событие OnClose
. Всегда используйте обработчики событий DoXXX
, а не сами события, когда вы создаете общий базовый класс или компонент.