2011-03-31 2 views
0
type 
    TMyClass = class 
    type 
    PMyClass = ^TMyClass; 
    TMyEvent = procedure(Sender: PmyClass) of object; 
    public 
    FTest: TMyEvent; 
    procedure Test; 
    end; 

procedure TMyClass.Test; 
begin 
    FTest(@Self); //error! 
end; 

Comment faire?Pointer to Self, comment?

+0

Vous faites exactement comme ça. Ce code compile sur mon D2010. Je ne suis pas sûr pourquoi vous voudriez faire cela cependant. –

+1

@ pop33 Self est déjà un pointeur ... qu'est-ce que vous essayez d'atteindre? – jachguate

+0

@ pop33: Si vous n'êtes pas sûr de ce que vous faites, vous voudrez probablement utiliser 'Sender: TMyObject' à la place. Comme le souligne @jachguate, une variable objet est essentiellement déjà un "pointeur". –

Répondre

5

Que voulez-vous faire dans le monde? Bien sûr, vous ne pouvez pas appeler FTest puisque vous ne lui avez encore attribué aucun TMyEvent! Et sont PMyClass et TMyEvent vraiment censé être des parties de TMyClass?

Au moins cela fonctionne parfaitement:

type 
    PMyClass = ^TMyClass; 
    TMyClass = class; 

    TMyEvent = procedure(Sender: PMyClass) of object; 

    TMyClass = class 
    private 
    FEvent: TMyEvent; 
    FSomeValue: string; 
    public 
    property OnSomething: TMyEvent read FEvent write FEvent; 
    property SomeValue: string read FSomeValue write FSomeValue; 
    procedure Test; 
    end; 

    TSomeOtherClass = class 
    public 
    class procedure MyEvent(Sender: PMyClass); 
    end; 

... 

procedure TForm6.FormCreate(Sender: TObject); 
var 
    o: TMyClass; 
begin 

    o := TMyClass.Create; 
    o.SomeValue := 'This is a test.'; 
    o.OnSomething := TSomeOtherClass.MyEvent; 

    o.Test; 
end; 

{ TMyClass } 

procedure TMyClass.Test; 
begin 
    FEvent(@Self); 
end; 

{ TSomeOtherClass } 

class procedure TSomeOtherClass.MyEvent(Sender: PMyClass); 
begin 
    ShowMessage(TMyClass(Sender^).SomeValue); 
end; 

Bien sûr, vous pouvez aussi avoir les TMyEvent dans le même objet:

type 
    TMyClass = class 
    private type 
    PMyClass = ^TMyClass; 
    TMyEvent = procedure(Sender: PMyClass) of object; 
    private 
    FEvent: TMyEvent; 
    FSomeValue: string; 
    public 
    procedure TheEventHandler(Sender: PMyClass); 
    property OnSomething: TMyEvent read FEvent write FEvent; 
    property SomeValue: string read FSomeValue write FSomeValue; 
    procedure Test; 
    end; 

... 

procedure TForm6.FormCreate(Sender: TObject); 
var 
    o: TMyClass; 
begin 

    o := TMyClass.Create; 
    o.SomeValue := 'This is a test.'; 
    o.OnSomething := o.TheEventHandler; 

    o.Test; 
end; 

{ TMyClass } 

procedure TMyClass.Test; 
begin 
    FEvent(@Self); 
end; 

procedure TMyClass.TheEventHandler(Sender: PMyClass); 
begin 
    ShowMessage(TMyClass(Sender^).SomeValue); 
end; 
+1

@Andreas Il est très normal de déclarer des types privés à une classe afin de restreindre leur portée et d'éviter la pollution des espaces de noms. Delphi n'a pas beaucoup de fonctionnalités d'espace de noms. J'ai pris l'erreur //! pour signifier une erreur de compilateur. –

+0

@David: Je le sais. Je l'ai fait plus tôt aujourd'hui, vous savez. Mais j'ai eu l'impression que la logique dicte que le type d'événement devrait être en dehors de la classe. –

+0

@Andreas J'aime les déclarations de type privé et mon ancienne base de code D6 évolue dans cette direction. –