2016-01-02 1 views
1

J'ai créé un composant, dans lequel j'utilise des fils, quelque chose comme ceci:Est-il possible d'accéder à un événement de mon composant (déclaration privée) à partir d'un thread (une autre classe)?

type 
    TEvent = procedure(sender:TObject) of object; 

    TMyComponent = class(TComponent) 
    protected 
    Fvar:String; 
    FMyEvent:TEvent; 
    public 
    Constructor Create(AOwner:TComponent);override; 
    published 
    property MyProperty:String read Fvar write Fvar; 
    property Event:TEvent read FMyEvent write FMyEvent; 
    end; 

    TMyThread = class(TThread) 
    procedure Execute; override; 
    end; 

implementation 

procedure TMyThread.Execute; 
begin 
    if assigned (FMyEvent) then 
    FMyEvent(Self); 
end; 

Comme vous pouvez le voir, j'accéder à FMyEvent qui est une variable privée, d'une autre classe, donc cela génère une compilation erreur (Undeclared Identifier), je sais qu'il est illogique d'accéder à une variable privée d'une autre classe mais j'ai vraiment besoin de l'utiliser! J'ai besoin que cet événement se produise lorsque TMyThread est exécuté. J'ai essayé ce code:

type 
    TEvent = procedure(sender:TObject) of object; 

    TMyComponent = class(TComponent) 
    protected 
    Fvar:String; 
    FMyEvent:TEvent; 
    public 
    Constructor Create(AOwner:TComponent);override; 
    published 
    property MyProperty:String read Fvar write Fvar; 
    property Event:TEvent read FMyEvent write FMyEvent; 
    end; 
    TMyThread = class(TThread) 
    private 
    fev:TEvent; 
    protected 
    procedure Execute; override; 
    public 
    constructor Create(afev:TEvent); 
    end; 

    implementation 
    procedure TMyThread.Create(afev:TEvent);//when i call this one i send the real Event of the component. 
    begin 
    fev:=afev; 
    if assigned (FMyEvent) then 
    FMyEvent(Self);  // it works here 
    end; 

procedure TMyThread.Execute; 
begin 
if assigned (FMyEvent) then 
    FMyEvent(Self);  //IT doesn't work here 
    end; 

Comme vous pouvez le voir, quand je crée le fil que j'envoie les propriétés du composant en tant que paramètres, j'ai appelé l'événement dans deux endroits différents, alors quand je l'appelle dans le constructeur ça marche bien, mais quand je l'appelle dans la procédure d'exécution rien ne se passe !! cependant la condition: if assigned (FMyEvent) est vraie dans les deux cas (j'ai essayé quelques tests pour vérifier celui-ci). Je suppose que le problème est pertinent pour "Self" dois-je remplacer par un autre propriétaire? Pourquoi l'événement fonctionne-t-il uniquement lorsque je l'appelle dans la procédure de création?

+1

Rechercher [Si vous souhaitez rendre votre application plus flexible, vous pouvez créer un événement pour le fil] (http://wiki.freepascal.org/Multithreaded_Application_Tutorial#The_TThread_Class) et lire cette page de début à fin soigneusement. Vous trouverez ici toutes les informations sur le multithreading. – Abelisto

Répondre

2
  1. FMyEvent n'est pas privé, il est protégé.
  2. Il est également publié en tant que Événement si accessible.
  3. Vous avez besoin d'une instance pour accéder à l'événement publié.

L'erreur Identificateur est Présence non déclarée en fait du point 3 et non pas de la visibilité.

Il devrait plutôt être quelque chose comme

procedure TMyThread.Execute; 
begin 
    if assigned (Instance.Event) then 
    Instance.Event(Self); 
end; 

Ou vous pouvez créer le fil avec un événement comme paramètre.

TMyThread = class(TThread) 
private 
    FMyEvent: TEvent; 
public 
    constructor construct(ev: TEvent); 
    procedure Execute; override; 
end; 

constructor TMyThread.construct(ev: TEvent); 
begin 
    FMyEvent := ev; 
end; 

procedure TMyThread.Execute; 
begin 
    if assigned (FMyEvent) then 
    FMyEvent(Self); 
end; 
+0

Votre deuxième suggestion m'a aidé à essayer quelque chose, voir ma modification. – Safa