Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Prozedur von einer anderen Unit verwenden


schitho - Fr 06.02.04 22:50
Titel: Prozedur von einer anderen Unit verwenden
Hi,

hab wieder einmal eine typische Anfängerfrage :oops:

Ich habe 2 Formulare (Form1 und Form2) in 2 Units (Unit1 und Unit2).

In Unit1 hab ich eine Prozedur, die ich über die Schaltfläche Button1 starten kann. Dies funktioniert.

Von Form1 möchte ich über eine Schaltfläche Form2 aufrufen. Dies funktioniert auch.

Und nun kommts: Von der Form2 möchte ich über eine Schaltfläche die Prozedure der Unit1 aufrufen. Dies funktioniert nicht :cry:

Hier der Code der Unit1:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation


{$R *.dfm}

uses unit2;

procedure test;
begin
  showMessage('Hallo');
end;

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

procedure TForm1.Button2Click(Sender: TObject);
begin
  Form2.show;
end;

end.


Hier der Code der Unit2:



Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
unit Unit2;

interface

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

type
  TForm2 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

uses unit1;

procedure TForm2.Button1Click(Sender: TObject);
begin
 form1.test;
end;

end.


Beim Versuch das Projekt zu Compilieren erhalte ich folgende Fehlermeldung:

Zitat:
[Fehler] Unit2.pas(30): Undefinierter Bezeichner: 'test'


Was mach ich falsch?

Danke!

Thomas

Moderiert von user profile iconPeter Lustig: Topic verschoben


Christian S. - Fr 06.02.04 23:19

Hallo!

Du hättest auch die Suchfunktion nutzen können, Fragen diesen Typs gibt es sehr oft. Aber hier eine Antwort:

Du hast folgende Fehler gemacht:
(1) Die Prozedur "test" steht nicht im Interface-Teil der Unit1. Das muss sie, damit andere Units überhaupt "wissen", dass es sie gibt.

(2) Wenn Du (1) erledigen willst, musst Du das nicht machen, in dem Du test der Form1 zuordnest. Das heißt, die Funktion kann auch außerhalb von TForm1 deklariert werden und kann (muss) dann nicht mehr über "Form1.Test" sondern nur noch über "Test" aufgerufen werden.

MfG
Peter


schitho - Sa 07.02.04 00:48

Hallo Peter,

die Suche hab ich eh genutzt, allerdings bin ich damit auch nicht wirklich weitergekommen.

Wenn ich im Inteface-Teil der Unit1 die Prozedur ergänze, dann erhalte ich folgende Fehlermeldung:

Zitat:
[Fehler] Unit1.pas(13): Ungenügende Forward- oder External-Deklaration: 'TForm1.test'


Im Interface-Teil hab ich die Prozedur nun so deklariert:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure test;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);

  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;
:
:


Oder hab ich was falsch verstanden???

Gruß
Thomas


broesis - Sa 07.02.04 11:28

Hallo!

Anstatt

Delphi-Quelltext
1:
2:
3:
4:
procedure test; 
begin 
  showMessage('Hallo'); 
end;

muss es

Delphi-Quelltext
1:
2:
3:
4:
procedure tform1.test; 
begin 
  showMessage('Hallo'); 
end;

heißen. Die Deklaration der Prozedur an sich is richtig.
Dann kannst du die Prozedur ganz einfach von Form2 mit form1.test; aufrufen.

Tschau
Broesis


Christian S. - Sa 07.02.04 12:48

Allerdings sehe ich keinen Sinn darin, die Prozedur als Member von TForm1 zu deklarieren.


schitho - Sa 07.02.04 23:26

@ Broesis

Danke! Jetzt funktioniert es.

Gruß
Thomas


Delete - Mo 09.02.04 13:47

alternativ koenntest du die funktion test auch global bekannt machen, wenn sie dir so wichtig ist... in diesem beispiel waer das wohl sogar eher sinnig, da diese "Hallo-Welt"-Anzeige ja nicht unbedingt zu Form1 gehoert....

daher koenntest du


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

procedure test;  {<span style="font-weight: bold">:arrow: globale Definition der Funktion test</span>}

var
  Form1: TForm1;

implementation


{$R *.dfm}

uses unit2;

procedure test;
begin
  showMessage('Hallo');
end;

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

procedure TForm1.Button2Click(Sender: TObject);
begin
  Form2.show;
end;

end.


davon wuerd ich aber allgemein abraten, wenn es sich um "Formularbezogene" Funktionen handelt... oder wenn "sensitive" Daten darin verarbeitet werden....

uruz [/b]