[gelöst] eigene unit

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
mulcheo
Beiträge: 57
Registriert: Do 1. Aug 2013, 15:11

[gelöst] eigene unit

Beitrag von mulcheo »

Hallo,

einfache Frage, denke ich, aber irgendwo stecke ich leider fest: da ich mehrere Funktionen habe, die thematisch zusammen gehören, möchte ich sie gerne in eine eigene unit 'auslagern' (standard 'unit2'). Ich füge also im Hauptprgramm 'unit2' bei 'uses' hinzu und lege (Datei, Neue Unit) eine neue unit an, der ich eine Minimalprocedure verpasse...

Unit2 schaut nun so aus:

Code: Alles auswählen

 
unit Unit2;
 
{$mode objfpc}{$H+}
 
interface
 
  procedure Aendern(Zeile: string);
 
 
implementation
 
uses
  crt,classes,unit1;
 
procedure Aendern(Zeile: string);
begin
  Zeile:='Neue Nachricht';
end;
 
 
end.


ich führe jetzt vom Hauptprogramm her aus:

Code: Alles auswählen

Nachricht:='alte Nachricht';
Aendern(Nachricht);
Form1.Caption:=Nachricht;
und erhalte zwar keinen compiler error aber auch keinen Effekt (d.h. die Caption gibt 'alte Nachricht' aus) - woran liegt's?

B-Frage:
wie kann ich von 'unit2' aus direkt die Caption der Form1 änder oder beispielsweise Text (Canvas.Textout) darauf ausgeben?

Danke schonmal :)
Zuletzt geändert von mulcheo am So 29. Jun 2014, 21:51, insgesamt 1-mal geändert.

Scotty
Beiträge: 768
Registriert: Mo 4. Mai 2009, 13:24
OS, Lazarus, FPC: Arch Linux, Lazarus 1.3 r44426M FPC 2.6.4
CPU-Target: x86_64-linux-qt/gtk2
Kontaktdaten:

Re: eigene unit

Beitrag von Scotty »

Prinzipiell ist das richtig. Du hast nur vergessen, den Parameter als Rückgabewert zu deklarieren: procedure Aendern(var Zeile: string); oder function Aendern: string;

http://lazarus-ccr.sourceforge.net/fpcd ... 100011.4.2
http://lazarus-ccr.sourceforge.net/fpcd ... 12800011.3

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: eigene unit

Beitrag von Michl »

mulcheo hat geschrieben: B-Frage:
wie kann ich von 'unit2' aus direkt die Caption der Form1 änder oder beispielsweise Text (Canvas.Textout) darauf ausgeben?
Würd ich gar nicht, ist kein gutes Programmdesign. Weise lieber in der zum Formular gehörenden Unit die entsprechenden Werte den Controls zu.

Ansonsten:
http://www.delphi-treff.de/object-pasca ... fbau#c4934
oder
http://wiki.freepascal.org/Form_Tutoria ... .C3.B6nnen

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

mulcheo
Beiträge: 57
Registriert: Do 1. Aug 2013, 15:11

Re: eigene unit

Beitrag von mulcheo »

ah, super; das 'var' löst mein erstes Problem.

jetzt lese ich immer wieder (auch im Rahmen meiner Recherche vor und nach der Frage) von 'schechtem Programmdesign' und ich verstehe ja auch, dass Formulare, die sich wechselseitig aufrufen, vielleicht nicht die beste Idee sind, ABER: was ich will, ist doch eigentlich sehr naheliegend und eher ein Merkmal guten Designs, oder hab ich hier Denkfehler?

Ich habe in meinem Hauptprogramm mit der Zeit einfach sehr viele einzelne Funktionen und Proceduren - beispielsweise 6 Stück, die sich nur im die Textausgabe und Zeilenabstände kümmern, dann eine weitere handvoll für das Dateihandling, weitere für Usereingaben, da gibt es Keyeingaben, dann Maus, dann noch Popupmenüs usw... jetzt war meine Intuition einfach die, Gruppen zu bilden und die aus meinem Hauptprogramm auszulagern - eben in eigene 'units'. Das scheint mir auch sehr sinnreich, da beispielsweise die proceduren und functionen, welche die Textausgaben regeln, sich untereinander aufrufen, dabei aber beispielsweise nicht mit den Routinen für Dateilesen, -überschrieben, -anhängen interferieren. Wenn ich die nun in einer eigenen unit versammelt hätte, könnte ich sie in einem eigenen Fenster bzw. 'unit-Reiter' coden und verwalten und hätte letztlich viel an Übersichtlichkeit gewonnen. Ich will also gar keine neuen Formulare schöpfen, sondern - platt ausgedrückt - nur meinen Quellcode auf verschiedene units verteilen; was in meinem konkreten Fall wirklich sinnvoll ist, da sich hier gut abgrenzbare Gruppen bilden lassen.

Und dann kommt es eben zu dem Problem, dass die Routinen der unit 'AllesRundUmDieTextausgabe' ab und an mal auch ein Textout bringen müssen, also technisch gesprochen einen Canvas-Befehl auf der mainForm ausführen.

Gibt es dafür keine etablierten 'Lösungen'?

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: eigene unit

Beitrag von Michl »

mulcheo hat geschrieben:Gibt es dafür keine etablierten 'Lösungen'?
Doch, die nutzt Du ja bei der Erstellung einer eigenen Anwendung, indem Du Dir Komponenten lädst. Sobald Du von einer Parent-Klasse wieder auf die abgeleitete Klasse zugreifst, verbaust du Dir jede Möglichkeit, von diesem Parent jemals wieder eine andere/neue Klasse abzuleiten.

Für das, was Du vorhast, könnten TFrames für dich sinnvoll sein: http://wiki.freepascal.org/Frames
Was etwas aufwendiger ist, ist die Erstellung einer eigenen Komponente: http://wiki.freepascal.org/How_To_Write ... _Component

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

mulcheo
Beiträge: 57
Registriert: Do 1. Aug 2013, 15:11

Re: eigene unit

Beitrag von mulcheo »

ich hatte eher sowas im Kopf wie die guten alten Pascal(functional)-units, in denen man einfach etwas quellcode auslagern kann. Aber vielleicht funktioniert dieses Konzept auch im Objektorientierten Bereich nicht mehr - wäre schade, aber ich kenne mich da leider nicht genug aus.

Was wäre denn dann eure Empfehlung, um im Quellcode nicht die Übersicht zu verlieren?

p.s. ich will keine zweite Form erstellen (das scheint mir beim Überfliegen der Hauptsinn der Frames zu sein). Ich hoffe mal, da liegt jetzt kein Missverständnis vor. Es wäre ja auch schon ausreichend, wenn die teile der 'unit' zwar nicht innerhalb der unit selbst (also von anderen unit-functionen), dafür aber jeweils vom Hauptprogramm aus aufgerufen werden können.

oder anders formuliert: was wäre das lazarus-äquivalent zu folgendem Pascal-stück?

Hauptprgramm:

Code: Alles auswählen

 
PROGRAM Ich_habe_ne_unit;
 
USES Crt, Unit1;   
 
BEGIN
  Prozedur1;    
  ReadKey;
END.
unit1.pas:

Code: Alles auswählen

 UNIT Unit1;
 
INTERFACE
 
  PROCEDURE Prozedur1;
 
IMPLEMENTATION
 
  PROCEDURE Prozedur1;
  BEGIN
    Writeln ('Prozedur1 wurde aufgerufen.');
  END;
 
END.
Zuletzt geändert von mulcheo am Di 20. Mai 2014, 12:27, insgesamt 1-mal geändert.

Benutzeravatar
theo
Beiträge: 10893
Registriert: Mo 11. Sep 2006, 19:01

Re: eigene unit

Beitrag von theo »

Ich würde das nicht machen.
Ein über mehrere Units zersplitterter Code ist nicht übersichtlicher.
Gehe einfach von der Logik aus, dass du alles was direkt mit dem Formular "verbunden ist" in der zugehörigen Unit erledigst (Event-Bearbeitung, Ausgabe etc.).
Auslagern kannst du alles Andere, also Helferfunktionen und Klassen.

Ausserdem: Was heisst schon übersichtlich? Im Quellcode bewegt man sich sowieso mit den Hilfsmitteln ("Suche Deklaration", Shift+Ctrl+Up/Dwn, Code Explorer etc.). Manche mögen auch "Code Folding".

mulcheo
Beiträge: 57
Registriert: Do 1. Aug 2013, 15:11

Re: eigene unit

Beitrag von mulcheo »

ich konnte die Zirkelreferenz (unit1 nutzt Hilfsunit, Hilfsunit nutzt unit1) nun endlich umgehen, dank http://www.lazarusforum.de/viewtopic.php?f=55&t=7918 :)

Antworten