Autor Beitrag
master_mane
Hält's aus hier
Beiträge: 4



BeitragVerfasst: So 18.10.09 13:00 
Code auslagern mit Zugriff auf Objekte der Hauptdatei


Guten Mittag,

Wie man Funktionen/Prozeduren in eine separate Unit auslagert und anschließend einbindet, solange kein Zugriff auf ein Objekt der Hauptdatei besteht, habe ich mittlerweile kapiert.
Wenn ich aber z.B. eine Prozedur auslagern möchte, die eine Buttonbeschriftung ändert, bringt er mir immer Tausende von Fehlern ;)
Diese kann ich dann durch einbinden der Type-Deklaration und Co, was ja eigentlich logisch ist, soweit reduzieren, dass Borland nurnoch über i.eine forward oder external Deklaration der Prozedur bzw. Funktion mekert.
Ich weiß nicht, ob mein Ansatz korrekt ist, und wie man es richtig macht.

Codebeispiel Hauptdatei:
ausblenden volle Höhe 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:
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    btn_click: TButton;
    procedure btn_clickClick(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.btn_clickClick(Sender: TObject);
begin
  ChangeCaption();
end;

end.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
procedure ChangeCaption();
begin
  btn_click.Caption := 'klick mich';
end;

Es soll beim Klicken auf den Button "btn_klick" die Prozedur "ChangeCaption" aus Unit2 aufgerufen werden.

Was muss ich in Unit1, was in Unit2 schreiben, dass das Ganze funktioniert wie es soll?
Codebeispiele wären sehr Hilfreich!

Vielen Dank,
Manuel
Jakob_Ullmann
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1747
Erhaltene Danke: 15

Win 7, *Ubuntu GNU/Linux*
*Anjuta* (C, C++, Python), Geany (Vala), Lazarus (Pascal), Eclipse (Java)
BeitragVerfasst: So 18.10.09 13:50 
Du müsstest logischerweise, da Form1.Button1 in Unit1 definiert ist, Unit1 in Unit2 einbinden, da in Unit2 auf Unit1.Form1.Button1 zugegriffen wird. Genauso wird in Unit1 auf Unit2.ChangeCaption zugegriffen. Dafür gibt es eine uses-Klausel im interface-Teil und eine uses-Klausel im implementation-Teil (Unit2):

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
unit Unit1

interface

uses
  SysUtils, ..., Unit2, ...;

...

implementation

...

  ChangeCaption;

...


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

interface

uses
  SysUtils, ...;

...

implementation

uses
  Unit1

...

procedure ChangeCaption;
begin
  ...
end;
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19312
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 18.10.09 13:55 
Besser wäre es aber alles was in den ausgelagerten Routinen benötigt wird auch mitzugeben. Sonst wird das schnell sehr unübersichtlich, wenn von überall auf irgendetwas zugegriffen wird...
master_mane Threadstarter
Hält's aus hier
Beiträge: 4



BeitragVerfasst: So 18.10.09 14:01 
Danke, Jakob!
Zumindest einmal die "forward"-Fehlermeldungen bleiben aus, allerdings sagt er jetzt bei mir "[Fehler] Unit1.pas(29): Undefinierter Bezeichner: 'ChangeCaption'"...

Und wie macht man das, jaenicke?

Danke für die Antworten!

Lieben Gruß,
Manuel
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19312
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 18.10.09 14:04 
user profile iconmaster_mane hat folgendes geschrieben Zum zitierten Posting springen:
Und wie macht man das, jaenicke?
Wie genau das sinnvoll ist kommt auf den genauen Anwendungszweck an. Man kann für Statusausgaben zum Beispiel eine Callback-Routine einbauen, aber ich glaube für dich reicht das so:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
procedure ChangeCaptionExample(AButton: TButton; ANewCaption: String);
begin
  AButton.Caption := ANewCaption;
end;
So kannst du zusätzlich zu dem was du sonst brauchst auch die Komponente mitgeben und kannst das dann universell verwenden. Denn du kannst ja verschiedene Buttons übergeben und es wird immer klappen. Und du musst nicht wissen welcher Button darin verändert wird, da du ihn angibst.
Jakob_Ullmann
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1747
Erhaltene Danke: 15

Win 7, *Ubuntu GNU/Linux*
*Anjuta* (C, C++, Python), Geany (Vala), Lazarus (Pascal), Eclipse (Java)
BeitragVerfasst: So 18.10.09 14:07 
Ja, das wäre eine Möglichkeit.

Ich muss gestehen, dass ich einen Fehler gemacht habe: Wenn man das ChangeCaption auch außerhalb von Unit2 verwenden will, schreibt man das noch bei interface mit rein:

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

interface

uses
  SysUtils, ...;

procedure ChangeCaption; // bzw. mit Argumenten, falls vorhanden

implementation

uses
  Unit1

procedure ChangeCaption; // bzw. mit Argumenten
begin
  ...
end;

end.
master_mane Threadstarter
Hält's aus hier
Beiträge: 4



BeitragVerfasst: So 18.10.09 14:19 
Parameter zu verwenden ist natürlich noch besser! Danke, das werde ich machen!

Jetzt sagt Borland allerdings in Unit2, der Button (bzw. bei Parameterübergabe der TButton) wäre ein "undefinierter Bezeichner"...

Liebe Grüße,
Manuel
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19312
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 18.10.09 14:23 
Halte einmal die Maus in der Formularunit über TButton, dann siehst du (bei einigermaßen modernen Delphiversionen), dass der in der Unit StdCtrls deklariert ist. Also musst du in der anderen Unit die StdCtrls ebenfalls in die uses legen.
Jakob_Ullmann
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1747
Erhaltene Danke: 15

Win 7, *Ubuntu GNU/Linux*
*Anjuta* (C, C++, Python), Geany (Vala), Lazarus (Pascal), Eclipse (Java)
BeitragVerfasst: So 18.10.09 14:29 
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Halte einmal die Maus in der Formularunit über TButton, dann siehst du (bei einigermaßen modernen Delphiversionen)


Bei älteren Versionen kann man auch einfach TButton in der Hilfedatei suchen.
master_mane Threadstarter
Hält's aus hier
Beiträge: 4



BeitragVerfasst: So 18.10.09 14:45 
Dankeschön euch Beiden :)
Es funktioniert einwandfrei.
Schön, dass ihr so viel Geduld mit mir hattet.

Lieben Gruß,
Manuel