Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Procedure TForm.xyz in Unit (https://www.delphipraxis.net/111114-procedure-tform-xyz-unit.html)

Fussball-Robby 29. Mär 2008 20:02


Procedure TForm.xyz in Unit
 
Hey, ich möchte mit eine Unit erstellen, in die ich alle möglichen Funktionen und Prozeduren packe. Diese Unit will ich dann unter uses eintragen, damit ich sie in meinen Projekten nutzen kann. Wie das geht, weiß ich auch. Ich habe nun aber ein anderes Problem.
Ich muss die Funktionen ja im Interface-Abschnitt deklarieren und in den Implementations-Abschnitt reinschreiben. Wenn ich jetzt aber z.B. so eine Prozedur machen will:
Delphi-Quellcode:
Procedure TForm.xyz(S: String);
begin
end;
Wie muss ich die dann oben deklarieren? Wenn ich jetzt Procedure TForm.xyz(S: String); in den Interface-Teil reinschreibe, klappt das nämlich nicht.
Hoffe, ihr könnt mir helfen.

Mfg

MrKnogge 29. Mär 2008 20:07

Re: Procedure TForm.xyz in Unit
 
Du kannst eine Klassen-Funktion nur in der Unit implementieren, in der die Klasse deklariert ist.

Fussball-Robby 29. Mär 2008 20:08

Re: Procedure TForm.xyz in Unit
 
Das heißt, es gibt keine Möglichkeit, eine solche Prozedur in eine Unit zu tun, ohne TForm zu deklarieren?

Noobinator 29. Mär 2008 20:08

Re: Procedure TForm.xyz in Unit
 
eine andere Frage: wieso willst du denn deine Proceduren als Methoden der Form implementieren?

mkinzler 29. Mär 2008 20:09

Re: Procedure TForm.xyz in Unit
 
Delphi unterstütz )noch) keine partielle Klassen. Alle Methoden müssen in der selben Unit deklariert werden.

Fussball-Robby 29. Mär 2008 20:11

Re: Procedure TForm.xyz in Unit
 
Zitat:

Zitat von Noobinator
eine andere Frage: wieso willst du denn deine Proceduren als Methoden der Form implementieren?

Da ich in manchen Prozeduren z.B. die Funktion ScreenToClient() benutze, für die ich eine TForm brauche, und ich will die Form ungerne als Parameter mitgeben.

Noobinator 29. Mär 2008 20:15

Re: Procedure TForm.xyz in Unit
 
Zitat:

Zitat von Fussball-Robby
Zitat:

Zitat von Noobinator
eine andere Frage: wieso willst du denn deine Proceduren als Methoden der Form implementieren?

Da ich in manchen Prozeduren z.B. die Funktion ScreenToClient() benutze, für die ich eine TForm brauche, und ich will die Form ungerne als Parameter mitgeben.

Dann realisieren das ganze doch einfach über einen Kreuzbezug.
Deine Formdeklaration ist doch bereits im interface teil.

Fussball-Robby 29. Mär 2008 20:21

Re: Procedure TForm.xyz in Unit
 
Zitat:

Zitat von Noobinator
Deine Formdeklaration ist doch bereits im interface teil.

Nein, ist sie ja eben nicht, da ich eine einfache Unit OHNE Form habe.

Noobinator 29. Mär 2008 20:27

Re: Procedure TForm.xyz in Unit
 
deine Main Unit sieht doch wie folgt aus:

Delphi-Quellcode:
unit Mainunit;

interface

uses unit2; //hier ein Uses auf deine unit2

type
  TForm1 = class(TForm)
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;// globale Formvariable im interface teil

implementation

{$R *.dfm}
deine neue Unit so:

Delphi-Quellcode:
unit Unit2;

interface

implementation
uses Mainunit;//hier ein uses auf deine mainunit;

end.
wenn du das so machst, dann hast du einen Kreuzbezug zwischen deiner Mainunit und der Unit2.
D.H. beide Units greifen aufeinander zu.

Jetzt ist in deiner Mainunit ja
Delphi-Quellcode:
var:form1:Tform1;
im interface teil, und damit kannst du dank Kreuzbezug direkt drauf zugreifen, auch aus der Unit2 ;)

ich finde diese Lösung jedoch ziemlich bescheiden.
Denn wozu mache ich ne Modulare Unit, wenn beide alles kennen ;)
da kann man es gleich in eine Unit schreiben.

Fussball-Robby 29. Mär 2008 20:31

Re: Procedure TForm.xyz in Unit
 
Ok, so geht es natürlich. Ich will aber, wie im ersten Post beschrieben, eine einzelne Unit schreiben, die ich dann in alle Projekte einbinden will, um die Funktionen nicht jedesmal kopieren zu müssen. D.h., meine Unit muss eigenständig laufen, ohne irgendeine MainUnit.

Mfg

mkinzler 29. Mär 2008 20:33

Re: Procedure TForm.xyz in Unit
 
Dann verwende Vererbung oder die Objektablage.

Fussball-Robby 29. Mär 2008 20:42

Re: Procedure TForm.xyz in Unit
 
Und wie geht das?

mkinzler 29. Mär 2008 20:46

Re: Procedure TForm.xyz in Unit
 
Vererbung?
Oder die Objektablage?

Fussball-Robby 29. Mär 2008 20:50

Re: Procedure TForm.xyz in Unit
 
Zitat:

Zitat von mkinzler
Vererbung?
Oder die Objektablage?

Kommt drauf an, was in diesem Fall geeigneter ist :wink:

mkinzler 29. Mär 2008 20:52

Re: Procedure TForm.xyz in Unit
 
Du könntest dir eine eigene Formklasse ableiten und deine Formulare von dieser ableiten.

Fussball-Robby 29. Mär 2008 21:01

Re: Procedure TForm.xyz in Unit
 
Also in meiner Unit so:
Delphi-Quellcode:
interface

type
  TUForm = class(TForm)
    Procedure xyz(S: String);
  end;


implementation

Procedure TUForm.xyz(S: String);
begin
end;
Und im Projekt:
Delphi-Quellcode:
Uses UMyCodes;
//[..]
type
  TForm1 = class(TUForm)
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;
Stimmt das so?

mkinzler 29. Mär 2008 21:02

Re: Procedure TForm.xyz in Unit
 
Ja. Bei neueren Delphiversionen könntest du auch einen ClassHelper verwenden.

Fussball-Robby 29. Mär 2008 21:05

Re: Procedure TForm.xyz in Unit
 
Gibts bei Delphi 5 bestimmt mal wieder noch nicht :wink:
Danke, für die Hilfe, ich werds jetzt so machen.

Mfg

mkinzler 29. Mär 2008 21:13

Re: Procedure TForm.xyz in Unit
 
Nein, erst ab D10.

Fussball-Robby 30. Mär 2008 08:48

Re: Procedure TForm.xyz in Unit
 
Ich hab noch eine klitzekleine Frage :wink:
Ich hatte ja jetzt das hier in meiner Unit:
Delphi-Quellcode:
Type
  TUForm = class(TForm);
    Procedure xyz //[..]
Das hat natürlich den Nachteil, dass ich in jedem Projekt die Form von TUForm ableiten müsste. Ich hab jetzt mal das ausprobiert:
Delphi-Quellcode:
Type
  TUForm = class(TForm);
  TForm = class(TUForm)
    Procedure xyz //[..]
Und das funktioniert so. Die Unit lässt sich kompilieren und ich kann die Funktionen aus der MainUnit mit einer ganz normalen TForm nutzen. Kann ich das so machen, oder gibts da irgebndwelche Nachteile/Fehlverhalten?

Mfg

Edit: Fipptehler :wink:

Noobinator 30. Mär 2008 09:08

Re: Procedure TForm.xyz in Unit
 
Zitat:

Zitat von Fussball-Robby
...
Delphi-Quellcode:
Type
  TUForm = class(TForm);
  TForm = class(TUForm)
    Procedure xyz //[..]
....

hääh :gruebel:

Tuform ist von Tform abgeleitet, und Tform wieder vom Tuform?

sehe ich das jetzt richtig oder ist meine Morgenmüdigkeit noch zu massiv zum denken?

Fussball-Robby 30. Mär 2008 16:00

Re: Procedure TForm.xyz in Unit
 
Ja, du siehst das richtig, hat aber auch nen simplen Grund. Im Hauptformular ist die Form1 von TForm abgeleitet. Das heißt, die Funktionen der anderen Unit, die von dieser Form genutzt werden sollen, müssen in einer Klasse stehen, die ebenfall von TForm abgeleitet ist und dazu noch den Namen TForm haben muss. Da ich aber TForm nicht von TForm ableiten kann, mache ich es eben über TUForm.

mkinzler 30. Mär 2008 16:03

Re: Procedure TForm.xyz in Unit
 
Aber du leitest eine Klasse mit der Bezeichnung TForm wieder davon ab.

Fussball-Robby 30. Mär 2008 16:09

Re: Procedure TForm.xyz in Unit
 
Wenn ich es so belassen würde:
Delphi-Quellcode:
Type
  TUForm = class(TForm)
    Procedure xyz //[..]
Dann müsste ich in der MainUnit das Formular von TUForm ableiten. Füge ich aber die 2. Ableitung in der Unit hinzu, kann ich in der MainUnit das Formular ganz normal lassen und muss da nichts ändern.

mkinzler 30. Mär 2008 16:56

Re: Procedure TForm.xyz in Unit
 
Aber so erbt Formx nicht deine Erweiterungen.

Fussball-Robby 30. Mär 2008 17:00

Re: Procedure TForm.xyz in Unit
 
Zitat:

Zitat von mkinzler
Aber so erbt Formx nicht deine Erweiterungen.

Doch, sonst hätte ich es erst garnicht so gemacht :wink:

Tharon 30. Mär 2008 18:10

Re: Procedure TForm.xyz in Unit
 
Puuuhhh... also ich glaube, hier wird völlig aneinander vorbei geredet... und anscheinend wurde auch das eigentliche Problem gar nicht verstanden :wink:

Also... zunächst mal geht es doch darum, eine allgemein verwendbare Funktion in einer Bibliotheksunit unterzubringen. Derartige Funktionen werden nicht als Methoden (einer Klasse), sondern als ganz normale (öffentliche) Funktionen/Prozeduren implementiert:

Delphi-Quellcode:

interface

procedure xyz(s: String);


implementation

procedure xyz(s: String);
begin
  ...
end;
Das "TForm." vor dem Prozedurnamen "xyx" war also der Fehler.

Wir wissen jetzt natülrlich nicht, was diese Prozedur eigentlich tun soll... aber falls diese Prozedur etwas mit einem Formular tun soll, dann muss natürlich dieses Formular als Argument übergeben werden:

Delphi-Quellcode:
unit LibFormUtils;

uses
  Forms;


interface

procedure LibFormXYZ(a_frm: TForm; a_sText: String);


implementation

procedure LibFormXYZ(a_frm: TForm; a_sText: String);
begin
  ...
end;
Diese Prozedur kann dann mit jedem beliebigen Formular aufgerufen werden, und zwar egal von welcher Klasse dieses Formular abgeleitet ist und egal, wie dieses Formular heißt.

Der Aufruf kann so aussehen:

Delphi-Quellcode:
unit formMain;

interface

type

TfrmMain = class(TForm)
  ...
  private
    procedure XXXX;
  ...
end;

...


implementation

uses
  LibFormUtils;


procedure TfrmMain.XXXX;
begin
  ...
  LibFormXYZ(Self, 'Ein Text');
  ...
end;
Nebenbei bemerkt, muss diese Prozedur auch nicht unbedingt aus einer Methode einer Formularklasse heraus aufgerufen werden, wie in diesem Beispiel. Eine solche Funktion/Prozedur ist universell verwendbar, aus jedem beliebigen Kontext heraus (natürlich darf dann nicht "Self" als Argument übergeben werden, sondern die betreffende Formularvariable). Und darum ging es doch... eine universelle Funktion/Prozedur zu implementieren, die überall verwendbar ist :wink:

mkinzler 30. Mär 2008 18:13

Re: Procedure TForm.xyz in Unit
 
Nein er wollte Methoden der Form extern einbinden.

Tharon 30. Mär 2008 18:37

Re: Procedure TForm.xyz in Unit
 
@mkinzler:
Ich glaube, er meinte genau das, was ich beschrieben habe:

Zitat:

Hey, ich möchte mit eine Unit erstellen, in die ich alle möglichen Funktionen und Prozeduren packe. Diese Unit will ich dann unter uses eintragen, damit ich sie in meinen Projekten nutzen kann.
Eine partielle Klasse macht hier doch auch überhaupt keinen Sinn, denn das Endergebnis wäre ja genau eine Klasse, "xyz" wäre also eine Methode genau dieser einen Klasse - es soll aber doch eine allgemein verwendbare Prozedur sein. Mal abgesehen davon, dass das in Delphi sowieso nicht geht :wink:

Ein Problem kam nur dadurch zustande (und damit die ganze Diskussion), weil er fälschlicherweise (vielleicht auch nur versehentlich) "TForm1." vor den Prozedurnamen geschrieben hat - vielleicht weil er dachte, er könnte diese Prozedur sonst nicht in seinem Formular verwenden...

Falls Robby aber eigentlich die Basisklasse seiner Formulare erweitern wollte, dann muss er eine neue Klasse, die von TForm abgeleitet ist mit dieser Prozedur implementieren und seine Formulare dann von dieser neuen eigenen Basisklasse ableiten:

Delphi-Quellcode:

unit LibForm;

uses
  Forms;


type

TLibForm = class(TForm)
  ...
  procedure XYZ(a_sText: String);
  ...
end;


----------------------------------------

unit formMain;

uses
  LibForm;


type

TfrmMain = class(TLibForm)
  ...
end;

...


implementation


TfrmMain.XXXX;
begin
  ...
  XYZ('Ein Text');
  ...
end;
Aber wir sollten hier jetzt vielleicht nicht weiter darüber diskutieren, was Robby jetzt vielleicht tatsächlich gemeint haben könnte... das sollte er selbst am besten wissen und ich denke, er hat jetzt alle nötigen Infos :wink:

mkinzler 30. Mär 2008 18:52

Re: Procedure TForm.xyz in Unit
 
So ist das Problem vielleicht auch gelöst, aber doch recht umständlich, denn wenn er jede Methode händisch anpassen muss, könnte er auch gleich den Code direkt reinkoppieren.

Fussball-Robby 30. Mär 2008 19:00

Re: Procedure TForm.xyz in Unit
 
So, jetzt wurde hier mal genug spekuliert, was ich wissen wollte :wink:
Im Prinzip will ich das machen, was im letzten Beispiel hier gezeigt wurde. Das mit der abgeleiteten Formklasse hatte ich ja auch so gemacht. Jetzt will ich aber in der MainUnit nicht jedesmal das Formular von dieser neuen Klasse ableiten, deshalb hatte ich in der LibUnit eine Ableitung einer Ableitung von TForm gemacht, sodass die neue Klasse TForm hieß und ich in der MainUnit nichts mehr ableiten musste. Das hat dann auch geklappt. Denn dadurch, dass die doppelt abgeleitete Klasse nun TForm heißt, muss ich in der MainUnit nichts mehr ableiten.
Ich habs jetzt so gemacht:
Delphi-Quellcode:
Unit LibUnit;

uses
  Forms;


type
  TUForm = class(TForm);
  TForm = class(TUForm)
    ..
    Procedure xyz(S: String);
    ..
  end;

------------

Unit MainForm;

uses
  LibUnit;

type
  TForm1 = class(TForm)
  ...
  ...
  end;

var
  Form1: TForm1;

implementation

procedure TForm1.Button1Click(Sender: TObject);
begin
  xyz('A');
end;
Auch, wenn das mit der doppelten Ableitung komisch aussieht, es funktioniert. Meine Frage war jetzt eigentlich nur, ob es irgendwie einfacher geht bzw. ob diese Lösung in irgendeiner Weise Probleme machen könnte.

Mfg

mkinzler 30. Mär 2008 19:09

Re: Procedure TForm.xyz in Unit
 
Wie beschrieben ist es ab D10 möglich einen Class-Helper zu implementieren, und damit die Klasse ohen Ableitung zu erweitern.

Fussball-Robby 30. Mär 2008 19:11

Re: Procedure TForm.xyz in Unit
 
Das hilft mir aber nicht weiter :wink:
Also so wie ich das jetzt bisher mitbekommen habe, gibts dafür keine bessere Lösung. Dann werd ich das so lassen. Bin für Verbesserungsvorschläge aber trotzdem offen.

Mfg

mkinzler 30. Mär 2008 19:14

Re: Procedure TForm.xyz in Unit
 
Doch auf eine neuere Delphiversion umsteigen. TDE kann viel mehr als D5 Std

Fussball-Robby 30. Mär 2008 19:26

Re: Procedure TForm.xyz in Unit
 
Zitat:

Zitat von mkinzler
Doch auf eine neuere Delphiversion umsteigen. TDE kann viel mehr als D5 Std

Wäre natürlich eine Idee, hilft mir im Moment aber auch nicht. Ich wollte mir sowieso bald eine neue Version holen.
Danke für die Hilfe

Mfg


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