Click here to Skip to main content
15,883,705 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
The scenario is: I have a parent form that creates a child form, in order to communicate between them, a object of the custom event type is created in the parent. The handel of the parent form is passed as a param to the event create procedure.

In the child form a custom event type property of the same type as the parent form is created, then at the time of creating the child form, from the parent, the parent's object is equated with the child's property, for example: propForm.CreateScheduleEvent:= CreateScheduleFormEvent;

In the scenario that only a parent form and a corresponding child form are used, the call back works without problems.

In the scenario of creating several parent forms with their respective child forms, the event is only recognized by the last created parent form, regardless of which child form the custom event has executed. Supposedly, if each parent form has an object of the listener type activated (attentive to the return calls of the custom event), at the moment of executing the custom event a loop should be triggered that listens for each parent form, that is the reason for using the handle variable but, the result only It runs only once.

The custom event declaration is:

Delphi
  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;


The Parent implementation is:

Delphi
  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;


The Child form implementation is:

Delphi
  private
    { Private declarations }
    FCreateScheduleEvent : TNewScheduleFormEvent;
........
  public
    { Public declarations }
    property CreateScheduleEvent: TNewScheduleFormEvent read FCreateScheduleEvent write FCreateScheduleEvent;
......
//Event Execution
  CreateScheduleEvent.OnCreateScheduleForm(CreateScheduleEvent.Source, GroupSchedule);


The question is: What would be the correct or better configuration of the customized event so that it is possible to have several parent forms with their respective child forms and that when a button is pressed to execute the custom event from a child form, this event will be heard by the correct parent even if the parent form does not have the focus activated.

What I have tried:

Clarification of the problem:

A child form is created from a parent form

In the child form there is a button that must be able to send a message to the parent form so that any action or method can be executed.

An event type class is created to establish communication between the parent form and the child form. As an aid to the recognition of the parent form by the child form, to the creation of the event class a parent handle is passed as a parameter of the create event.
A listener event type object is created in the parent form and is associated with the event class to listen to the child form.

CreateScheduleFormEvent:= TNewScheduleFormEvent.Create(FormHandle); CreateScheduleFormEvent.OnCreateScheduleForm:= FileListener.CreateScheduleFormEvent; propForm.CreateScheduleEvent:= CreateScheduleFormEvent;

If there is only one parent form with a child form, the event from the child form is heard correctly by its parent form.

If there are several parent forms, of the same type, each with its corresponding child, the event is not heard by the corresponding parents, that is, if from the child1 the event is executed, it should be heard by the parent1 and if it is executed from the child2 this should be heard from the parent2.

In the case of multiple parents with their corresponding children, the event executed by any of the children, child1 ... child10, only heard from the last parent created parent10 ..

What is the correct configuration of personalized events between parent forms and child forms, when the parents are of the same type and the children are of the same type, both are duplicates of two basic forms. When executing an event in the child form, it should only be listened to by its corresponding parent and not by another instance of the same parent form.
Posted
Updated 28-Feb-19 3:59am

1 solution

The solution has been to change the technique from events shared by multiple instances in the same way to the use of the technique with TMethod and TExecute from the child forms to the parents.

With this technique you can pass the handle of the parent form and the name of the method to be executed and regardless of how many instances of the same form exist in the application it always points to the method in the correct parent.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900