Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Und wieder einmal CallBack (https://www.delphipraxis.net/206448-und-wieder-einmal-callback.html)

Ykcim 22. Dez 2020 16:09

Delphi-Version: 10.4 Sydney

Und wieder einmal CallBack
 
Hallo Zusammen,

ich habe das Thema leider immer noch nicht unter die Füße bekommen...
Callback-Procedure ohne Parameter-Übergabe laufen mittlerweile, aber jetzt müsste ich unsauber arbeiten, wenn ich es weiterhin ohne mache...

Ich habe diesen Type definiert:
Delphi-Quellcode:
type
  TDataRecieved_Param = reference to procedure(JSResult: boolean);
und eine Procedure, in dem dieser Type zur Anwendung kommen soll:
Delphi-Quellcode:
public
    { Public-Deklarationen }
    procedure Mail_Confirm(v_code: string; DataRecieved_Param: TDataRecieved_Param);
In dieser Procedure wird ein Service aufgerufen und ein Überprüfung gibt einen boolean-Wert zurück.
Delphi-Quellcode:
procedure TForm_MailConf.Mail_Confirm(v_code: string; DataRecieved_Param: TDataRecieved_Param);
   procedure OnResponse(Response: TXDataClientResponse);
   var  JSResult: boolean;
         JSObj: TJSObject;
   begin
      JSObj:=TJSJSON.parseObject(Response.ResponseText);
      JSResult:= StrToBool(String(JSObj['value']));
      if (Assigned(DataRecieved_Param)) then begin
         DataRecieved_Param(JSResult);
      end;
   end;
begin
   Try
      xDWC_MailConfirmed.RawInvoke('ITV_CreateNewCustService.Valid_LogIn',[v_code], @OnResponse);
   Except
      MessageDlg('Es hat einen Fehler beim Speichern gegeben',WEBLib.Dialogs.mtError, [mbOK]);
      Exit;
   End;
end;
Jetzt möchte ich der Callback-Procedure diesen Wert übergeben. Ich dachte, dass ich das hiermit mache:
Delphi-Quellcode:
if (Assigned(DataRecieved_Param)) and (JSResult=true) then begin
         DataRecieved_Param(JSResult);
      end;
Mit dem Aufruf der habe ich meine Probleme. Bei Callbacks ohne Prameter habe ich das so gemacht:
Delphi-Quellcode:
procedure TForm_MailConf.WebButton1Click(Sender: TObject);
var  v_code: string;
      JSResult: boolean;
begin
   v_code:=GetQueryParam('mail_code');
   Mail_Confirm(v_code, procedure begin Display_Result(JSResult) end); //Allerdings war dann da kein Parameter.
end;
Ich habe folgende Varianten versucht:
Delphi-Quellcode:
Mail_Confirm(v_code, procedure begin Display_Result end);  //Ich dachte, dass das geht, denn er bekommt den Parameter ja in der Mail_Confirm. Fehler: [Fataler Fehler] Wrong number of parameters specified for call to "Display_Result"

Mail_Confirm(v_code, procedure begin Display_Result(JSResult) end); //Ich dachte, vielleicht muss ich einen Parameter mitgeben, der dann überschrieben wird. Fehler: [Fataler Fehler] Incompatible type arg no. 2: Got "Procedure/Function", expected "TDataRecieved_Param"
:oops: Und während ich Euch das hier aufschreibe, komme ich auf die Lösung... Ich lasse es jetzt hier drinstehen, denn vielleicht hilft es jemandem weiter...

Die Lösung:
Delphi-Quellcode:
Mail_Confirm(v_code, @Display_Result);
Wenn ich das richtig verstanden habe, dann sorgt das @ dafür, dass die Procedure nur als ein Zeiger verstanden und sie nicht sofort ausgeführt wird. Den Parameter muss ich nicht übergeben, denn der wird ja beim Aufruf in Mail_Confirmed gesetzt.

Jedenfalls so funktioniert es...

Rollo62 22. Dez 2020 16:23

AW: Und wieder einmal CallBack
 
Versuche mal mit const, ohne jetzt tiefer reingesehen zu haben:
Delphi-Quellcode:
procedure TForm_MailConf.Mail_Confirm(v_code: string; const DataRecieved_Param: TDataRecieved_Param);
...

himitsu 22. Dez 2020 16:32

AW: Und wieder einmal CallBack
 
Dir wurde doch der Fehler genau genannt?

> Wrong number of parameters specified for call to "Display_Result"
Ja, Display_Result möchte einen Parameter haben.

> Incompatible type arg no. 2: Got "Procedure/Function", expected "TDataRecieved_Param"
Du hast "Procedure" übergeben, aber der Parameter in Mail_Confirm ist ein TDataRecieved_Param,
also deine "procedure" hat die falsche Signatur (ParameterTypen+Result).

Delphi-Quellcode:
Mail_Confirm(v_code, procedure(JSResult: boolean) // also genauso, wie TDataRecieved_Param definiert wurde
  begin
    Display_Result(JSResult); // k.A. was du hier eigentlich anzeigen willst (niemandem hast du verraten wie Display_Result definiert ist)
  end);
Außerdem willst du bestimmt "das" JSResult aus dem Callback haben
und nicht irgendein "JSResult", was du in WebButton1Click definiert hattest (und dem noch nichtmal ein Wert zugewiesen wurde).


Wenn Display_Result eine Prozedur oder Klassenmethode
Delphi-Quellcode:
procedure {TEineKlasse.}Display_Result(irgendwas: boolean);
ist,
dann geht es auch direkt, da die Signatur passt.
Delphi-Quellcode:
Mail_Confirm(v_code, Display_Result);

außer "Display_Result" war nur ein "Dummycode", für irgendwas zum Anzeigen.

Ykcim 22. Dez 2020 16:52

AW: Und wieder einmal CallBack
 
Zitat:

Dir wurde doch der Fehler genau genannt?
Stimmt, aber ich wusste nicht, was er mir zu sagen hatte...

Zitat:

Display_Result(JSResult); // k.A. was du hier eigentlich anzeigen willst (niemandem hast du verraten wie Display_Result definiert ist)
Dachte, es wäre nicht wichtig...
Delphi-Quellcode:
procedure TForm_MailConf.Display_Result(JSResult: boolean);
begin
   if JSResult then begin
      Label_Result.Font.Color:=clGreen;
      Label_Result.Caption:='Ihre Mail-Adresse wurde erfolgreich bestätigt. Sie können sich nun in Ihrem TheVisit anmelden.'
   end
   else begin
      Label_Result.Font.Color:=clRed;
      Label_Result.Caption:='Ihre Mail-Adresse konnte nicht verifiziert werden. Sollen wir Ihnen den Link erneut zuschicken?'
   end;
end;
Es geht darum, dass ein User sich auf einer WebPage mit seiner Mail-Adresse registriert und diese dann mit einem Link bestätigt wird. Nach dem Speichern in der Datenbank, bekommt der Benutzer eine Mail mit einem Link. Er klickt auf diesen und diese WebPage wird geöffnet und die Mail-Adresse bestätigt und dem Benutzer ein Feedback gegeben...

Zitat:

Wenn Display_Result eine Prozedur oder Klassenmethode procedure {TEineKlasse.}Display_Result(irgendwas: boolean); ist,
dann geht es auch direkt, da die Signatur passt.
Mail_Confirm(v_code, Display_Result);
Hierbei habe ich das Problem gehabt, dass die Procedure sofort aufgerufen wurde, statt zu warten, bis der Server ein Ergebnis zurückgeliefert hat, ob die Mail-Adresse bestätigt gefunden wurde...

Ich hatte nicht verstanden, das es ein Zeiger bedeutet, wenn ich ein @ vor die Procedure setze...
Jetzt funktioniert es.

Vielen Dank!

Jens01 22. Dez 2020 17:10

AW: Und wieder einmal CallBack
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich habe den Thread jetzt nicht verfolgt. Hier ist aber ein schönes Tool, um Callbacks in den Griff zu bekommen.


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