Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Code aus Button in andere unit auslagern (https://www.delphipraxis.net/85313-code-aus-button-andere-unit-auslagern.html)

moperswings 29. Jan 2007 08:41


Code aus Button in andere unit auslagern
 
Hallo,

wenn ich einen Button in einer Form habe und möchte übersichtshalber den Code in eine seperate unit auslagern, wie mache ich das? Es gibt doch bestimmt so einen Befehl wie bei php die include()-Funktion, die ich zwischen procedure begin und end einfügen kann? Wenn es doch mit uses gehen sollte, wie muss ich meinen Code dann deklarieren?

Hoffe, Ihr könnt mir helfen!

Viele Grüsse, moperswings

Masterof 29. Jan 2007 08:43

Re: Code aus Button in andere unit auslagern
 
Hallo!

meines Wissens nach musst du in deiner Funktion "Buttonclick" eine andere Funktion in aufrufen, und die entsprechenden Parameter übergeben.
Das es sowas wie "include" gibt ist mir nicht bekannt, weil du die Units ja oben im Kopf einbindest.

Gruß Master

mkinzler 29. Jan 2007 08:47

Re: Code aus Button in andere unit auslagern
 
Einfach die Event-Property (.onClick) auf Methode der Klasse in anderer Unit setzen.

moperswings 29. Jan 2007 09:05

Re: Code aus Button in andere unit auslagern
 
@mkinzler

Und wie mache ich das?

mkinzler 29. Jan 2007 09:08

Re: Code aus Button in andere unit auslagern
 
Unit2:
Delphi-Quellcode:
 ...
  procedure c1.ButtonClick( Sender: TObject);
 ...
Uni1:
Delphi-Quellcode:
 ...
  implementation
  uses Unit2;
  ...
  Form1.Button1.onClick = c1.ButtonClick;

moperswings 29. Jan 2007 09:49

Re: Code aus Button in andere unit auslagern
 
hmm, ich krieg das nicht hin!

unit1
Delphi-Quellcode:
procedure Button1.onClick (Sender: TObject);

implementation
uses unit2;

procedure Button1.onClick (Sender: TObject);
begin
      Form1.Button1.onclick = c1.ButtonClick;
end;
unit2
Delphi-Quellcode:
procedure c1.ButtonClick(Sender: TObject);
begin
   Form1.Color := clred;
end;
Wo ist der Fehler?

Phoenix 29. Jan 2007 09:51

Re: Code aus Button in andere unit auslagern
 
Was sagt denn der Compiler? Der gibt Dir bei DEM Code unter Garantie eine Meldung, die Dir genau sagt was Du da nicht richtig gemacht hast.

mkinzler 29. Jan 2007 09:56

Re: Code aus Button in andere unit auslagern
 
procedure Button1.onClick (Sender: TObject);
procedure Button1.onClick (Sender: TObject);
begin
Form1.Button1.onclick = c1.ButtonClick;
end;

Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
begin
    Button1.onClick := c1.ButtonClick;
end;

moperswings 29. Jan 2007 10:35

Re: Code aus Button in andere unit auslagern
 
In unit2 sieht es so aus:
Delphi-Quellcode:
procedure cl.Button(Sender: TObject);
begin
    Form1.Color := clred;
end;
Fehlermeldung:
Bei der procedure ; erwartet aber , gefunden
Form1 und clred sind undefinierte Bezeichner
Unit1 gibt keine Fehlermeldung zurück

Michael80 29. Jan 2007 10:36

Re: Code aus Button in andere unit auslagern
 
Irgendwie blick ich den Sinn hier net ganz.

wieso nicht einfach

unit1 = Form1 ??
Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, System.ComponentModel, Borland.Vcl.StdCtrls;

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

var
  Form1: TForm1;

implementation
uses Unit2;
{$R *.nfm}

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

end.
unit2
Delphi-Quellcode:
procedure Button1Click(Sender: TObject);
implementation
uses Unit1;
procedure Button1Click(Sender: TObject);
begin
   Form1.Color := clred;
end;
end.

mkinzler 29. Jan 2007 10:49

Re: Code aus Button in andere unit auslagern
 
Zitat:

Zitat von moperswings
In unit2 sieht es so aus:
Delphi-Quellcode:
procedure cl.Button(Sender: TObject);
begin
    Form1.Color := clred;
end;
Fehlermeldung:
Bei der procedure ; erwartet aber , gefunden
Form1 und clred sind undefinierte Bezeichner
Unit1 gibt keine Fehlermeldung zurück

Dann muß es
1. auch
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
  begin
      Button1.onClick := c1.Button;
  end;
heißen, wenn auch button ein erdenklich schlecher Namen einer Methode ist und
2. die entsprechende Klasse samt Methode deklariert sein.

Michael80 29. Jan 2007 11:05

Re: Code aus Button in andere unit auslagern
 
Zitat:

Zitat von moperswings
In unit2 sieht es so aus:
Delphi-Quellcode:
procedure cl.Button(Sender: TObject);
begin
    Form1.Color := clred;
end;
Fehlermeldung:
Bei der procedure ; erwartet aber , gefunden
Form1 und clred sind undefinierte Bezeichner
Unit1 gibt keine Fehlermeldung zurück

Du musst auch in der neuen Unit2 die ganzen sachen Deklarieren

wie hier z.B.

Delphi-Quellcode:
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,
  Dialogs, System.ComponentModel, Borland.Vcl.StdCtrls;
was du noch weglassen kannst, musst schauen, weiß ich etz net auswendig

SirThornberry 29. Jan 2007 11:29

Re: Code aus Button in andere unit auslagern
 
Zitat:

Zitat von Masterof
Hallo!

meines Wissens nach musst du in deiner Funktion "Buttonclick" eine andere Funktion in aufrufen, und die entsprechenden Parameter übergeben.
Das es sowas wie "include" gibt ist mir nicht bekannt, weil du die Units ja oben im Kopf einbindest.

Gruß Master

Sowas wie Include gibt es auch unter Delphi
Delphi-Quellcode:
{$I einzubindendeDatei.inc}

moperswings 29. Jan 2007 13:15

Re: Code aus Button in andere unit auslagern
 
Hallo,

DANKE AN ALLE, jetzt weiss ich, wie das Prinzip funktioniert!

Viele Grüsse, moperswings

moperswings 29. Jan 2007 14:29

Re: Code aus Button in andere unit auslagern
 
Nachfrage:

Ein Problem ist mir unangenehm aufgefallen, was ich Aufgrund meines einfaches Beispiels gar nicht gemerkt habe. Vor jede Komponente muss man - wenn sie denn so heißt - Form1. davorschreiben!
Gibt es da nicht noch eine Möglichkeit, die Form1 so in die unit einzubinden, dass sie für alle Komponenten des Formulars gültig ist?

Viele Grüsse, moperswings

SirThornberry 29. Jan 2007 14:36

Re: Code aus Button in andere unit auslagern
 
Form1 musst du nur davor schreiben wenn du explzit diese Instanz ansprechen willst. Wenn ein Member von (in deinem Fall) TForm1 angesprochen werden soll braucht man das nicht davor schreiben. Wenn du aber außerhalb der Klasse auf eine Variable, Member, etc. zugreifen willst muss logicher Weise die Instanz benannt sein da sonst nicht eindeutig ist welche Instanz von TForm1 du ansprechen willst.

Michael80 29. Jan 2007 14:38

Re: Code aus Button in andere unit auslagern
 
IMHO musst du immer das Form1. davor schreiben, weil du ja in jeder Unit z.B.
ein Edit1 oder einen Button1 haben kannst, und sonst Delphi das ja net referenzieren kann

moperswings 29. Jan 2007 14:59

Re: Code aus Button in andere unit auslagern
 
Ok, dann bedanke ich mich nochmal bei Dir Michael80 für das gute Beispiel.
Das wird bestimmt auch noch einmal anderen Nutzern helfen.

Vielen Dank und Grüsse!

omata 29. Jan 2007 15:17

Re: Code aus Button in andere unit auslagern
 
Hallo,

findet ihr diese Vorgehenweise wirklich gut?

Wenn diese ButtonClick-Routine sehr groß ist (viele Zeilen enthält), würde ich vielleicht diese Befehle in eine Prozedur auslagern und diese dann in eine andere Unit schreiben.

Die Anspielung auf den Zugriff auf Form1 lässt ja nur den Schluss zu, dass hier ein Zirkelschluss über die Units gemacht wird. Also mal ehrlich, ich finde diese Hinweise nicht sehr sinnvoll. Klar kann man so programmieren. Aber sauber ist das nicht, hier wird gar keine ordentliche Schnittstelle zwischen den Units definiert.
Wenn ein Zugriff auf die Elemente eines Formulars von nöten ist und eine logische Trennung zwischen den Elementen auf dem Formular realisiert werden soll, weil die Logik die da hintersteckt sehr aufwendig und lang ist. Dann würde ich zumindest mal erwähnen, das es auch Frames gibt.

Gruss
Thorsten

SirThornberry 29. Jan 2007 15:22

Re: Code aus Button in andere unit auslagern
 
Zitat:

Zitat von Michael80
IMHO musst du immer das Form1. davor schreiben, weil du ja in jeder Unit z.B.
ein Edit1 oder einen Button1 haben kannst, und sonst Delphi das ja net referenzieren kann

Das ist so nicht korrekt. Grund ist das von der Klasse mehrere Referenzen existieren können:
Delphi-Quellcode:
Form1 := TForm1.Create(nil);
Form2 := TForm1.Create(nil);
Bei diesem Beispiel wurde das Formular 2 mal erzeugt aber jeweils anderen Instanzzeigern zugewiesen. In diesem Fall wäre jetzt ohne "Form1." nicht herleitbar welches der beiden gleichaussehenden Formularinstanzen gemeint ist.
Allerdings zeigt dies auch das es nicht empfehlenswert ist über die Instanzvariable zu gehen sondern man sollte Objectorientiert arbeiten. Alles was zu diesem Object gehört sollte auch in einer Methode des Objectes sein und nicht in einer globalen Funktion oder dergleichen.

moperswings 29. Jan 2007 15:29

Re: Code aus Button in andere unit auslagern
 
Könnt Ihr dann nicht einmal - für alle - ein Bsp. schreiben, wie die "beste" Lösung für dieses Problem aussehen würde. Ich bin ja bestimmt nicht der einzige, der viel Code in einer Unit vermeiden möchte, um den Durchblick zu behalten!

omata 29. Jan 2007 16:00

Re: Code aus Button in andere unit auslagern
 
Hallo,

ich bin ja eigentlich auch ein grosser Freund von Beispielen. Aber hier liegt die Sache etwas anders. Es gibt verschiedene Wege, das liegt am jeweiligen Problem. Es gibt hier nicht unbedingt die Lösung.

Aber es gibt auf jeden Fall eine Sache, die man auf jeden Fall einhalten sollte. Keine Zirkelschlüsse, das ist das Wichtigste. Und auch nicht mal kurz, um mal eben etwas zutesten. Klare Antwort: nein. Sag einfach nein, mach dein Gehirn an und überlege erst, bevor du anfängst. Wenn man einen Zirkelschluss braucht, hat man schon etwas falsch gemacht, so einfach ist das.

Nun ist es natürlich so, das ein Programm langsam immer größer wird und irgendwann erkennt man dann, dass man die Übersicht verliert. Eigentlich sollte man schon gleich anfangen und richtig sortieren bzw. auslagern. Ok, manchmal ist man selber überrachst, was da noch alles dazukommt.

Trotzdem der einfachste Weg ist immer noch Trennung von Eingabe, Verarbeitung und Ausgabe (eben EVA). Alles was mit der Verarbeitung zu tun hat, hat nichts in einer Formularunit zu suchen. Diese Routinen sollte man auslagern. In der Formularunit werden dann die Inhalte aus den Formularelementen an diese Routinen übergeben. So einfach kann das sein.
Und jetzt kommt mir nicht mit irgendwelchen konstruierten Beispielen, dann dafür gibt es auch immer ein ordentliches Beispiel.

Eigentlich sollten diese Vorgehenweisen schon zum Erfolg führen. Allerdings gibt es eben auch hier wieder Ausnahmen. Und ab Delphi5 gibt es eben auch für diese Ausnahmen noch eine weitere Möglichkeit. Nämlich Frames. Da kann man eben auch noch sein Formular in logische Bereiche unterteilen, die dann jeweils eine eigene Unit bekommen.
Und wenn man dann beide Vorgehenweisen ausgiebig nutzt, sollte man keine Platzprobleme mehr haben.

Wie gesagt, Beispiel ist zwar möglich. Aber es gibt nicht das Beispiel für alles was auftreten kann. Vielleicht kannst du noch etwas konkreter werden, dann werde ich es eventuell auch :zwinker:

Gruss
Thorsten

moperswings 29. Jan 2007 16:10

Re: Code aus Button in andere unit auslagern
 
Ich arbeite an einem Fragebogen, benutze ein Form und meine Fragen bringe ich TabSheets unter.
Speichern möchte ich das ganz als *.csv um die Daten in SPSS zu importieren. Beim Speichern sammeln sich meine Komponenten in der writeln an und deshalb wollte ich den Inhalt meiner Speicher-Buttons auslagern.
Das ist im Moment das Problem, vor dem ich stehe!

omata 29. Jan 2007 16:38

Re: Code aus Button in andere unit auslagern
 
Wie sieht den deine Datenstruktur aus?

moperswings 29. Jan 2007 16:44

Re: Code aus Button in andere unit auslagern
 
Ich gehe halt von Tabsheet zu TabSheet, Frage meine Antworten ab und am Ende wird das ganze in iener Zeile gespeichert. Der nächste Datensatz wird dann angehangen. Ich habe ca. 50 Radiogroups, 20 Edit, 20 Memos und 4 Checkboxen aus denen sich ein Datensatz zusammensetzt.

omata 29. Jan 2007 17:16

Re: Code aus Button in andere unit auslagern
 
Das heisst also du hast deine Fragen da fest reingemeisselt.
Du hast dir also keine Gedanken gemacht, was für Antworten es so geben könnte.
Also zum Beispiel: Einfache Antwort (ja/nein), Mehrfachauswahl (Radiobutton, Checkbox), Kreuzungstabellen, Freie Eingabe, ...
Also eine Struktur die dir deine Frage + Antwortmöglichkeiten zusammenbaut.
Damit ist dein Fragebogen aber ziemlich festgenagelt. Was ist wenn dir morgen noch eine Frage einfällt? Dann machst du ein neues TabSheets auf und baust dir dafür auch wieder alles zusammen? Findest du das elegeant?
Wäre es nicht sinnvoller eine Datei mit Fragen zuhaben. Diese Datei müsste dann auch den Frage-Typ beinhalten und eventuell die möglichen Antworten. Vermutlich würde sich da eine einfache XML-Struktur für eignen. Wie sieht den die Datei aus, die du an SPSS geben möchtest? So weit ich weiss sind da die Antworten die Spalten und die Zeilen sind die Einzelnen Personen.
Da stellt sich mir dann gleich die Frage, wie bzw. wann du deine Einzelnen Antwortzeilen speicherst? Und an dieser Stelle schliesst sich der Kreis und wir sind wieder bei dir Frage, wie deine Datenstruktur aussieht? Zur Zeit denke ich hast du keine.

Stimmen meine Annahmen soweit...

Gruss
Thorsten

moperswings 30. Jan 2007 14:47

Re: Code aus Button in andere unit auslagern
 
Der Begriff "fest reingemeisselt" gefällt mir sehr gut.
Also, meine Fragen stehen!
Ich gehe Tabsheet für Tabsheet durch. Meine Antwortmöglichkeiten sind durch Radiogroups vorgegeben und für freie Antworten benutze ich Edits oder Memos, je nach dem, was ich brauche. Speichern mache ich ganz klassisch mit writeln.
Das alles funktioniert ja auch soweit! Das Problem ist nur, das ich jetzt 1000 Zeilen in einer unit habe und deshalb wollte ich den Code auslagern. Da Du den Lösungsvorschlag von Michael80 nicht optimal gefunden hast, hätte ich halt gern ein Beispiel, wie Du das Problem lösen würdest - das ist alles!
Mit xml in Verbindung mit Delphi habe ich noch nichts gemacht und von Frames habe ich auch keine Ahnung!

Viele Grüsse, moperswings

stahli 30. Jan 2007 17:44

Re: Code aus Button in andere unit auslagern
 
Hallo moperswings,

schau Dir doch mal den Tip von SirThornberry näher an...
Ich habe es noch nicht genutzt, aber Du kannst damit m.E. Quelltextteile einfach in eine andere Datei schreiben und diese wird vom Compiler so verwendet, als würde er in Deiner Pas stehen. Deine Unit würde dadurch deutlich kürzer und Du bräuchtest keine Schnittstelle definieren. Der Nachteil: Du hättest viele weitere Dateien, in die Dein Quelltext aufgeteilt ist.

Andere Variante: Du erzeugst eine neue Unit MeineProceduren und definierst dort vollständige Proceduren mit allen nowendigen Übergabeparametern...

-> procedure Proc1(Hin:String;var Zurueck1:String; var Zurueck2:Integer);

Die Unit MeineProceduren bindest Du in Deine HauptUnit ein und rufst die gewünschten Proceduren auf. Ist natürlich etwas Schreibarbeit, aber sauber.
Und evtl. kannst Du einige Proceduren mehrfach benutzen.

Stahli


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