Genereller Aufbau von FPC/Lazarus Programmen

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
bembulak
Beiträge: 370
Registriert: Di 6. Feb 2007, 09:29
OS, Lazarus, FPC: L0.9.29 SVN:24607 FPC 2.4.0-32 bit @ Win XP SP3
CPU-Target: 32bit i386, ARM
Wohnort: Oberösterreich

Genereller Aufbau von FPC/Lazarus Programmen

Beitrag von bembulak »

Hi und Guten Morgen!

Ich bin heute ein wenig verwirrt. Wie gesagt komme ich ja von anderen Sprachen nach FPC/Lazarus. Was mich jetzt ein wenig verwirrt ist folgendes:

Ich spiele jetzt seit ein paar Tagen mit der IDE herum und habe schon gemerkt, dass ein Button, wenn ich ihn in der Form doppelt anklicke, die IDE in den Editor wechselt und ich dort in der jeweiligen OnClick-Prozedur Code einfügen kann.
Der Deklarationsteil des Programms scheint aber im "Kopf" der Sourcedatei zu liegen (vor Implementation --> var). Heißt dies nun, dass ich alle Variablen, die ich benutze, dort deklarieren muss? :shock: Das glaub ich nicht! Und was, wenn eine dieser Proceduren einen Wert zurück gibt? (Ist es dann eine Funktion oder umgekehrt - in FPC scheint es da ja unterschiede zu geben) An wen oder was kann ich den Wert zurück geben?

Und wenn ich schon eine Klasse schreiben will.. Wo macht ihr sowas? Wie sieht die Structure eurer Programme aus?

Ich bin da im Moment wirklich ein wenig verzweifelt, da meine Quellcodes der letzten Tage an Unübersichtlichkeit kaum zu überbieten sind. Selbst Basic-codes sind leichter lesbar (ohne Goto: natürlich ;) )

Dankeschön!

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6770
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Beitrag von af0815 »

Das 'var' in der Parameterliste bezeichnet die Art der Parameterübergabe.

Ohne 'var' ist übergabe bei Wert, da wird der Wert direkt übergeben (Calling by value).
Mit 'var' ist die Übergabe bei Referenz, da wird nicht der Wert, sondern ein Zeiger übergeben. (Calling by reference)

Beide Versionen gibt es aber auch bei VB und anderen Programmiersprachen.

Bezüglich Code, schick mir mal ein kleines Projekt und ich seh mir da deine Übersichtlichkeitsprobleme an (Source). :mrgreen:

Übrigends halte ich es für eine 'urban legend', das man bei den heutigen Basic-IDE noch goto's benötigt. :lol:
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Christian
Beiträge: 6079
Registriert: Do 21. Sep 2006, 07:51
OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
CPU-Target: AVR,ARM,x86(-64)
Wohnort: Dessau
Kontaktdaten:

Beitrag von Christian »

Grundsätzlich:

pascal units haben eine
interface
und eine implementation section

in der interface section kommt alles rein was deklarationen sind bzw du in anderen units verwenden können willst.

in der implementation section kommen die implementationen dazu rein.

die interface section entspricht den headerfiles in c und die implementation section den c files.

in objektpascal ist es nun so das formulare objekte sind diese werden in der interface section mit type deklariert
die variablen dazu sind unter var zu finden

Bsp.:

interface

type
TForm1 = class(TForm)
...

var
Form1 : TForm1;


ereignisse dieser Formulare werden im Formularobjekt deklariert und logischerweise in der implementation implementiert.

wenn du nun variablen deklarieren willst die global benutzbar sind tust du das am besten in der klasse des formulars

Bsp.:

TForm1 = class(TForm)
...
public
MeineVariable : string
...
end;

Du kannst sie dann mit Form1.meineVariable := 'Teststring'; setzen.

aus jeder anderen Form in der Form1 in der uses anweisung steht.

Wenn du die Variable nur innerhalb des Ereignisses oder der routine brauchst kannst du das folgendermassen machen

procedure TForm1.MeineProcedure;
var
Meinevariable : string;
begin
MeineVariable := 'teststring';
end;

routinen ohne Rückgabewert sind proceduren
mit rückgabewert function (en)

am besten du schaust mal in ein object pascal tuturial es gibt son anfängerthread weiss jetz die adresse nicht aber der is gepinnt dürfte einfach zu finden sein heisst glaub ich "Tuturials und Problemlösungen" da findest auch Object pascal tuturials
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

pluto
Lazarusforum e. V.
Beiträge: 7192
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Beitrag von pluto »

ich habe mir angewöhnt bei größern Projekten wie z.b. mein paint2 Projekt(das kannst du hier Downloaden... ist aber nicht mehr aktuell da ich es ständig weiter entwickle) die aus mehren klassen bestehen pro klasse eine unit
(außer bei kleinern klassen, die kommen dann in einer unit, z.b. die Objekte die bei meinem Paint2 Projekt auf das Panel gezogen werden können, sind alle in einer unit drin)

und Kometare sind zwischen durch auch nicht schlecht !

häng mal so ein Projekt/unit hoch wo du meinst sie ist unübersichtlich
dann könnten wir dir tipps geben was du anders machen könntes !
MFG
Michael Springwald

Christian
Beiträge: 6079
Registriert: Do 21. Sep 2006, 07:51
OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
CPU-Target: AVR,ARM,x86(-64)
Wohnort: Dessau
Kontaktdaten:

Beitrag von Christian »

Ich denk das muss jeder selber wissen ich z.b. arbeite mit riesenunits ich mag das nicht 1000 files im projekt zu haben dann kann ich gleich mit c arbeiten wobei es dort ja auch nur gemacht wird weil man sich sonst nicht zurechtfindet dank der codetools kann man ja wunderbar im source navigieren ...
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

pluto
Lazarusforum e. V.
Beiträge: 7192
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Beitrag von pluto »

naja ich finde mich in risen units nie zurecht !
ab einer gewissen größe muss man den code einfach auslagern !

z.b. mein Paint2 Projekt da bin ich am überlegen ob ich gewisse teile nicht als DLL speichere !
Das geht aber auch wieder nicht da ich jede unit einzeln ständig bearbeite !
Das Komplieren dauert richtig lange !
ca ne minute würde ich schon sagen !

und im ausgabe verzeichnis habe ich mind 1000 Dateien rumliegen neben der Anwendung... aber das ist ja noch eine anderer geschichte !
MFG
Michael Springwald

Euklid
Lazarusforum e. V.
Beiträge: 2808
Registriert: Fr 22. Sep 2006, 10:38
OS, Lazarus, FPC: Lazarus v2.0.10, FPC 3.2.0
Wohnort: Hessen
Kontaktdaten:

Re: Genereller Aufbau von FPC/Lazarus Programmen

Beitrag von Euklid »

bembulak hat geschrieben: An wen oder was kann ich den Wert zurück geben?
Wenn ich alles durchgelesen habe, wurde diese Frage noch nicht beantwortet.

Beispiel die Funktion IstBuchstabe, die true zurückgibt, wenn z ein Buchstabe ist:

Code: Alles auswählen

function IstBuchstabe(z:String):Boolean;
begin
  IstBuchstabe:=true;
  If z='' then IstBuchstabe:=false else
  begin
    If length(z)>1 then IstBuchstabe:=false;
    If ord(z[1])<65 then IstBuchstabe:=false;
    If (ord(z[1])>90)and(ord(z[1])<97) then IstBuchstabe:=false;
    If ord(z[1])>122 then IstBuchstabe:=false;
  end;
end;
Nun der Aufruf und die Rückgabe in einer Beispielprozedur:

Code: Alles auswählen

//Beispiel: fuctions in der Anwendung.
 
procedure beispiel;
var test: boolean;  // <<--- lokale Variable für die Prozedur Beispiel
    s: string;
begin
//.....
// Nun der Beispieltext:
 
s:=Edit1.Text;  //Benutzereingabe
test:= IstBuchstabe(s);  // So erhält man den Funktionswert zurück!
 
If NOT test = true then Close;  // Bestrafung des Benutzers, wenn er keinen Buchstaben eingibt. Programm wird geschlossen.
 
//...
//Alternativ geht auch schneller:
 
If NOT IstBuchstabe(s)=true then Close;
 
// u.s.w.
 
end;

Euklid

bembulak
Beiträge: 370
Registriert: Di 6. Feb 2007, 09:29
OS, Lazarus, FPC: L0.9.29 SVN:24607 FPC 2.4.0-32 bit @ Win XP SP3
CPU-Target: 32bit i386, ARM
Wohnort: Oberösterreich

Beitrag von bembulak »

Danke euch allen schon mal. Ich werde jetzt mal ein paar Tage über eueren Tips und Hinweisen brüten und das versuchen zu verstehen.
Wenn es recht ist, komme ich in diesem Thread dann wieder mit neuen Fragen.

Danke.

Euklid
Lazarusforum e. V.
Beiträge: 2808
Registriert: Fr 22. Sep 2006, 10:38
OS, Lazarus, FPC: Lazarus v2.0.10, FPC 3.2.0
Wohnort: Hessen
Kontaktdaten:

Beitrag von Euklid »

Nur zu ;)

bembulak
Beiträge: 370
Registriert: Di 6. Feb 2007, 09:29
OS, Lazarus, FPC: L0.9.29 SVN:24607 FPC 2.4.0-32 bit @ Win XP SP3
CPU-Target: 32bit i386, ARM
Wohnort: Oberösterreich

Beitrag von bembulak »

So, ich weiß, ich bin ein Leichengräber, aber ich mach trotzdem hier weiter, da es immernoch/wieder das Thema ist.

Konkreter Fall:
Kleine Programm mit ein paar Werten (aus TEdit) und einer Berechnung und einem Label. Funktioniert soweit ja auch alles.
Nun kommt etwas dazu: --> die Felder sollen also gelöscht werden und der Startwert wird reingeschrieben.
Dies Procedure solle aber a) aber das Menü und b) über einen Button aufgerufen werden.
Nur: WO schreibe ich diese Procedur, damit ich über a) und b) darauf zugreifen kann?

Danke.

Hier der Code:

Code: Alles auswählen

unit main;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls,
  Buttons, Menus;
 
type
 
  { TForm1 }
 
  TForm1 = class(TForm)
    btn_calc_bmi: TButton;
    btn_reset: TButton;
    edt_groesse: TEdit;
    edt_weight: TEdit;
    GroupBox1: TGroupBox;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    MainMenu1: TMainMenu;
    MenuItem1: TMenuItem;
    MenuItem2: TMenuItem;
    MenuItem3: TMenuItem;
    MenuItem4: TMenuItem;
    procedure btn_calc_bmiClick(Sender: TObject);
    procedure btn_resetClick(Sender: TObject);
    procedure MenuItem2Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end; 
 
var
  Form1: TForm1; 
  cm, weight : Double;
  bmi : String;
 
implementation
 
{ TForm1 }
 
procedure TForm1.btn_calc_bmiClick(Sender: TObject);
var
   len : Integer;
 
begin
 
    cm := StrToFloat(edt_groesse.Text);
    weight := StrToFloat(edt_weight.Text);
    bmi := FloattoStr((weight / sqr(cm/100)));
    len := Length(bmi);
 
    if len > 5 then
           begin
            delete(bmi, 5, len-5);
           end;
 
    Label3.Text := bmi;
 
end;
 
procedure TForm1.btn_resetClick(Sender: TObject);
begin
  { Hier soll das Rücksetzen der Felder aufgerufen werden }
end;
 
procedure TForm1.MenuItem2Click(Sender: TObject);
begin
 
{ Hier soll das Rücksetzen der Felder aufgerufen werden }
 
end;
 
initialization
  {$I main.lrs}
 
end.

Christian
Beiträge: 6079
Registriert: Do 21. Sep 2006, 07:51
OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
CPU-Target: AVR,ARM,x86(-64)
Wohnort: Dessau
Kontaktdaten:

Beitrag von Christian »

entwder du Schreibst eine extra procedure also

Code: Alles auswählen

procedure ResetFields;
begin
  ... 
end;
und die rufst einfach mit REsetFields; überall auf wo du willst.

Speziell in Delphi/Lazarus kannst auch eine ActionList nehmen eine neue Action anlegen und deinen Buttons einfach die Action zuweisen...
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

bembulak
Beiträge: 370
Registriert: Di 6. Feb 2007, 09:29
OS, Lazarus, FPC: L0.9.29 SVN:24607 FPC 2.4.0-32 bit @ Win XP SP3
CPU-Target: 32bit i386, ARM
Wohnort: Oberösterreich

Beitrag von bembulak »

entwder du Schreibst eine extra procedure also

Code: Alles auswählen

procedure ResetFields;
begin
  ...
end;
und die rufst einfach mit REsetFields; überall auf wo du willst.
Genau das meine ich - aber WO im obigen Code muss ich das machen? Ich meine, vlt bei Zeile 46, nach Implementation oder erst gaaaanz am Ende des Codes, oder wie?

Darum geht es mir. In anderen Sprachen wäre es nun so, dass ich die Proc deklarieren muss, bevor ich sie das erste mal aufrufe. Demnach wäre Zeile 46/47 gar nicht so verkehrt.

Keinesfalls kann ich mir vorstellen, sie erst z.B. IN Zeile 67 (procedure TForm1.btn_resetClick(Sender: TObject); ) zu machen, da es dann eine Prozedur innerhalb einer Prozedur wäre und somit von aussen nicht sichtbar.

Wo, also muss ich das machen und gibt es dann noch was zu beachten?

Danke für die Geduld!

monta
Lazarusforum e. V.
Beiträge: 2809
Registriert: Sa 9. Sep 2006, 18:05
OS, Lazarus, FPC: Linux (L trunk FPC trunk)
CPU-Target: 64Bit
Wohnort: Dresden
Kontaktdaten:

Beitrag von monta »

Ich würde sie noch der Form unterstellen, und das sieht dann ungefähr so aus:

Code: Alles auswählen

unit main;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls,
  Buttons, Menus;
 
type
 
  { TForm1 }
 
  TForm1 = class(TForm)
    btn_calc_bmi: TButton;
    btn_reset: TButton;
    edt_groesse: TEdit;
    edt_weight: TEdit;
    GroupBox1: TGroupBox;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    MainMenu1: TMainMenu;
    MenuItem1: TMenuItem;
    MenuItem2: TMenuItem;
    MenuItem3: TMenuItem;
    MenuItem4: TMenuItem;
    procedure btn_calc_bmiClick(Sender: TObject);
    procedure btn_resetClick(Sender: TObject);
    procedure MenuItem2Click(Sender: TObject);
  private
    procedure ResetFields;   //<<da noch deklarieren
    { private declarations }
  public
    { public declarations }
  end; 
 
var
  Form1: TForm1; 
  cm, weight : Double;
  bmi : String;
 
implementation
 
{ TForm1 }
 
procedure TForm1.btn_resetClick(Sender: TObject);
begin
  { Hier soll das Rücksetzen der Felder aufgerufen werden }
  ResetFields;
end;
 
procedure TForm1.MenuItem2Click(Sender: TObject);
begin
  { Hier soll das Rücksetzen der Felder aufgerufen werden }
  ResetFields;
end;
 
//Stellung egal, hauptsache zwischen implementation und initialization und nicht innerhalb anderer Procedure/function
procedure TForm1.ResetFields;
begin
  Edit1.Text := '';
  //usw...
end;
 
initialization
  {$I main.lrs}
 
end.
Wenn du sie nur aus der seleben Unit aufrufst, kann sie in den privat-Abschnitt, und steht so von außerhalb nicht zur verfügung, wenn du sie von ner anderen Unit auch ansprechen willst, dann muss sie aus privat raus.
Johannes

bembulak
Beiträge: 370
Registriert: Di 6. Feb 2007, 09:29
OS, Lazarus, FPC: L0.9.29 SVN:24607 FPC 2.4.0-32 bit @ Win XP SP3
CPU-Target: 32bit i386, ARM
Wohnort: Oberösterreich

Beitrag von bembulak »

Das hilft mir weiter - vor allem beim generellen Verständnis.
Verneig' und herzlichen Dank auch!

DANKE.

monta
Lazarusforum e. V.
Beiträge: 2809
Registriert: Sa 9. Sep 2006, 18:05
OS, Lazarus, FPC: Linux (L trunk FPC trunk)
CPU-Target: 64Bit
Wohnort: Dresden
Kontaktdaten:

Beitrag von monta »

Kein Problem ;)
Johannes

Antworten