Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi OnIrgendwas Handler lokal zuweisen --> Typfehler... (https://www.delphipraxis.net/101674-onirgendwas-handler-lokal-zuweisen-typfehler.html)

Ares 17. Okt 2007 09:28


OnIrgendwas Handler lokal zuweisen --> Typfehler...
 
Hallo!


Folgendes Problem:

Delphi-Quellcode:
type
  TMeineKlase = class(TObjekt)
  private
    procedure MachIrgendwas;
    ...
  end;

...

  procedure TMeineKlasse.MachIrgendwas;
  var Obj: TEinObjekt;
      str: string;

      procedure IrgendwasPassiert(Param1: string; Param2: integer);
      begin
        ReagiereIrgendwie();
        str := str + Param1;
      end;
  begin
    Obj := TEinObjekt.Create;  
    Obj.OnIrgendwas := IrgendwasPassiert;

    Obj.MachWas;

    Obj.Free:
  end;
In der Methode MachIrgendwas() einer eigenen Klasse wird also ein Objekt erzeugt und ein EventHandler zugewiesen. Beim Compilieren erhalten ich aber immer die Meldung E2009 Inkompatible Typen: 'Methodenzeiger und reguläre Prozedur'.

Das Ereignis TEinObjekt.OnIrgendwas ist dabei vom Typ TIrgendeinEvent:
Delphi-Quellcode:
...
  TIrgendeinEvent = procedure(Param1: string; Param2: integer) of object;
...
Die Signatur der lokalen Procedure IrgendwasPassiert() passt also zu TIrgendeinEvent und trotzdem erhalte ich die genannte Fehlermeldung.

Was mache ich hier falsch?

Besten Dank für eure Hilfe!
Ares

Nuclear-Ping 17. Okt 2007 12:29

Re: OnIrgendwas Handler lokal zuweisen --> Typfehler...
 
Deine "Irgendwaspassiert" ist, wie dein Delphi-Compiler schon meckert, eine reguläre Prozedur, die du keinem Ereignis als Behandlungsroutine zuweisen kannst.

Die "Irgendwaspassiert" muss ein "Methodenzeiger" sein. Kurz gesagt heisst das, dass er eine Methode einer Klasse sein muss, was bei dir aber nicht gegeben ist.

Delphi-Quellcode:
type
  TIrgendwaspassiert = procedure (Sender: TObject; Param1: String; Param2: String) of object;

  TIrgendeineKlasse = class (...)
  private
    FIrgendwaspassiert: TIrgendwaspassiert;
  public
    procedure MacheIrgendwas;
  published
    property OnIrgendwaspassiert: TIrgendwaspassiert read FIrgendwaspassiert write FIrgendwaspassiert;
  end;

  TForm1 = class (TForm)
  private
    FIrgendeineKlasse: TIrgendeineKlasse;

    procedure MyIrgendwaspassiert (Sender: TObject; Param1: String; Param2: String);
  public
    ...
  end;

implementation

procedure TIrgendeineKlasse.MacheIrgendwas;
begin

  MacheVieleSachen;

  if Assigned (FIrgendwaspassiert) then
    FIrgendwaspassiert (Self, DeinParam1, DeinParam2);

  MacheAndereSachen;
end;

// ****

procedure TForm1.Create (Sender: TObject);
begin
  FIrgendwaspassiert := TIrgendwaspassiert.Create;
  FIrgendwaspassiert.OnIrgendwaspassiert := MyIrgendwaspassiert;
end;

procedure TForm1.Button1Click (Sender: TObject);
begin
  FIrgendwaspassiert.MacheIrgendwas;
end;

procedure TForm1.Destroy;
begin
  FreeAndNil (FIrgendwaspassiert);
  inherited;
end;

end.
Das sollte klappen.

Ares 17. Okt 2007 13:05

Re: OnIrgendwas Handler lokal zuweisen --> Typfehler...
 
Vielen Dank für deine ausführliche Antwort!

Kurz zusammengefasst heißt das, dass die Procedure die als Eventhandler zuweise eine Methode einer Klasse sein muss und nicht irgendeine "zwischendurch" definierte Procedure.

Dabei habe ich aber folgende Probleme:
1. In meiner Klasse gibt es nicht nur eine Methode die ein lokales TEinObjekt verwendet sonder ziemlich viele. Fast jede dieser Methoden soll auf Ergeinisse des Objektes anders reagieren. Ich müsste also für jede Methode eigene Eventhandler in meiner Klasse definieren. Das wären ziemlich viele.

2. Die Eventhandler sollen mit lokalen Variablen der jeweiligen Methoden arbeiten. Das ist nicht möglich, wenn die Eventhandler als private Procedure der Klasse deklariert sind (siehe die Variable str in meinem Beispiel). Dann müsste ich statt lokaler Variablen in den Methoden globale Variablen im Objekt verwenden. Das wäre ebenfalls ziemlich viel und unübersichtlich.

Gibt es also irgend eine Möglichkeit den Eventhandler "elegant" lokal zu definieren und zu verwenden oder ist dies ausgeschlossen?

Nuclear-Ping 17. Okt 2007 13:19

Re: OnIrgendwas Handler lokal zuweisen --> Typfehler...
 
Wenn du in solche Abhängigkeiten gerätst, solltest du vielleicht nochmal dein Vorhaben und das Konzept dazu überdenken. ;)

Du kannst auch nur einen zentralen Eventhandler anlegen, dem du als Parameter eine ID oder sowas übergibst, damit du weißt, von welcher Funktion in deiner Klasse er aufgerufen wurde. Darauf kannst du ja entsprechend reagieren ...

Muetze1 17. Okt 2007 13:22

Re: OnIrgendwas Handler lokal zuweisen --> Typfehler...
 
oder B'n'D dies so abändern:
Delphi-Quellcode:
  TIrgendeinEvent = procedure(Param1: string; Param2: integer);

Ares 17. Okt 2007 13:34

Re: OnIrgendwas Handler lokal zuweisen --> Typfehler...
 
Zitat:

Zitat von Nuclear-Ping
Wenn du in solche Abhängigkeiten gerätst, solltest du vielleicht nochmal dein Vorhaben und das Konzept dazu überdenken. ;)

Mmh, ich verwende doch "nur" an verschiedenen Stellen meiner Klasse ein TEinObjekt dessen Events ich nutzen möchte. Das ist quasi so, als ob TStrings ein Ereignisse hätte und ich für jede lokale Varable str: TStrings einen eigenen globalen Handler definieren müsste... Aber mal sehen was ich anders machen kann.

Zitat:

Zitat von Nuclear-Ping
Du kannst auch nur einen zentralen Eventhandler anlegen, dem du als Parameter eine ID oder sowas übergibst, damit du weißt, von welcher Funktion in deiner Klasse er aufgerufen wurde. Darauf kannst du ja entsprechend reagieren ...

Ich glaube nicht, dass das geht. Meine Klasse soll ja auf ein Ereigniss reagiern (und nicht selbst eins auslösen). Die Signatur des Eventhandlers ist vorgegeben (TIrgendeinEvent) und darin ist keine ID vorgesehen. Das Objekt enthält auch keinen Tag oder dergleichen den man als ID verwenden könnte.


Zitat:

Zitat von Muetze1
oder B'n'D dies so abändern:
Delphi-Quellcode:
  TIrgendeinEvent = procedure(Param1: string; Param2: integer);

Sorry, das verstehe ich nicht ganz. Wo muss ich was abändern? Was genau soll das bewirken?

Hawkeye219 17. Okt 2007 14:03

Re: OnIrgendwas Handler lokal zuweisen --> Typfehler...
 
Hallo Ares,

Zitat:

Zitat von Ares
Die Eventhandler sollen mit lokalen Variablen der jeweiligen Methoden arbeiten.

Auch wenn du als Mensch dies garantieren kannst - der Compiler weiß nicht, ob die lokalen Variablen gültig sind, wenn der Event ausgelöst wird. Aus diesem Grund verhindert Delphi die Zuweisung von lokalen Routinen an Prozedurvariablen. Du solltest also nach anderen Lösungen für dein Problem suchen.

Gruß Hawkeye


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:51 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz