Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi OnClick-Ereignis ohne Prozedur (https://www.delphipraxis.net/1993-onclick-ereignis-ohne-prozedur.html)

CalganX 2. Jan 2003 11:23


OnClick-Ereignis ohne Prozedur
 
Hi,
ich bin dabei einige Komponenten auf dem Formular dynamisch zu erstellen. Nun meine Frage: Wie kann ich das OnClick-Ereignis so zuweisen, dass ich keine zusätzliche Funktion schreiben muss (ausgenommen sind Funktionen in Funktionen, sofern dass in Delphi geht (in TP gings))...

Chris

Chewie 2. Jan 2003 11:57

Korrigiert mich bitte, falls ich was Falsches sag:

Ein Prozedurpointer kann einem Ereignishandler zugewiesen werden.
Diese Prozedur oder Funktion kannst du selbst erstellen, du kannst aber auch eine nehmen, die bereist existiert.
Also folgendes müsste z. B. gehen:
Delphi-Quellcode:
//Objekte erzeugen
//...

MyObject.onClick := ShowMessage(MyObject.Text);
Über den Sinn und Zweck lässt sich da allerdings streiten.

Ob es eine andere (sinnvolle) Möglichkeit gibt, weiß ich nicht.

CalganX 2. Jan 2003 14:12

Geht leider nicht, wird wohl doch eine eigene Prozedur werden.
Frage dann ist: Kann man in Delphi (in TP ging's, wie gesagt) eine Prozedur in eine andere schachteln? So ein etwa:
Delphi-Quellcode:
procedure TForm1.MyProc(Sender: TObject);
var
  bButton1: TButton;
begin
  procedure b1Click(Sender: TObject);
  begin
    ShowMessage('Button1 geklickt!');
  end;

  bButton1 := { ... };
  { ... alles weitere ... }
  bButton1.OnClick := b1Click(bButton1);
end;
Geht das und was müsste man an diesem Source anders machen?

Chris

d3g 2. Jan 2003 14:16

@Chewie: Das geht nicht, weil die Events vom Typ
Delphi-Quellcode:
type
  TNofifyEvent = procedure(Sender: TObject) of object;
sind. ShowMessage ist aber eine procedure(Text: String) of object.

@Chakotay:
Wie in TP auch: Die Prozedurendeklaration vor begin.

MfG,
d3g

Helld_River 2. Jan 2003 14:17

Wenn mich nicht alles täuscht, mußt Du die innere Procedure über dem begin der äusseren deklarieren.
Allgemein gesehen ist das überhaupt kein Problem. Ich glaube in der Hilfe von Delphi finden sich auch einige Beispiele dazu.

Gruß, Helld

CalganX 2. Jan 2003 14:19

Zitat:

Zitat von Helld_River
Wenn mich nicht alles täuscht, mußt Du die innere Procedure über dem begin der äusseren deklarieren.
Allgemein gesehen ist das überhaupt kein Problem. Ich glaube in der Hilfe von Delphi finden sich auch einige Beispiele dazu.

Gruß, Helld

Nein, leider nicht. Und leider habe ich dazu auch nix im Turbo Pascal-Kompendium gefunden...

Trotzdem, danke...

Chris

CalganX 2. Jan 2003 14:50

Delphi-Quellcode:
procedure TForm1.Serienummergenerator1Click(Sender: TObject);
var
  { ein paar Variablen }

 procedure bButtonClick(Sender: TObject);
 begin
   // ein paar Anweisungen
 end;

begin
  // einige Zeilen Code
  bButton.OnClick := bButtonClick;
end;
Das ist mein Source... Und warum funktioniert das nicht?

Chris

CalganX 2. Jan 2003 15:36

So, habe meinen Fehler gefunden (ich hatte geschrieben bButton.OnClick := bButtonClick(bButton);) schon folgt der nächste gleich Zeile, korrigierter Source:

Zitat:

Zitat von Delphi-Debugger
[Error] Unit1.pas(222): Incompatible types: 'method pointer and regular procedure'

Frage: Was tun? Lt. Delphi-Hilfe:

Zitat:

Zitat von Delphi-Hilfe
Der Compiler hat einen Unterschied zwischen der Deklaration und der Verwendung einer Prozedur entdeckt.

Delphi-Quellcode:
program Produce;

  type
    ProcedureParm0 = procedure; stdcall;
    ProcedureParm1 = procedure(VAR x : Integer);

  procedure WrongConvention; register;
  begin
  end;

  procedure WrongParms(x, y, z : Integer);
  begin
  end;

  procedure TakesParm0(p : ProcedureParm0);
  begin
  end;

  procedure TakesParm1(p : ProcedureParm1);
  begin
  end;

begin
  TakesParm0(WrongConvention);
  TakesParm1(WrongParms);
end.
Der Aufruf von TakesParm0 löst einen Fehler aus, weil der Typ ProcedureParm0 eine Prozedur stdcall erwartet, während WrongConvention mit der Aufrufkonvention register deklariert wurde. Außerdem wird der Aufruf von TakesParm1 fehlschlagen, weil die Parameterlisten nicht übereinstimmen.

Allerdings kann ich einen solchen Fehler nirgendsfinden...

Chris

d3g 2. Jan 2003 15:41

Hi Chakotay,

das Problem liegt in der Definition von TNotifyEvent:
Delphi-Quellcode:
type
  TNotifyEvent = procedure(Sender: TObject) of object;
Das "of object" ist das Problem, es bedeutet, dass die Prozedur eine Methode einer Klasse sein muss (also sollte sie ein "TForm1." vor dem Namen stehen). Mit Prozeduren innerhalb anderer Prozeduren ist das aber nicht möglich. Ich habe es mit einem schmutzigen Trick versucht:
Delphi-Quellcode:
bButton.OnClick := TNotifyEvent((@bButtonClick)^);
Das führt aber zu einer Access Violation. Dir bleibt wahrscheinlich nichts anderes übrig, als jedes Ereignis als Methode von TForm1 zu deklarieren.

MfG,
d3g

[edit]Die zu große Anzahl an Tippfehlern dezimiert.[/edit]

Chewie 2. Jan 2003 16:05

Zitat:

Zitat von d3g
@Chewie: Das geht nicht, weil die Events vom Typ
Delphi-Quellcode:
type
  TNofifyEvent = procedure(Sender: TObject) of object;
sind. ShowMessage ist aber eine procedure(Text: String) of object.

MfG,
d3g

:oops:
Ja, ist eigentlich logisch. Es erschien mir auch seltsam, aber ich hatte angefangen zu schreiben und keine LList, aufzuhören :wink:


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:48 Uhr.
Seite 1 von 2  1 2      

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