Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Procedure als Parameter übergeben (https://www.delphipraxis.net/14230-procedure-als-parameter-uebergeben.html)

SleepyMaster 5. Jan 2004 10:49


Procedure als Parameter übergeben
 
Delphi-Quellcode:
function XShow(p:pointer):integer;
begin
ShowMessage('Hallo');
end;

procedure StartThread(Thread:procedure); //<--- Das procedure da mag er ned!
//Hab aber leider keinen Plan was ich sonst da reinschreiben muss!
var
  ThreadID: DWORD;
  ThreadHandle: THandle;
begin
  ThreadHandle:=BeginThread(nil, 0, TFNThreadStartRoutine(@Thread),
    nil, 0, ThreadID);
  if ThreadHandle<>0 then CloseHandle(ThreadHandle);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
StartThread(XShow);
end;
Wie muss es richtig heißen???
Vielen Dank schon mal

MrKnogge 5. Jan 2004 11:07

Re: Procedure als Parameter übergeben
 
also wenn, dann müsstest du auch die parameter der Übergabe-procedure angeben, mir ist aber nicht bekannt, dass man eine procedure als parameter einer anderen Procedure übergeben kann.

Ich weiss auch ehrlich gesagt nicht, was das bringen soll :gruebel:

[Edit]Aber vielleicht kann man das Problem auch anders lösen[/Edit]

mirage228 5. Jan 2004 11:11

Re: Procedure als Parameter übergeben
 
Delphi-Quellcode:
type
  TMyProc = procedure;
end;

{ ... }

procedure Wuppdi(Proc: TMyProc);
begin
 // ...
end;
mfG
mirage228

MrKnogge 5. Jan 2004 11:13

Re: Procedure als Parameter übergeben
 
ui :shock:
geht das ? Wow, aber wenn dann nur mit Parameterangabe !

mirage228 5. Jan 2004 11:14

Re: Procedure als Parameter übergeben
 
Joa, das geht^^

Auf diese Weise kann man z.B. ein sog. "Callback" realisieren.

Die Events der VCL (TNotifyEvent = procedure(Sender: TObject);) benutzen auch procedures als Paramater.

mfG
mirage2328

Jens Schumann 5. Jan 2004 11:15

Re: Procedure als Parameter übergeben
 
Hallo,
Du kannst eine Methode (bzw einen Methodenzeiger) oder eine reguläre Prozedure übergeben.
Hier ist das Beispiel für den Methodenzeiger
Delphi-Quellcode:
unit Unit1;

interface

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

type

  TMyProc = function (p:pointer):integer of object;

  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
    procedure Test(AProc : TMyProc);
    function AFunction(p:pointer):integer;
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

function TForm1.AFunction(p: pointer): integer;
begin
  Result:=5;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Test(AFunction);
end;

procedure TForm1.Test(AProc: TMyProc);
var
  a : Integer;
begin
  a:=AProc(Nil);
  ShowMessage(IntToStr(a));
end;

end.
Und hier das Beispiel für die reguläre Procedure
Delphi-Quellcode:
unit Unit1;

interface

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

type

  TMyProc = function (p:pointer):integer ;

  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
    procedure Test(AProc : TMyProc);
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

function AFunction(p: pointer): integer;
begin
  Result:=5;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Test(AFunction);
end;

procedure TForm1.Test(AProc: TMyProc);
var
  a : Integer;
begin
  a:=AProc(Nil);
  ShowMessage(IntToStr(a));
end;

end.

MrKnogge 5. Jan 2004 11:18

Re: Procedure als Parameter übergeben
 
Zitat:

Zitat von mirage228
Joa, das geht^^

Auf diese Weise kann man z.B. ein sog. "Callback" realisieren.

Die Events der VCL (TNotifyEvent = procedure(Sender: TObject);) benutzen auch procedures als Paramater.

mfG
mirage2328

Das die Events (die ja ebenfallsso deklariert werden müssen)
auch proceduren sind, wusst ich aber ich dachte das sie dann
nur ausgeführt werden können, das man dann noch allerlei
anderes Zeugs machen kann, weiss ich erst seit grad eben :mrgreen:

SleepyMaster 5. Jan 2004 11:33

Re: Procedure als Parameter übergeben
 
Vielen Dank!
Es geht!

Micha88 10. Nov 2011 18:18

AW: Procedure als Parameter übergeben
 
Zitat:

Delphi-Quellcode:
ThreadHandle:=BeginThread(nil, 0, TFNThreadStartRoutine(@[B][I]test[/I][/B]),
    nil, 0, ThreadID);
  if ThreadHandle<>0 then CloseHandle(ThreadHandle);

Ist es auch möglich, eine vollständig deklarierte Procedur als Parameter zu übergeben?

also nicht diese
Delphi-Quellcode:
procedure test;
sondern diese
Delphi-Quellcode:
procedure TForm1.test;

s.h.a.r.k 10. Nov 2011 18:23

AW: Procedure als Parameter übergeben
 
Müsste dann halte eine
Delphi-Quellcode:
procedure of object;
sein. Wobei ich dir an der Stelle dann eher raten würde, auf die TThread-Klasse zu setzen und die Referenz auf die Methode via Property zu setzen.

DeddyH 10. Nov 2011 18:23

AW: Procedure als Parameter übergeben
 
Steht doch weiter oben (Methodenzeiger).

David Martens 24. Sep 2013 09:15

AW: Procedure als Parameter übergeben
 
Ich weiß das Thema ist schon etwas älter, aber meine Frage ist eine Weiterführung von diesem hier. Da wollte ich keinen neuen anfangen.

Nun zur Frage.

Ich habe ein Aktivformular. An das übergebe ich eine Prozedur als Property. Diese wird in ShowModal aufgerufen. Der einzige Nachteil an diesem Vorgehen, die Prozedur muß Parameterlos, bzw. die Parameter haben die ich in der Deklaration angegeben habe, besitzen.
Kann ich als Property eine Anonyme Prozedur angeben?

Hier was ich bisher habe (nur die wesentlichen Teile):
Delphi-Quellcode:
  TCallProc = procedure of object;
  TCallFunc = function: string of object;

  TWorkerThread = class(TThread)
    procedure Execute; override;
  private
    FCallProc: TCallProc;
    procedure SetCallProc(const Value: TCallProc);
  public
    property CallProc : TCallProc read FCallProc write SetCallProc;
  end;


  TAktivForm = class(TForm)
    procedure FormShow(Sender: TObject);
  private
    procedure WmAfterShow(var Msg: TMessage); message WM_AFTER_SHOW;
  public
    property CallProc : TCallProc read FCallProc write SetCallProc;
  end;

procedure TAktivForm.FormShow(Sender: TObject);
begin
  PostMessage(Self.Handle, WM_AFTER_SHOW, 0, 0);
end;

procedure TAktivForm.WmAfterShow(var Msg: TMessage);
begin
  Thread := TWorkerThread.Create(True);
  Thread.FreeOnTerminate := True;
  Thread.CallProc := FCallProc;
  Thread.Start;

  while (not Thread.Terminated) do
  begin
    Application.ProcessMessages;
    Sleep(50);
  end;

  Close;
end;

...

  AktivForm := TAktivForm.Create(Self);
  AktivForm.CallProc := Run;
  AktivForm.lblText.Caption := rcDatenabfrage;
  AktivForm.ShowModal;
Im wesentlichen wird an die Form eine Prozedur übergeben, die bei OnShow ausgeführt wird und am Ende wird das Formular geschlossen.
Nochmal:
Nachteil, die Prozedur "Run" muß so aussehen wie TCallProc definiert ist.

Jetzt habe ich versucht:
Delphi-Quellcode:
  TCallProc = reference to procedure[(parameterlist)];
Aber da damit geht es nicht:
E2010 Inkompatible Typen: 'TCallProc' und 'Procedure of object'

Kann man das irgendwie machen oder eher nicht?

David

stahli 24. Sep 2013 09:31

AW: Procedure als Parameter übergeben
 
Ich denke nicht, dass das geht.

Definiere dorch einfach die in Frage kommenden Prozeduren und prüfe, ob eine davon zugewiesen ist.

Ansonsten könntest Du den Weg über die RTTI gehen. Dann weist Du einen Text zu, ermittelst die passende Methode und rufst diese auf (Invoke).

Jonas Shinaniganz 24. Sep 2013 11:05

AW: Procedure als Parameter übergeben
 
Zitat:

Der einzige Nachteil an diesem Vorgehen, die Prozedur muß Parameterlos, bzw. die Parameter haben die ich in der Deklaration angegeben habe, besitzen.
Das trifft auch 1 zu 1 auf Anonyme Methoden zu.

Mal anders formuliert: Du suchst sowas wie Typenlosen-Methoden-Aufruf? Das gibt es in Delphi meines Wissens nach nicht. Dann müsste ja klar definiert sein, was passiert, wenn man die Methode aufruft ohne z.b. ein nicht Default Parameter übergeben zu haben?

Es gilt immer:

Zitat:

Zwei prozedurale Typen sind kompatibel, wenn sie folgende Bedingungen erfüllen:
Sie verwenden dieselbe Aufrufkonvention.
Sie haben denselben (oder keinen) Rückgabetyp.
Sie verwenden die gleiche Anzahl Parameter identischen Typs an den entsprechenden Positionen (die Parameternamen sind nicht von Bedeutung).
Was du machen kannst:

Delphi-Quellcode:
type
  Test = procedure(i : integer);
  procedure proc(i : integer);

procedure proc(i : integer);
begin
  ShowMessage(IntToStr(i));
end;



var
  myPointer : Pointer;
begin
  myPointer := @proc;

  if (myPointer = @proc) then
    Test(myPointer)(10);
end;

Bei
Delphi-Quellcode:
procedure of Object
kannst du mit
Delphi-Quellcode:
TMethod(proc).Code
den Pointer überprüfen.

Lass mich hören falls es was neues gibt, Grüße

Uwe Raabe 24. Sep 2013 11:33

AW: Procedure als Parameter übergeben
 
Zitat:

Zitat von David Martens (Beitrag 1229701)
Jetzt habe ich versucht:
Delphi-Quellcode:
  TCallProc = reference to procedure[(parameterlist)];
Aber da damit geht es nicht:
E2010 Inkompatible Typen: 'TCallProc' und 'Procedure of object'


Mir ist nicht ganz klar, was bei der Definition von TCallProc jetzt wirklich gemeint ist. Grundsätzlich kann man einem Property vom Typ reference to procedure auch eine parameterlose Klassenmethode zuweisen. Wichtig ist nur, daß die Signatur der Parameter passt.
Delphi-Quellcode:
type
  { geht beides }
  TCallProc = TProc;
  TCallFunc = TFunc<string>;
//  TCallFunc = function: string of object;
//  TCallProc = procedure of object;

type
  TForm158 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    FCallFunc: TCallFunc;
    FCallProc: TCallProc;
    function TestFunc: string;
    procedure TestProc;
  public
    property CallFunc: TCallFunc read FCallFunc write FCallFunc;
    property CallProc: TCallProc read FCallProc write FCallProc;
  end;

procedure TForm158.FormCreate(Sender: TObject);
begin
  CallProc := TestProc;
  CallFunc := TestFunc;
end;

function TForm158.TestFunc: string;
begin
  Result := 'Hallo Welt';
end;

procedure TForm158.TestProc;
begin
end;


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