Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Methodenaufrufe intern (https://www.delphipraxis.net/71191-methodenaufrufe-intern.html)

stoxx 10. Jun 2006 17:10


Methodenaufrufe intern
 
ich möchte folgendes realisieren.
Die Procedure : Zwischenaufruf soll nicht wissen, ob es sich um ein TNotifyEvent oder andere Events handelt.
Sie soll einfach jedes beliebige Event weiterleiten.
Aber irgendwie fehlen mir die genauen und professionellen Kenntnisse in Delphi.
Wie würde da funktionieren (procedure Zwischenaufruf)

hmm *grübel*

Delphi-Quellcode:
unit Unit2;

interface

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

type
  TEvent = procedure of Object;
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    procedure ZwischenAufruf( args: array of const);
    procedure Aufruf(Sender : TObject);
    { Private declarations }
  public
    Event : TEvent;
    FMethod : TMEthod;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var NotifyEvent : TNotifyEvent;
begin
  NotifyEvent := self.Aufruf;
  FMethod := TMethod(NotifyEvent);

  zwischenAufruf([self]);
end;

//==============================================================================

procedure TForm1.ZwischenAufruf( args: array of const);
begin

    TEvent(FMethod)( args); ?!?!?


end; //  ZwischenAufruf (TForm1)

//==============================================================================

procedure TForm1.Aufruf(Sender : TObject);
begin

    TForm1(Sender).Caption := 'Erfolgreich';
end; //  Aufruf (TForm1)

Dax 10. Jun 2006 17:35

Re: Methodenaufrufe intern
 
Puh... Ich weiß nicht, obs funktioniert, aber mein erster Ansatz wäre soetwas:
Delphi-Quellcode:
procedure TForm1.ZwischenAufruf(args: array of const);
var i: Integer; p: Pointer;
begin
  p := FMethod.Code;
  i := Length(args);
  case i of
    0: asm
         push p
         mov eax, Self
         call [esp]
         pop p
       end;
    1: asm
         push p
         mov eax, Self
         mov edx, [edx]
         mov edx, [edx]
         call [esp]
         pop p
       end;
    2: asm
         push p
         mov eax, Self
         mov edx, [edx]
         mov ecx, [edx+4]
         mov edx, [edx]
         call [esp]
         pop p
       end;
    else
      asm
        mov eax, args
        mov eax, [eax]
        mov ecx, [eax-4]
        mov edx, [edx]
      @_l:
        push [edx+ecx*4]
        cmp ecx, 2
        jnz @_1

        mov ecx, [edx+4]
        mov edx, [edx]
        call p
      end
  end;
end;
Ist ungetestet.. Grad so runtergeschrieben eben. Um Assembler wirst du bei diesem Vorhaben jedenfalls nicht rumkommen...

stoxx 10. Jun 2006 18:22

Re: Methodenaufrufe intern
 
Hi Dax,

ASM .. hmmm .. muss das sein ?
Dein Code funktioniert leider nicht und es kommt eine Access Violation.
Der Else zweig geht gar nicht zu kompilieren, @_1 wäre unbekannt.
Der Self parameter soll nicht verwendet werden sondern aus der Variablen MEthod extrahiert.
Jetzt hab ich es mal probiert so probiert.

Delphi-Quellcode:
unit Unit2;

interface

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

type
  TEvent = procedure of Object;
  TIrgendeinEvent = procedure(Sender : TObject; MeineZahl : Integer) of object;

  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    procedure Aufruf(Sender : TObject);
    procedure Aufruf2(Sender : TObject; MeineZahl : Integer);
  public
  end;

var
  Form1: TForm1;
  procedure ZwischenAufruf(Method : TMethod; args: array of const);

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
    NotifyEvent : TNotifyEvent;
    IrgendeinEvent : TIrgendeinEvent;
begin
  NotifyEvent := self.Aufruf;
  IrgendeinEvent := self.aufruf2;

  zwischenAufruf(TMethod(NotifyEvent), [self]);
  zwischenAufruf(TMethod(IrgendeinEvent), [self, 95]);
end;

//==============================================================================

procedure ZwischenAufruf(Method : TMethod; args: array of const);
var i: Integer; p: Pointer;
    self : Pointer;
begin
  p := Method.Code;
  self := Method.Data;
  i := Length(args);
  case i of
    0: asm
         push p
         mov eax, Self
         call [esp]
         pop p
       end;
    1: asm
         push p
         mov eax, Self
         mov edx, [edx]
         mov edx, [edx]
         call [esp]
         pop p
       end;
    2: asm
         push p
         mov eax, Self
         mov edx, [edx]
         mov ecx, [edx+4]
         mov edx, [edx]
         call [esp]
         pop p
       end;
    else
      asm
//        mov eax, args
//        mov eax, [eax]
//        mov ecx, [eax-4]
//        mov edx, [edx]
//      @_l:
//        push [edx+ecx*4]
//        cmp ecx, 2
//        jnz @_1
//
//        mov ecx, [edx+4]
//        mov edx, [edx]
//        call p
      end
  end;

end; //  ZwischenAufruf (TForm1)


//==============================================================================

procedure TForm1.Aufruf(Sender : TObject);
begin
    TForm1(Sender).Caption := 'Erfolgreich';
end; //  Aufruf (TForm1)

//==============================================================================

procedure TForm1.Aufruf2(Sender : TObject; MeineZahl : Integer);
var form : TForm1;
begin
  self.Caption := 'Self hat funktioniert';
  form := TForm1(Sender);
  form.Caption := form.Caption + ' Sender hat funktioniert';
  form.caption:= form.caption +   ' Integer ist gekommen: ' +  IntToStr(MeineZahl);
end; //  Aufruf2  (TForm1)

end.


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