Как определить, какая дочерняя форма запускает обычное пользовательское событие в delphi
Сценарий таков: у меня есть родительская форма, которая создает дочернюю форму, чтобы общаться между ними, в родительской форме создается объект пользовательского типа события. Гендель родительской формы передается в качестве параметра процедуре создания события.
В дочерней форме создается пользовательское свойство типа события того же типа, что и родительская форма, затем в момент создания дочерней формы из родительского объекта родительский объект приравнивается к дочернему свойству, например: propForm.CreateScheduleEvent:= CreateScheduleFormEvent;
В сценарии, где используются только родительская форма и соответствующая дочерняя форма, обратный вызов работает без проблем.
В сценарии создания нескольких родительских форм с соответствующими дочерними формами событие распознается только последней созданной родительской формой, независимо от того, какую дочернюю форму выполнило пользовательское событие. Предположительно, если в каждой родительской форме активирован объект типа listener (внимательный к обратным вызовам пользовательского события), то в момент выполнения пользовательского события должен быть запущен цикл, который прослушивает каждую родительскую форму, что является причиной использования переменной handle, но в результате он запускается только один раз.
Пользовательское объявление события выглядит следующим образом:
TCreateScheduleEvent = procedure(source: HWND; GroupSchedule: TGroupSchedule) of object; TNewScheduleFormEvent = class private FCreateScheduleForm: TCreateScheduleEvent; FHandle: Int64; public constructor Create(source: HWND); property OnCreateScheduleForm: TCreateScheduleEvent read FCreateScheduleForm write FCreateScheduleForm; property Source: Int64 read FHandle write FHandle; procedure CreateScheduleForm(GroupSchedule: TGroupSchedule); end; //TNewScheduleFrmEvent constructor TNewScheduleFormEvent.Create(source: HWND); begin inherited Create; FHandle:= source; end; procedure TNewScheduleFormEvent.CreateScheduleForm(GroupSchedule: TGroupSchedule); begin { Call the registerd event only if there is a listener } if Assigned(FCreateScheduleForm) then FCreateScheduleForm(FHandle, GroupSchedule); end;
Родительская реализация такова:
TFileListener = class procedure CreateScheduleFormEvent(source: HWND; GroupSchedule: TGroupSchedule); end; ......... private { Private declarations } FileListener: TFileListener; CreateScheduleFormEvent : TNewScheduleFormEvent; ........ procedure TFileListener.CreateScheduleFormEvent(source: HWND; GroupSchedule: TGroupSchedule); begin if FormHandle = source then begin ............... end; end; ........ //OnCreate FileListener := TFileListener.Create(); FormHandle:= Handle; CreateScheduleFormEvent:= TNewScheduleFormEvent.Create(FormHandle); CreateScheduleFormEvent.OnCreateScheduleForm:= FileListener.CreateScheduleFormEvent; //Child form propForm:= TfrmPropList.Create(Self); propForm.PopupMode:= pmExplicit; propForm.Parent:= Parent; propForm.CreateScheduleEvent:= CreateScheduleFormEvent; propForm.Show;
Реализация дочерней формы такова:
private { Private declarations } FCreateScheduleEvent : TNewScheduleFormEvent; ........ public { Public declarations } property CreateScheduleEvent: TNewScheduleFormEvent read FCreateScheduleEvent write FCreateScheduleEvent; ...... //Event Execution CreateScheduleEvent.OnCreateScheduleForm(CreateScheduleEvent.Source, GroupSchedule);
Вопрос заключается в следующем: какова была бы правильная или лучшая конфигурация настроенного события, чтобы можно было иметь несколько родительских форм с их соответствующими дочерними формами и чтобы при нажатии кнопки для выполнения пользовательского события из дочерней формы это событие было услышано правильным родителем, даже если родительская форма не имеет активированного фокуса.
Что я уже пробовал:
Прояснение проблемы:
Дочерняя форма создается из родительской формы
В дочерней форме есть кнопка, которая должна иметь возможность отправить сообщение в родительскую форму, чтобы можно было выполнить любое действие или метод.
Класс типа события создается для установления связи между родительской формой и дочерней формой. В качестве вспомогательного средства для распознавания родительской формы дочерней формой, для создания класса событий Родительский дескриптор передается в качестве параметра события create.
Объект типа события прослушивателя создается в родительской форме и связан с классом событий для прослушивания дочерней формы.
CreateScheduleFormEvent:= TNewScheduleFormEvent.Create(FormHandle); CreateScheduleFormEvent.OnCreateScheduleForm:= FileListener.CreateScheduleFormEvent; propForm.CreateScheduleEvent:= CreateScheduleFormEvent;
Если существует только одна родительская форма с дочерней формой, событие из дочерней формы правильно воспринимается ее родительской формой.
Если существует несколько родительских форм одного и того же типа, каждая со своим соответствующим дочерним элементом, событие не слышится соответствующими родителями, то есть, если от child1 событие выполняется, оно должно быть услышано parent1, и если оно выполняется от child2, это должно быть услышано от parent2.
В случае нескольких родителей с их соответствующими детьми событие, выполняемое любым из детей, child1 ... child10, слышно только от последнего родителя, созданного parent10 ..
Какова правильная конфигурация персонализированных событий между родительскими формами и дочерними формами, когда родители имеют один и тот же тип, а дети-один и тот же тип, оба являются дубликатами двух основных форм. При выполнении события в дочерней форме оно должно прослушиваться только соответствующим родителем, а не другим экземпляром той же родительской формы.