Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Callback oder sonstige Methode (https://www.delphipraxis.net/117884-callback-oder-sonstige-methode.html)

Pluto 27. Jul 2008 09:38


Callback oder sonstige Methode
 
Ich habe ein Object, das in einer Schleife einen Windows Ordner und
Unterordner nach bestimmten Dateien durchsucht und bei den gefundenen
Dateien gewisse Untersuchungen durchführt. Im aufrufenden Form (Unit1)
möchte ich anzeigen, welche Datei gerade bearbeitet wird.
Das wäre einfach, wenn ich in der Unit des Objectes ein "uses Unit1"
einfügen würde, das ist aber nicht möglich, da ich das Object von
verschiedenen Stellen des Programmes aufrufen möchte.

Um nicht den umfangreichen Code des Objectes hier bringen zu müssen,
habe ich das Problem hier auf ein simples Testprogramm reduziert.
Unit1 enthält das aufrufende Form, Unit2 das simplifizierte Object TCBTest.
Statt der Datei Proceduren wird von TCBTest nur eine Liste gefüllt.

Hier das Object TCBTest:
Delphi-Quellcode:
unit Unit2;

interface

uses
  Classes, SysUtils, Controls, Dialogs ;

type
  TCBTest = class(TControl)
  private
    FSList: TStringList;
    procedure FillSL;
  public
    constructor Create; override;
    destructor Destroy; override;
    property SList: TStringList read FSList;
  end;

var
  CBTest: TCBTest;

implementation

constructor TCBTest.Create(AOwner: TComponent);
begin
  inherited;
  FSList := TStringList.Create;
  FSList.Clear;
  FillSL;
end;

destructor TCBTest.Destroy;
begin
  FreeAndNil(FSList);
  inherited Destroy;
end;

procedure TCBTest.FillSL;
var
  i: integer;
begin
  FSList.Clear;
  for i := 0 to 9 do begin
    FSList.Add(IntToStr(i));
    ShowMessage(IntToStr(i) + ' added to list');
    { statt ShowMessage sollte hier die Rückmeldung zum
    aufrufendem Form erfolgen - Anzeige im Edit Feld }
    Sleep(200); // Zeit für Anzeige
  end;
end;

end.
Das Form, welches das Object aufruft hat nur einen Button,
eine Listbox und ein Editfeld.
Delphi-Quellcode:
unit Unit1;

interface

uses
  Messages, SysUtils, Classes, Controls, Forms,
  Dialogs, StdCtrls, Unit2;

type
  TForm1 = class(TForm)
    Button1: TButton;
    lbxSL: TListBox;
    Edit1: TEdit;
    procedure Button1Click(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  CBTest := TCBTest.Create(Self);
  lbxSL.Items := CBTest.SList;
  FreeAndNil(CBTest);
end;

end.
Ich habe mit Callback Funktionen und auch mit Procedural Types
experimentiert, ohne eine Lösung zu finden.
Kann mir jemand helfen?

mkinzler 27. Jul 2008 09:41

Re: Callback oder sonstige Methode
 
Übergib das Ausgabe-Control doch als Parameter

Luckie 27. Jul 2008 12:37

Re: Callback oder sonstige Methode
 
Warum nutzt du keine Ereignisse?

Khabarakh 27. Jul 2008 12:54

Re: Callback oder sonstige Methode
 
Zitat:

Zitat von Pluto
Ich habe mit Callback Funktionen und auch mit Procedural Types
experimentiert, ohne eine Lösung zu finden.

Dann lass uns doch einmal an deinen Experimenten teilhaben. Ansonsten würde ich mich am Vorzeigebeispiel orientieren: TList.Sort.

rollstuhlfahrer 27. Jul 2008 13:16

Re: Callback oder sonstige Methode
 
das müsste doch ganz einfach gehen. Du definiest einen Typ mit
Delphi-Quellcode:
type
  TTestType = procedure (Sender: TObject; AddedValue: String) of object;
Diesen fügst du im Konstruktor ein und schreibst den entsprechenden Wert in ein private-Member deines Objekts. Beim füllen frägst du dann ab, ob der Wert vorhanden ist (mit Assigned()) und führst bei Erfolg die Prozedur aus. Dann brauchst du auch kein Sleep.

Bernhard

Beispiel:
Plutos Beispiel

Delphi-Quellcode:
unit Unit2;

interface

uses
  Classes, SysUtils, Controls; // Dialogs wirst du auf Grund von ShowMessage nicht mehr brauchen

type
  TTest = procedure (Sender: TObject; AddedValue: String) of object;

  TCBTest = class(TControl)
  private
    fTest: TTEst;
    procedure FillSL;
  public
    constructor Create(AOwner: TComponent; Test: TTest);
    property SList: TStringList read FSList;
  end;

implementation

constructor TCBTest.Create(AOwner: TComponent; Test: TTest);
begin
  inherited;
  fTest := Test;
  FSList := TStringList.Create;
  FSList.Clear;
  FillSL;
end;

procedure TCBTest.FillSL;
var
  i: integer;
begin
  FSList.Clear;
  for i := 0 to 9 do begin
    FSList.Add(IntToStr(i));
    if Assigned(fTest) then
      fTest(Self, IntToStr(i));
  end;
end;

end.
Das Form, welches das Object aufruft hat nur einen Button,
eine Listbox und ein Editfeld.
Delphi-Quellcode:
unit Unit1;
  [snip]

procedure TForm1.OnTest(Sender: TObject; AddedValue: String);
begin
  Edit1.Text := AddedValue;
  Sleep(200);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  CBTest := TCBTest.Create(Self, OnTEst);
  lbxSL.Items := CBTest.SList;
  FreeAndNil(CBTest);
end;

end.

Pluto 27. Jul 2008 15:40

Re: Callback oder sonstige Methode
 
Vielen Dank an Alle!

Ihr habt mir geholfen.

Luckie 27. Jul 2008 16:08

Re: Callback oder sonstige Methode
 
Zitat:

Zitat von rollstuhlfahrer
das müsste doch ganz einfach gehen. Du definiest einen Typ mit
Delphi-Quellcode:
type
  TTestType = procedure (Sender: TObject; AddedValue: String) of object;

Und genau das ist die Deklaration eines Ereignisses.

Pluto 28. Jul 2008 09:12

Re: Callback oder sonstige Methode
 
noch ne kleine Ergänzung:

@Rollstuhlfahrer:
Erstmal Dank für den auführlichen Code.
Der constructor Create in Unit2 mit dem zusätzlichen Parameter Test: TTest hat den Nachteil
dass inherited einen Fehler erzeugt. (Der constructor von TControl ist dazu nicht kompatibel)
Besser ist es den Parameter in Create wegzulassen und die Variable FTest über eine
Property Test im Object TCBTest zu übergeben.

Ihr dürft alle über mich lachen:
Genau so hatte ich bei meinen "Experimenten" angefangen. Irgend ein Tippfehler führte mich dann
über nicht verstandene Compilerfehlermeldungen in die Irre. Als ich garnicht mehr weiter kam, habe
ich hier gepostet und ihr habt mich dann wieder auf den richtigen Pfad zurückgeführt.

mkinzler 28. Jul 2008 09:19

Re: Callback oder sonstige Methode
 
Zitat:

Der constructor Create in Unit2 mit dem zusätzlichen Parameter Test: TTest hat den Nachteil
dass inherited einen Fehler erzeugt. (Der constructor von TControl ist dazu nicht kompatibel)
Besser ist es den Parameter in Create wegzulassen und die Variable FTest über eine
Property Test im Object TCBTest zu übergeben.
Nein es macht schon Sinn einen überladenen Konstruktor zu verwenden. Man muss halt den Konstruktor der Superklasse mit dem Parameter aufrufen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:22 Uhr.

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