Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Event in einer Class programmieren (https://www.delphipraxis.net/121817-event-einer-class-programmieren.html)

Chemiker 5. Okt 2008 10:01


Event in einer Class programmieren
 
Hallo,

ich möchte ein Ereignis in eine Class integrieren. Wenn die Class innerhalb des Forms deklariert wird ist das so möglich:

Delphi-Quellcode:
type
  THPLCom1 = class(TComponent)
  private
    FCom1: TApdCustomComPort;
    FPack1: TApdDataPacket;
  public
    Constructor Create(AOwner : TComponent); override;
    destructor Destroy; override;
  end;

type
  TForm3 = class(TForm)
    btnCOMPortOeffnen: TButton;
    btnCOMPortSchliessen: TButton;
    MemoDatenAnzeigen: TMemo;
    procedure btnCOMPortOeffnenClick(Sender: TObject);
    procedure btnCOMPortSchliessenClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }

    ComTest2: THPLCom1;
    Procedure MyStringPacketTest (Sender: TObject; Data: String); // Event!
  end;
Das Ereignis zuweisen geht so:

Delphi-Quellcode:
procedure TForm3.FormCreate(Sender: TObject);
begin
  ComTest2:= THPLCom1.Create(self);
  ComTest2.FPack1.OnStringPacket:= MyStringPacketTest; // Event zuweisen
end;
Das Ereignis verwenden so:

Delphi-Quellcode:
Procedure TForm3.MyStringPacketTest (Sender: TObject; Data: String); // Event ausführen
begin
  MemoDatenAnzeigen.lines.Add(Data);
end;
Ich will nun die Class in eine separate Unit ablegen und suche jetzt eine Möglichkeit das Ereignis mit in die Class zu integrieren.

Die Class in der separaten Unit sieht so aus:

Delphi-Quellcode:
unit uApdComPortDynamischErstellen;

interface

uses
  Classes, AdPort, AdPacket;


type
  THPLComPortClass= Class(TComponent)
  private
    FComPort      : TApdCustomComPort;
    FStringPackete : TApdDataPacket;
    function GetOeffnen: Boolean;
    procedure SetOeffnen(const Value: Boolean);
    function GetZuweisen: TApdCustomComPort;
    procedure SetZuweisen(const Value: TApdCustomComPort);

  public
    Constructor Create(AOwner : TComponent); override;
    destructor Destroy; override;

    property Oeffnen: Boolean Read GetOeffnen Write SetOeffnen;
    property zuweisen: TApdCustomComPort Read GetZuweisen Write SetZuweisen;
  End;
An welcher Stelle und wie kann ich das Ereignis in der Class ablegen?

Bis bald Chemiker

taaktaak 5. Okt 2008 11:14

Re: Event in einer Class programmieren
 
Moin, Moin.

Kommt auf das Event an, du willst ein individuelles Event erstellen. Also zuerst eine Typdefinition:
Delphi-Quellcode:
TMyDataEvent = procedure(Data:String) of Object;
Danach muss ein Methodenzeiger im private-Abschnitt bereitgestellt werden:
Delphi-Quellcode:
private
  FOnData : TMyDataEvent
Danach im published-Abschnitt die Eigenschaft für das Ereignis definieren:
Delphi-Quellcode:
published
  property OnData : TMyDataEvent read FOnData write FOnData
Das sollte eigentlich schon alles sein.

Na, nicht ganz, der Aufruf fehlt nun noch:
Delphi-Quellcode:
if Assigned(FOnData) then FOnData(Self,'mein string');
// edit: Jens hat Recht, der Aufruf sollte noch dabei sein :hi:

Luckie 5. Okt 2008 11:42

Re: Event in einer Class programmieren
 
Du kannst dir das mal in meiner Klasse TFileSplitter angucken: http://www.michael-puff.de/Developer/Delphi/Demos -> TFileSplitter.zip

SirThornberry 5. Okt 2008 13:25

Re: Event in einer Class programmieren
 
@taaktaak: der Vollständigkeit halber fehlt noch wie man das Event dann auslöst :-) Dann wäre es schon beinahe Codelib-fähig

Chemiker 5. Okt 2008 17:20

Re: Event in einer Class programmieren
 
Hallo taaktaak, Luckie,

vielen Dank für eure Hilfe. Ich bin aber noch nicht weiter gekommen.

Das Event ist schon vorhanden in der Komponente: TApdDataPacket.

In der Hilfe wird das Event so angegeben:

Zitat:

TApdDataPacket.OnStringPacket

property OnStringPacket : TStringPacketNotifyEvent

TStringPacketNotifyEvent = procedure(

Sender : TObject; Data : string) of object;

Defines an event handler that is called when a complete data packet is available.

Data is the actual data in the packet. The data packet is only available for the duration of the event.
Note that a null character (#0) in the collected data may terminate the Data string prematurely. This is due to the way that Delphi and C++Builder implement huge strings. If you are expecting null characters in the collected data, use the OnPacket event instead.
Meine Class sieht jetzt so aus:

Delphi-Quellcode:
TMyDataEvent = procedure(Sender: TObject; Data:String) of Object;


  THPLComPortClass= Class(TComponent)
  private
    FComPort      : TApdCustomComPort;
    FStringPackete : TApdDataPacket;          // ---- in dieser Komponente ist das Event
                                                                      // schon vorhanden.

    FOnData : TMyDataEvent; // Event

    function GetOeffnen: Boolean;
    procedure SetOeffnen(const Value: Boolean);
    function GetZuweisen: TApdCustomComPort;
    procedure SetZuweisen(const Value: TApdCustomComPort);
  protected

  published
     property OnData : TMyDataEvent read FOnData write FOnData; // Event
  public
    Constructor Create(AOwner : TComponent); override;
    destructor Destroy; override;

    property Oeffnen: Boolean Read GetOeffnen Write SetOeffnen;
    property zuweisen: TApdCustomComPort Read GetZuweisen Write SetZuweisen;
  End;
Im Testprogramm weise ich das Event so zu:

Delphi-Quellcode:
type
  TfrmComPortPacket = class(TForm)
    btnCOMOeffnen: TButton;
    btnCOMSchliessen: TButton;
    Memo1: TMemo;
    procedure btnCOMOeffnenClick(Sender: TObject);
    procedure btnCOMSchliessenClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
    CP: THPLComPortClass;
    Procedure MyString (Sender: TObject; Data: String);
  end;


procedure TfrmComPortPacket.FormCreate(Sender: TObject);
begin
  CP:= THPLComPortClass.Create(Self);
  CP.OnData:= MyString;
end;
So wird das Event aufgerufen:

Delphi-Quellcode:
Procedure TfrmComPortPacket.MyString (Sender: TObject; Data: String);
begin
  Memo1.Lines.Add(Data);
end;
Das Programm lässt sich ausführen, aber das Ereignis wird nicht aufgerufen.

An welcher Stelle muss der Aufruf:

Delphi-Quellcode:
if Assigned(FOnData) then FOnData(Self,'mein string');
angegeben werden.


Bis bald Chemiker

mirage228 5. Okt 2008 17:34

Re: Event in einer Class programmieren
 
Du brauchst in Deiner Klasse einen Getter und einen Setter für "OnData". Im Setter musst Du das Event dann der Entsprechung in der TAdp...-Komponente zuweisen und im Getter von dort abrufen.

taaktaak 5. Okt 2008 18:33

Re: Event in einer Class programmieren
 
Hmm, da habe ich die Aufgabenstellung gründlich falsch verstanden.

Du bindest also eine fremde Komponente, die dieses Event bereits zur Verfügung stellt, im private-Abschnitt deiner Komponente ein. Das Anwendungsprogramm soll dann das Event der fremden Komponente nutzen können. Puh, da bin ich überfragt - da ist mein Beispiel natürlich nicht hilfreich.

Da muss ich leider passen :cry:

Blup 6. Okt 2008 09:44

Re: Event in einer Class programmieren
 
Delphi-Quellcode:
 THPLComPortClass= Class(TComponent)
  private
    FComPort      : TApdCustomComPort;
    FStringPackete : TApdDataPacket;          // ---- in dieser Komponente ist das Event
                                                                      // schon vorhanden.

    FOnData : TMyDataEvent; // Event

    function GetOeffnen: Boolean;
    procedure SetOeffnen(const Value: Boolean);
    function GetZuweisen: TApdCustomComPort;
    procedure SetZuweisen(const Value: TApdCustomComPort);
    procedure MyOnData(Sender: TObject; Data: String);
  protected

  published
     property OnData : TMyDataEvent read FOnData write FOnData; // Event
  public
    Constructor Create(AOwner : TComponent); override;
    destructor Destroy; override;

    property Oeffnen: Boolean Read GetOeffnen Write SetOeffnen;
    property zuweisen: TApdCustomComPort Read GetZuweisen Write SetZuweisen;
  End;


procedure THPLComPortClass.MyOnData(Sender: TObject; Data: String);
begin
  if Assigned(FOnData) then FOnData(Self, Data);
end;
Wichtig: Bei der Zuweisung von "FStringPackete" muss auch "FStringPackete.OnData" zugewiesen werden.
Delphi-Quellcode:
FStringPackete := ???
FStringPackete.OnData := MyOnData;

Chemiker 6. Okt 2008 21:54

Re: Event in einer Class programmieren
 
Hallo,

habe den Vorschlag von mirage228 umgesetzt.

Die Klasse sieht jetzt so aus:

Delphi-Quellcode:
TMyDataEvent = procedure(Sender: TObject; Data:String) of Object;

  THPLComPortClass= Class(TComponent)
  private
    FComPort      : TApdCustomComPort;
    FStringPackete : TApdDataPacket;
    function GetOeffnen: Boolean;
    procedure SetOeffnen(const Value: Boolean);
    function GetZuweisen: TApdCustomComPort;
    procedure SetZuweisen(const Value: TApdCustomComPort);
    function GetOnData: TMyDataEvent;
    procedure SetOnData(const Value: TMyDataEvent);
  protected

  published
     property OnData : TMyDataEvent read GetOnData write SetOnData;
  public
    Constructor Create(AOwner : TComponent); override;
    destructor Destroy; override;
usw.


function THPLComPortClass.GetOnData: TMyDataEvent;
begin
  Result:= FStringPackete.OnStringPacket;
end;

procedure THPLComPortClass.SetOnData(const Value: TMyDataEvent);
begin
  FStringPackete.OnStringPacket:= Value;
end;
Bis bald Chemiker


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:27 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