Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - Events erzeugen (winsock)


retnyg - Mo 28.02.05 12:17
Titel: Events erzeugen (winsock)
ich möchte gerne eine eigene HTTP-Komponente auf Basis der unit winsock aufbauen (indy is mir zu dick und zu viele unterschiedliche versionen)
bislang habe ich so auf den socket zugegriffen:

Delphi-Quelltext
1:
2:
3:
4:
while true do begin
  RECV(bla);
  tu_etwas_mit_den_empfangenen_daten;
end;

also eine endlosschleife die per Recv daten empfängt.
wie könnte ich das nun bei einer Kompo als Ereignis definieren also z.b. OnReceive ?

Moderiert von user profile iconraziel: Schiebeposting entfernt.


BenBE - Mo 28.02.05 14:19

Keine Schiebepostings vor Ablauf von 24h. Deine Frage wird sonst auch nicht schneller beantwortet. THX.

Tipp: Siehe Windows-Botschaften, die an dein Window gesendet werden, was Du beim Erstellen des Sockets angeben musst.


retnyg - Mo 28.02.05 14:23

das erstellen des sockets passiert so:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
  iResult := WSAStartup(MAKEWORD(2,2), wsaData);
  if (iResult <> NO_ERROR) then
    writeln('Error at WSAStartup()\n');

  //----------------------
  // Create a SOCKET for connecting to server
  ConnectSocket := socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

finde hier nicht wirklich einen zusammenhang zu windows-botschaften o0


Grendel - Mo 28.02.05 14:26

Wo willst Du das Event auslösen? In der Schleife?
Und wo ist genau das Problem? Weißt Du nicht, wie man Events implementiert oder hab ich Dich einfach nur misverstanden?!

Bis neulich ...


retnyg - Mo 28.02.05 14:28

genau, habe keine ahnung wie man events auslöst. wäre nett wenn mir da jemand etwas auf die sprünge helfen kann


Grendel - Mo 28.02.05 14:38

Ahh, alles klar. Guckst Du:

Also man nehme eine Klasse (MyClass)

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
unit MyClassU;

interface

uses
  Classes;

type
  TOnMyEvent = procedure(Sender: TObject; AValue: Stringof object;

  TMyClass = class
  private
    FOnDingens: TNotifyEvent;
    FOnMyEvent: TOnMyEvent;
  public
    procedure RaiseEvents();
  published
    property OnDingens: TNotifyEvent read FOnDingens write FOnDingens;
    property OnMyEvent: TOnMyEvent   read FOnMyEvent write FOnMyEvent;
  end;

implementation

{ MyClass }

procedure TMyClass.RaiseEvents();
begin
  if Assigned(FOnDingens) then
    FOnDingens(self);

  if Assigned(FOnMyEvent) then
    FOnMyEvent(self, 'Test-Event');
end;



sowie ein Formular zum testen:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
unit FrmMainU;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, MyClassU, StdCtrls;

type
  TFrmMain = class(TForm)
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
    MyClass: TMyClass;
    procedure Dingens(Sender: TObject);
    procedure MyEvent(Sender: TObject; AValue: String);
  public
    { Public-Deklarationen }
  end;

var
  FrmMain: TFrmMain;

implementation

{$R *.dfm}

procedure TFrmMain.FormCreate(Sender: TObject);
begin
  MyClass := TMyClass.Create();
  MyClass.OnDingens := Dingens;
  MyClass.OnMyEvent := MyEvent;
end;

procedure TFrmMain.MyEvent(Sender: TObject; AValue: String);
begin
  ShowMessage('MyEvent: ' + AValue);
end;

procedure TFrmMain.Dingens(Sender: TObject);
begin
  ShowMessage('OnDingens');
end;

procedure TFrmMain.Button1Click(Sender: TObject);
begin
  MyClass.RaiseEvents();
end;

end.


Falls Du aus dem Beispiel nicht schlau wirst kann ich Dir auch gerne noch ein paar Erklärungen dranschreiben.

Bis neulich ...


retnyg - Mo 28.02.05 14:42

so weit so gut, aber wie wird das event gelauncht ?


Grendel - Mo 28.02.05 14:55

In o.g. Beipsiel werden die Events von Außen durch den Aufruf von RaiseEvents() ausgelöst.
Das eigentliche Auslösen ist das hier:

Delphi-Quelltext
1:
2:
if Assigned(FOnMyEvent) then  
  FOnMyEvent(self, 'Test-Event');

Und das kann selbstverständlich an jeder beliebigen Stelle in der Klasse ausgelöst werden.

Bis neulich ...


retnyg - Mo 28.02.05 15:01

ok, vielen dank. werde mal in mich gehen und das gelesene reflektieren.
bei eventuellen fragen werde ich mich wieder an dich wenden, wenn ich darf... ;)


Benutzername - Fr 20.05.05 01:10

Jetzt hab ich noch ne Frage :-)
Wann werden die Events ausgelöst?

Was muss ich tun, damit sie ausgelöst werden?

//edit: OK, hat sich erledigt :-)
Man muss natürlich noch irgendwo in ner Prozedur/Funktion die Eventhandlerfunktionen aufrufen, sonst ham die ja nix zu tun :-)


Daimonion - Fr 09.09.05 13:09

Hallo.

Hab genau das gleiche Problem gehabt und bisher hat mir dieser Thread sehr gut geholfen.

Allerdings hab ich eine etwas andere Sachlage als die Codeschnipsel die Grendel gepostet hat.


Die Klasse MyClass, wo das Event quasi geschrieben wird ist soweit klar. Diese hab ich auch fast 1:1 übernommen(nur das eine TNotifyEvent hab ich nicht übernommen).


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
type
   TOnTeachEvent = procedure(sender: Tobject) of object;

   TTeachEvent = class
   private
       FOnTeachEvent : TOnTeachEvent;
   public
       procedure RaiseEvent;
   published
       property OnTeachEvent : TOnTeachEvent read FOnTeachEvent write FOnTeachEvent;

implementation


procedure RaiseEvent;
begin
    if assigned(FOnTeachEvent) then FOnTeachevent(self);
end;
   
end.



Soweit ich das sehen kann, brauch man auch keinen Konstruktor, da die Methode RaiseEvent public. ist.

Meine Programmumgebung stellt sich wie folgt dar.

Ich habe eine Thread wo dieses Event ausgelöst wird. Der Thread an sich ist für Datenlesen und Datenaufbereitung aus einer Schnittstellenkarte zuständig. Im Konstruktor dieses Threads wird eine Methode aus einer anderen "Unit" (gern benutz ich den Namen nicht ;-) ) dem Property des Events zugewiesen.


Delphi-Quelltext
1:
teach_event.OnTEachEvent := FrmEinrichten.teachevent;                    


So wie ich das von den Codeschnipseln abstrahieren konnte, wird bei einem RaiseEvent die dem Property zugewiesene Methode ausgeführt?!
Oder hab ich das etwa falsch verstanden?

Das Thread Objekt wird beim erstellen der Applikation (FormCreate) aufgerufen.

Nur leider bekomme ich immer wenn ich was von meiner EventKlasse aufrufe eine Excpetion EAccessViolation.

Nach dem Debuggen hab ich herausgefunden, das sobald ich in die EventKlasse einsteige die Exception ausgelöst wird.

Könnt ihr mir helfen mein Problem zu beseitigen?
Danke schon mal im Voraus.


Daimonion - Fr 09.09.05 15:22

Okay, vergesst den letzten Post von mir und Schlagt mich mit Objektorientierten Knüppeln..

Fehler war, das ich anscheinend keine Objekte mehr instanziieren kann.
:roll:

teach_event.create; <----- falscher als Falsch

teach_event := TTeachevent.create; <--- so lernt man das ja eigentlich



Wird zeit das Wochenende wird