Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Wie geerbte Ereignisse verarbeiten ?? (https://www.delphipraxis.net/55945-wie-geerbte-ereignisse-verarbeiten.html)

Net7 29. Okt 2005 10:36


Wie geerbte Ereignisse verarbeiten ??
 
Hi Leute,

Ich sitze hier wieder vor einem Problem, bei der Komponentenentwicklung.

Es geht um ein Events von ServerSocket.


So ist dieses äusserlich zu sehen.

Delphi-Quellcode:
procedure TForm1.SocketServer1ClientDisconnect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
end;
Wie kann ich dieses Event innerhalb der Komponente abfragen, ob dieses aufgetreten ist?? :gruebel:

Für Tipps wäre ich sehr dankbar.

Dust Signs 29. Okt 2005 10:38

Re: Wie geerbte Ereignisse verarbeiten ??
 
OnClientDisconnect überschreiben und im Event deinen Code inkl. inherited?

Dust Signs

SirThornberry 29. Okt 2005 10:41

Re: Wie geerbte Ereignisse verarbeiten ??
 
es gibt die Methode:
Delphi-Quellcode:
procedure ClientDisconnect(Socket: TCustomWinSOcket); dynamic;
Diese einfach überschreiben.

@DustSigns: Ein Event kann man nicht überschreiben.

Dust Signs 29. Okt 2005 10:47

Re: Wie geerbte Ereignisse verarbeiten ??
 
Zitat:

Zitat von SirThornberry
@DustSigns: Ein Event kann man nicht überschreiben.

Echt :shock: Upsi :oops: Wieso eigentlich nicht? Ich mein, ich hab's noch nie versucht, weil es nie notwendig war, aber ich würd trotzdem gern wissen warum :stupid:

Delphi-Quellcode:
procedure OnBla(Blub: TBlub); override;
{..}
procedure TMuh.OnBla(Blub: TBlub);
begin
  inherited;
  {..}
end;
Dust Signs

Net7 29. Okt 2005 10:58

Re: Wie geerbte Ereignisse verarbeiten ??
 
Hmm.....

Zitat:


Delphi-Quellcode:
procedure ClientDisconnect(Socket: TCustomWinSOcket); dynamic;


Irgendwie stehe ich aufn schlauch :roll:

Wird denn diese Procedure aufgerufen wenn es ein Disconnect gibt??

Ich will doch auch nix überschreiben das Event soll ja bleiben so wie es ist.
Ich möchte kein neues Basteln. Ich möchte nur innerhalb der Kompo wissen ob es auftritt.


Oder bin ich aufm Holzweg. :gruebel:

Khabarakh 29. Okt 2005 11:04

Re: Wie geerbte Ereignisse verarbeiten ??
 
Zitat:

Zitat von Dust Signs
Wieso eigentlich nicht?

OnDisconnect ist ja nur eine Property für FOnDisconnect. Da müsstest du schon eine Variable überschreiben können (bzw. die Compiler-Magic, die hinter den Methodenzeigern steckt) :stupid: .

@Net7: Der Weg ist der richtige. ClientDisconnect ist der sog. Event-Dispatcher von OnDisconnect. Wenn die Komponente das Event auslösen will, wird sie immer ClientDisconnect aufrufen.

Net7 29. Okt 2005 11:41

Re: Wie geerbte Ereignisse verarbeiten ??
 
Zitat:

Zitat von Khabarakh
@Net7: Der Weg ist der richtige. ClientDisconnect ist der sog. Event-Dispatcher von OnDisconnect. Wenn die Komponente das Event auslösen will, wird sie immer ClientDisconnect aufrufen.

Die Procedure
Delphi-Quellcode:
procedure ClientDisconnect(Socket: TCustomWinSOcket);
begin
       ...schreib log.. //um zu sehen ob sie angesprungen wurde
end;
wird aber kommischerweise nicht aufgerufen innerhalb der Kompo wenn der Client disconnect.

Mach ich was falsch oder verstehe ich was nicht :wall:

SirThornberry 29. Okt 2005 11:45

Re: Wie geerbte Ereignisse verarbeiten ??
 
@Net7: Hast du die Methode nur neu declariert oder überschrieben? (eventuell Override vergessen)

Khabarakh 29. Okt 2005 11:52

Re: Wie geerbte Ereignisse verarbeiten ??
 
Checkliste:
  • Du musst eine Klasse von TServerSocket ableiten.
  • In dieser musst du ClientDisconnect überschreiben. Also eine Methode mit gleichem Namen, gleicher Signatur (gleiche Sichtbarkeit ist auch nie falsch) und der Direktive override;.
  • In dieser solltest du unbedingt inherited; aufrufen. Aber auch ohne sollte dein Code aufgerufen werden.
  • Du musst deine Klasse verwenden. Also nicht einfach einen ServerSocket aus der Tool-Leiste auf die Form ziehen, das funktioniert sicher nicht :wink: . Entweder du erstellst deinen neuen Socket zur Laufzeit oder registrierst ihn auch als Komponente.

Net7 29. Okt 2005 11:54

Re: Wie geerbte Ereignisse verarbeiten ??
 
Zitat:

Zitat von SirThornberry
@Net7: Hast du die Methode nur neu declariert oder überschrieben? (eventuell Override vergessen)


Ich erweitere die Klasse TServerSocket um ein parr Funktionen und Proceduren

Die Urklasse ist halt TServersockt. Damit ich zb. bestimmte Proceduren aufrufen kann, muss ich zb. Wissen ob Onclientdisconect der UrKlasse aufgetreten ist.

SirThornberry 29. Okt 2005 11:57

Re: Wie geerbte Ereignisse verarbeiten ??
 
wie? du schreibst in der originalen Klasse herum?? Mach das bloß nicht!! Der Sinn von oop ist das man ableiten kann und somit nicht jedesmal am original herum basteln muss.

Net7 29. Okt 2005 12:08

Re: Wie geerbte Ereignisse verarbeiten ??
 
Zitat:

Zitat von SirThornberry
wie? du schreibst in der originalen Klasse herum?? Mach das bloß nicht!! Der Sinn von oop ist das man ableiten kann und somit nicht jedesmal am original herum basteln muss.

mom ich geb mal bissel quellcode

Delphi-Quellcode:

unit Net7Server;

interface

uses
  SysUtils, Classes, ScktComp,Forms;


  //  Primärheader
  Type
     TPHead=record
     Size     :Longword;
     end;

   // Sekundärheader

   Type
     TSHead=record
     TPSize   :Longword;     //Lange komplettes Paket
     Size     :Longword;    // Länge der Kern Daten
     Typ      : Integer;    // Typ der Daten
     end;


   // Statisches Hilfspaket
   Type
     THilfspaket=record
      PriHead        : TPHead;
      SecHead        : TSHead;
      Datenbuffer    : array[0..512000] of byte;
     end;


     Type
     TClientenverwaltung=record
     Con           :array [0..100] of Integer;
     HNr           :array [0..100] of Integer;
     isOnline      :array [0..100] of boolean;
     end;

    Type
     AHandles=array [0..100] of Integer;
     ACon=array [0..100] of Integer;
// Event erstellen das Datentyp und Grösse wiedergibt
TDatenVerarbeitungEvent = procedure (Sender:TObject;var DatenTyp:Integer;var DatenSize:Longword) of object;


const LOGFILE = 'LogFile.log';

 type
  TNet7Server = class(TServerSocket)
  private
    { Private-Deklarationen }

       //Variablen für Datenempfang Statisch
       PriHead        : TPHead;  //  Header
       Datenbuffer    : Pointer; //  Hauptbuffer, dort lagern die empf. Daten
       PriDatensize   : Longword; //  Grösse kompl. Paket
       SecDatensize   : Longword; //  Grösse Kerndaten
       BufferPosition : Longword; //  Lesezeichen für Receive Buffer
       NetDatensize   : Longword; //  Grösse des TCP-Pakets
       Modus          : Integer; //  Modusschalter, Lesen oder Ignorieren
       ErstesPaket    : Boolean; //  ..
       fertig         : boolean; //  ...
       Dummypaket     : THilfspaket; //...
       ExportDatentyp : Integer;   // Datentyp







    //Clientverwaltung
       CV:TClientenverwaltung;
        CVZaehler      :Integer;



    //Event gibt später Datentyp und Size zurück
    FOnVerarbeitung:TDatenVerarbeitungEvent;

    FOnDisconnect:TSocketNotifyEvent;
    //Interner Logger
    function DebugLog(LogString: String;Varwert:integer;Zeilennummer:integer): Integer; virtual;


  protected
    { Protected-Deklarationen }
  public
    { Public-Deklarationen }

   function Datenempfang(Client_Verbindungsnummer:integer):boolean; virtual;
   function Datenverarbeitung(var Exportdaten):boolean;virtual;

   function ClientListNow(var EHandles;Var EConnections):boolean;Virtual;



   procedure InitNet7Server;virtual;
   procedure ClientOnList;virtual;
   procedure ClientDeleteList;virtual;
   //function Sendedaten(var Importdaten:pointer;Importdatensize:Longword;ImportDatentyp:Integer):boolean;virtual;


   procedure ClientDisconnect(Socket: TCustomWinSOcket); dynamic;


  published
    { Published-Deklarationen }
   // Eventproperty
   property   OnVerarbeitung:TDatenVerarbeitungEvent read FOnVerarbeitung write FOnVerarbeitung ;

   //property   ClientDisconnect:TSocketNotifyEvent read FOnClientDisconnect write FOnClientDisconnect;



  end;




procedure Register;









implementation





procedure Register;
begin
  RegisterComponents('Marko', [TNet7Server]);
end;
.
.
.

Sie ist abgeleitet von der Klasse.

Khabarakh 29. Okt 2005 12:14

Re: Wie geerbte Ereignisse verarbeiten ??
 
Das hätte man aber auch auf das Notwendige kürzen können :wink: . Dein Fehler steht sowohl in meinem als auch in SirThornberrys Post.

[add]
Delphi-Quellcode:
FOnDisconnect:TSocketNotifyEvent;
:gruebel: ? Was willst du damit bezwecken?
[/add]

SirThornberry 29. Okt 2005 12:16

Re: Wie geerbte Ereignisse verarbeiten ??
 
wenn du die Methode überschreiben willst darfst du nicht
Delphi-Quellcode:
procedure ClientDisconnect(Socket: TCustomWinSOcket); dynamic;
schreiben sondern:
Delphi-Quellcode:
procedure ClientDisconnect(Socket: TCustomWinSOcket); override;
Schließlich willst du die Methode ja überschreiben und keine virtuelle neu declarieren (schau dir mal auf Delphi-Source.de die Tutorials dazu an.

@Khabarakh: Wo war in meinem Post der Fehler? Ich hab die Methode gepostet welche er überschreiben muss und diese ist nunmal "dynamic".

Net7 29. Okt 2005 12:25

Re: Wie geerbte Ereignisse verarbeiten ??
 
Zitat:

Zitat von Khabarakh
Das hätte man aber auch auf das Notwendige kürzen können :wink: . Dein Fehler steht sowohl in meinem als auch in SirThornberrys Post.

[add]
Delphi-Quellcode:
FOnDisconnect:TSocketNotifyEvent;
:gruebel: ? Was willst du damit bezwecken?
[/add]

Huch.. das sind noch parr überbleibsel meiner Experimente. :mrgreen:

Khabarakh 29. Okt 2005 12:37

Re: Wie geerbte Ereignisse verarbeiten ??
 
Zitat:

Zitat von Khabarakh
Die Lösung für deinen Fehler steht sowohl in meinem als auch in SirThornberrys Post.

So ist es etwas verständlicher :stupid: .

Net7 29. Okt 2005 12:47

Re: Wie geerbte Ereignisse verarbeiten ??
 
Also ich glaube das wir uns missverstehen. :roll:

Ich möchte keine Procedure procedure ClientDisconnect(Socket: TCustomWinSOcket);
neu schreiben.


Ich erkläre es mal anders.

Die Orginalkomponente gibt ja, wenn ein Client offline geht, ein Ereignis zurück. Im OE zu finden unter OnClientDisconnect.

Wenn dieses Ereignis auftaucht, das meine abgeleitete Komponente ja auch hat, möchte ich davon Kenntniss nehmen. Um eine Procedure innerhalb der Komponente aufzurufen um zum Beispiel, Erbsen zu zählen, :mrgreen: und deren Anzahl bei bedarf zurückzugeben. :gruebel:

Net7 29. Okt 2005 13:18

Re: Wie geerbte Ereignisse verarbeiten ??
 
So.. habe die Lösung gefunden

Delphi-Quellcode:
  if Assigned(OnClientDisconnect) then
eigendlich zu simpel :mrgreen:

Wie ich die procedure am Leben erhalte die diesen Code beinhaltet ist ein anderes Problem.

Aber vielen herzlichen Dank an Euch.

SirThornberry 29. Okt 2005 16:11

Re: Wie geerbte Ereignisse verarbeiten ??
 
ahh, du musst die methode nicht neu schreiben. Wenn du die Funktion überschreibst wird diese aufgerufen (somit bekommst du Kenntnis das diese aufgerufen wurde). Um nun das auszuführen was in der alten methode ausgeführt wurde musst du die funktion nicht neu schreiben sondern rufst einfach mit inherited die alte methode auf! (ich glaube dir fehlen entscheidende Grundlagen in Delphi)

Delphi-Quellcode:
type
  TNet7Server = class(TServerSocket)
  protected
    procedure ClientDisconnect(Socket: TCustomWinSOcket); override;
  [...]

procedure TNet7Server.ClientDisconnect(Socket: TCustomWinSOcket);
begin
  //Hier Source plazieren der ausgeführt werden soll bevor event ausgelöst wird
  inherited ClientDisconnect(Socket); //Damit wird die alte ClientDisconnect-Methode aufgerufen welche unter anderem das OnClientDisconnect auslöst
  //Hier Source plazieren der ausgeführt werden soll nach dem event ausgelöst wurde
end;

Dust Signs 29. Okt 2005 16:59

Re: Wie geerbte Ereignisse verarbeiten ??
 
@SirThornberry: und was war dann an meiner Aussage oben falsch? Genau das meinte ich ja...

Dust Signs

SirThornberry 29. Okt 2005 17:39

Re: Wie geerbte Ereignisse verarbeiten ??
 
@DustSigns: Du hast geschrieben er soll "OnClientDisconnect" überschreiben. Und OnClientDisconnection ist nur das Event was man nicht überschreiben kann. Bei den meisten komponenten gibt es Methoden welche das Event ausführen und somit kann man diese Methoden überschreiben. Es gibt aber auch den Fall das die Methode welche das Event auslöst nicht dynamic ist und somit kann man diese teilweise auch nicht überschreiben. Es ist also ein Unterschied ob man ein Event überschreibt (was nicht geht) oder die Methode die das event auslöst. "OnClientDisconnect" ist also etwas anderes als ClientDisconnect

Khabarakh 29. Okt 2005 17:40

Re: Wie geerbte Ereignisse verarbeiten ??
 
Zitat:

Zitat von Dust Signs
@SirThornberry: und was war dann an meiner Aussage oben falsch? Genau das meinte ich ja...

Du hast gesagt, man müsse die Variable/Property überschreiben, aber das geht eben nur mit der Dispatcher-Methode. Für dich mag das das gleiche sein, aber für einen Anfänger :wink: ...

@Net7:
Zitat:

Zitat von SirThornberry
(ich glaube dir fehlen entscheidende Grundlagen in Delphi)

Passend dazu die Neuerscheinung des Tages: Luckies "Klassen in Delphi"

Net7 29. Okt 2005 17:54

Re: Wie geerbte Ereignisse verarbeiten ??
 
Zitat:

Zitat von SirThornberry
ahh, du musst die methode nicht neu schreiben. Wenn du die Funktion überschreibst wird diese aufgerufen (somit bekommst du Kenntnis das diese aufgerufen wurde). Um nun das auszuführen was in der alten methode ausgeführt wurde musst du die funktion nicht neu schreiben sondern rufst einfach mit inherited die alte methode auf! (ich glaube dir fehlen entscheidende Grundlagen in Delphi)

Delphi-Quellcode:
type
  TNet7Server = class(TServerSocket)
  protected
    procedure ClientDisconnect(Socket: TCustomWinSOcket); override;
  [...]

procedure TNet7Server.ClientDisconnect(Socket: TCustomWinSOcket);
begin
  //Hier Source plazieren der ausgeführt werden soll bevor event ausgelöst wird
  inherited ClientDisconnect(Socket); //Damit wird die alte ClientDisconnect-Methode aufgerufen welche unter anderem das OnClientDisconnect auslöst
  //Hier Source plazieren der ausgeführt werden soll nach dem event ausgelöst wurde
end;


Hmmm so habe ich es ja probiert, nur es funktioniert ja nicht, weil mir beim Compilieren der Fehler auftritt.. "Methode ClientDisconnect" nicht in Basisklasse gefunden.

Und ich konnte die richtige Basisklasse auch bis jetzt nicht ermitteln.

Ich helfe mir nun aus in der Anwendung damit die Daten zurückzuvermitteln
in die Komponente.

Delphi-Quellcode:

procedure TForm1.Net7Server1ClientDisconnect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
     

   
     Net7Server1.ClientDeleteList(Socket);

end;

deklariert in der kompo ist das so

Delphi-Quellcode:
.
.
public

procedure ClientDeleteList(DSocket: TCustomWinSocket);virtual;
.
.
.


Ich weiß das das absolut unelegant ist. Nur was soll ich machen... :wall:

Khabarakh 29. Okt 2005 18:42

Re: Wie geerbte Ereignisse verarbeiten ??
 
Oh, hab gerade in die Socket-Sourcen geschaut... erstens ist es anders und zweitens als man denkt :stupid: .
TServerSocket bezieht seine gesamten Client-Events von FServerSocket(TServerWinSocket). Du musst also von TServerWinSocket ableiten und dort ClientDisconnect überschreiben. Damit die neue Klasse auch verwendet wird, muss nun FServerSocket auch als diese instanziiert werden. Dazu fallen mir zwei Möglichkeiten ein:
1. Du leitest von TServerSocket ab und überschreibst den Constructor:
Delphi-Quellcode:
begin
  inherited;
  FServerSocket.Free;
  FServerSocket := TMyNewServerWinSocket.Create(INVALID_SOCKET);
end;
Finde ich allerdings nicht ganz so schön, besser ist IMO:
2. Leite von TCustomServerSocket ab, mit folgendem Constructor (Original: TServerSocket.Create):
Delphi-Quellcode:
begin
  inherited Create(AOwner);
  FServerSocket := TMyNewServerWinSocket.Create(INVALID_SOCKET); //<- Veränderung
  InitSocket(FServerSocket);
  FServerSocket.ThreadCacheSize := 10;
end;
Außerdem kopierst du den Interface-Teil von TServerSocket, was aber nicht viel ist (neue Implementierungen gibts auch nicht).

Das Ganze ist also doch nicht so trivial :zwinker: .

Net7 29. Okt 2005 19:07

Re: Wie geerbte Ereignisse verarbeiten ??
 
Zitat:

Zitat von Khabarakh
... hab gerade in die Socket-Sourcen geschaut...

Öhmmmm.... wie das denn, hast du dir das hikhak aus der DCU angetan??? :pale:


Tja wird mir wohl nix anderes übrig bleiben das so zumachen wie du vorschlägst. :roll:

Khabarakh 29. Okt 2005 19:25

Re: Wie geerbte Ereignisse verarbeiten ??
 
Zitat:

Zitat von Net7
Zitat:

Zitat von Khabarakh
... hab gerade in die Socket-Sourcen geschaut...

Öhmmmm.... wie das denn, hast du dir das hikhak aus der DCU angetan??? :pale:

Ich könnte einfach "Ja" sagen, aber eigentlich habe ich nur die Pas im "Source"-Ordner geöffnet :mrgreen: .

Net7 29. Okt 2005 19:30

Re: Wie geerbte Ereignisse verarbeiten ??
 
Zitat:

Zitat von Khabarakh
Ich könnte einfach "Ja" sagen, aber eigentlich habe ich nur die Pas im "Source"-Ordner geöffnet :mrgreen: .


Tja dann hast du mir eins vorraus, die gibs bei mir irgendwie nicht OnSource.. :wall:


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