Aufruf Form1.Komponente in Form2 ok?

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
NoCee
Beiträge: 170
Registriert: Do 3. Mär 2011, 21:34
OS, Lazarus, FPC: WinXp/7/10 Opensuse13.2/Leap15.3 (L 2.2.0 FPC 3.2.2 )
CPU-Target: Intel 32/64Bit, ARM9
Wohnort: Ulm

Aufruf Form1.Komponente in Form2 ok?

Beitrag von NoCee »

Hallo zusammen,
ich habe ein kleines Testprogramm für eine Netzwerkkommunikation mit einer Maschine geschrieben.
Über das Haupformular rufe ich ein zweites Formular auf.
Hier hab ich einen Button gepappt der mir ein Form1.Putty.SendMessage('Test') macht.
Die Komponente ist ein LNet TCPIP Server die ich auf die Form1 gezogen habe.
Ich starte die Komponente (Netzwerkserver Listen) mit OnCreate von Form1.
Hier werden auch alle Events dieser Komponente verarbeitet.
Das funktioniert auch, ich lese aber oft, daß man mit der Interaktion zwischen 2 Formularen aufpassen muß.

Ist das so ok wie ich das mache, wenn nein, wie mach ich das besser oder gar richtig?

Für Hilfe schon mal Danke im Vorraus
Gruß
NoCee

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Aufruf Form1.Komponente in Form2 ok?

Beitrag von Winni »

Hi!

Meistens wird vor dem rekursiven Benutzen der Units gewarnt.
Das kann umgangen werden mit einer zusätzlichen Unit.
In die kommen alle Konstanten, Variablen sowie grundlegende Proceduren für Dein Projekt rein.

Und dann benutzen beide Formen bzw. deren Unit eben diese neue Unit.
Und man kann über die Variablen in dieser Unit "kommunizieren" ohne große Klimmzüge.

Winni

wp_xyz
Beiträge: 4889
Registriert: Fr 8. Apr 2011, 09:01

Re: Aufruf Form1.Komponente in Form2 ok?

Beitrag von wp_xyz »

NoCee hat geschrieben:
Fr 27. Aug 2021, 18:05
Hallo zusammen,
ich habe ein kleines Testprogramm für eine Netzwerkkommunikation mit einer Maschine geschrieben.
Über das Haupformular rufe ich ein zweites Formular auf.
Hier hab ich einen Button gepappt der mir ein Form1.Putty.SendMessage('Test') macht.
Die Komponente ist ein LNet TCPIP Server die ich auf die Form1 gezogen habe.
Ich starte die Komponente (Netzwerkserver Listen) mit OnCreate von Form1.
Hier werden auch alle Events dieser Komponente verarbeitet.
Das funktioniert auch, ich lese aber oft, daß man mit der Interaktion zwischen 2 Formularen aufpassen muß.
Mir ist jetzt konkret nicht klar, wie das zusammengehört: Es gibt ein Hauptformular und es gibt ein "zweites Formular". Aber welches von den beiden ist Form1? Oder ist das ein drittes Formular? Und wer ruft was von wem auf?

NoCee
Beiträge: 170
Registriert: Do 3. Mär 2011, 21:34
OS, Lazarus, FPC: WinXp/7/10 Opensuse13.2/Leap15.3 (L 2.2.0 FPC 3.2.2 )
CPU-Target: Intel 32/64Bit, ARM9
Wohnort: Ulm

Re: Aufruf Form1.Komponente in Form2 ok?

Beitrag von NoCee »

Hallo,
vielleicht ein bisschen knapp erklärt.
Ich habe Form1 (Hauptformular) und habe da die Komponente LNet draufgezogen.
Über dieses Formular wird alles mit dieser Komponente gehandelt.
Alle Events wie OnEmpfang, OnError, OnConnect usw.
Auf der Form2 möchte ich jetzt mit einem Button über diese Komponente von Form1
etwas senden. Im Buttonevent von Form2 steht in der procedure sowas wie Form1.Putty.SendMessage('Test').
Wie gesagt, das funktioniert, aber ob das sich nicht irgendwann mal sich selber ins Gehege kommt ist mir nicht klar.

@Winni ich wüßte jetzt nicht wie ich eine visuelle Komponente auf eine andere Unit auslagern könnte.
LNet ginge auch nonvisual, aber da ist der Vorteil der visuellen Programmierung weg, der mir aber als Halblaie sehr entgegenkommt.

Gruß
NoCee

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1435
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Aufruf Form1.Komponente in Form2 ok?

Beitrag von fliegermichl »

NoCee hat geschrieben:
Mo 30. Aug 2021, 10:04
ich wüßte jetzt nicht wie ich eine visuelle Komponente auf eine andere Unit auslagern könnte.
Wer sagt, daß die dritte Unit kein Formular haben kann?

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Aufruf Form1.Komponente in Form2 ok?

Beitrag von Winni »

Hallo!

Oder doch rekursiv:

Code: Alles auswählen

unit Unit1;
interface
uses  ....., unit2;
....
und dann:

Code: Alles auswählen

unit unit2;
....
implementation
uses unit1;
...
Und dann kann man in unit2:

Code: Alles auswählen

Form1.Komponente.property := .....
Und in unit1:

Code: Alles auswählen

Form2.Komponente.property := ...

Winni

wp_xyz
Beiträge: 4889
Registriert: Fr 8. Apr 2011, 09:01

Re: Aufruf Form1.Komponente in Form2 ok?

Beitrag von wp_xyz »

LNet ist meines Wissens eine nicht-visuelle Komponente - die kann man auf ein Datenmodul auslagern, und schon hat man den Zirkelbezug "Form1 uses Form2" und "Form2 uses "Form1" verhindert, denn jetzt heißt es "Form2 uses Datamodule". Falls auch Form1 das Datenmodul benutzt muss man darauf achten dass dieses vor Form1 erzeugt wird, dazu das Datenmodul in der Liste der automatisch erzeugten Formulare vor Form1 ziehen! (Oder von Form1 manuell erzeugen lassen).

Bei einer nicht-visuellen Komponente sehe ich anderseits auch gar keinen Grund, LNet zur Designzeit auf ein Formular oder ein Datenmodul zu klatschen - die paar Properties kann man auch zur Laufzeit setzen. Damit könnte die ganze über LNet laufende Kommunikation in eine einfache Unit ausgelagert werden (was auch den Vorteil hätte, dass man das Designzeit-Package lnetvisual nicht installieren muss, und vielleicht sogar nur mit dem lnetbase Laufzeitpackage auskommt).

winni's Tipp, die "uses" einmal in den Interface-, einmal in den Implementation-Abschnitt zu setzen, funktioniert auch. Jedoch kann es bei einem größeren Projekt mit komplizierterer Unit-Abhängigkeit sein, dass das nicht mehr funktioniert. Daher habe ich solche Konstruktionen immer gleich von Anfang an vermieden.

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6209
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:

Re: Aufruf Form1.Komponente in Form2 ok?

Beitrag von af0815 »

wp_xyz hat geschrieben:
Mo 30. Aug 2021, 11:03
Falls auch Form1 das Datenmodul benutzt muss man darauf achten dass dieses vor Form1 erzeugt wird, dazu das Datenmodul in der Liste der automatisch erzeugten Formulare vor Form1 ziehen! (Oder von Form1 manuell erzeugen lassen).
Ich bin ein Anhänger von nur einem Form automatisch erzeugen lassen. Dieses erzeugt dann geplant alles andere und man ist nicht abhängig vom Editor wo der dann was wie einfügt.

Da hat mir schon Delphi früher mitgespielt und auch bei Lazarus kann man es beobachten, wenn man Projekte dupliziert/verschiebt/Strukturändert das schon mal die Liste der erzeugten Formulare leer ist oder sich was ungewollt umändert - weil man ein Formular mal zu herausnimmt und wieder hinzufügt.

Vor allen bei Datenmodulen kann es zu blöden Situationen kommen, wenn zB. das Datenmodul Parameter benötigt, diese erst aber nach dem Erstellen der Mainform bereitstehen. Wenn dann die Reihenfolgen nicht stabil sind, ist ärger vorprogrammiert.

Aufruf von Form1 zu Form2 ist IMHO ok, wenn man nicht zugleich in die andere Richtung arbeitet. Ich löse das dann über Callbacks oder übergebe der 2ten Form meine visuellen Objekte als Parameter oder Records zum Datenaustausch. Damit habe ich keine zirkularen Referenzen.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Aufruf Form1.Komponente in Form2 ok?

Beitrag von Winni »

af0815 hat geschrieben:
Mo 30. Aug 2021, 12:33

Vor allen bei Datenmodulen kann es zu blöden Situationen kommen, wenn zB. das Datenmodul Parameter benötigt, diese erst aber nach dem Erstellen der Mainform bereitstehen. Wenn dann die Reihenfolgen nicht stabil sind, ist ärger vorprogrammiert.
Hi!

Die definitive Stelle, bei der alles initialisiert ist ist

Code: Alles auswählen

TForm1.onActivate
Dabei muss man beachten, dass sich onActivate bei den Betriebssystemen verschieden verhält:

Linux führt es nur einmal beim ersten show aus.
Windows führt es bei jedem show aus - also auch wenn der WindowState von minimized wieder auf normal oder maximized geht.

Um Betriebssystem übergreifende Kompatibilität zu erzeugen, muss man also folgendes coden:

Code: Alles auswählen

procedure TForm1.FormActivate(Sender: TObject);
begin
...
onActivate := Nil;
end;
Dann wird es nur einmal ausgeführt.

Winni

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1435
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Aufruf Form1.Komponente in Form2 ok?

Beitrag von fliegermichl »

Hmm, kann ich nicht nachvollziehen.

Code: Alles auswählen

  TForm1 = class(TForm)
    Label1: TLabel;
    procedure FormActivate(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    cnt : integer;
  public

  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
begin
  cnt := 0;
end;

procedure TForm1.FormActivate(Sender: TObject);
begin
  inc(cnt);
  Label1.Caption := IntToStr(cnt);
end;
Bei mir bleibt das Label immer 1.
Windows 10 64 Bit Laz 2.3.0 FPC 3.3.1

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Aufruf Form1.Komponente in Form2 ok?

Beitrag von Winni »

fliegermichl hat geschrieben:
Di 31. Aug 2021, 07:27
Hmm, kann ich nicht nachvollziehen.

Code: Alles auswählen

  TForm1 = class(TForm)
    Label1: TLabel;
    procedure FormActivate(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    cnt : integer;
  public

  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
begin
  cnt := 0;
end;

procedure TForm1.FormActivate(Sender: TObject);
begin
  inc(cnt);
  Label1.Caption := IntToStr(cnt);
end;
Bei mir bleibt das Label immer 1.
Windows 10 64 Bit Laz 2.3.0 FPC 3.3.1
Hi!

Ups! Da bin ich wohl nicht auf der Höhe der Zeit!

Du hast Recht: Das Windows -Verhalten wurde dem Linux-Vehalten angepasst.
Wer immer das war - M$ oder das LCL-Team.

Gut zu wissen. Danke.

Winni

Soner
Beiträge: 623
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

Re: Aufruf Form1.Komponente in Form2 ok?

Beitrag von Soner »

Winni hat geschrieben:
Mo 30. Aug 2021, 19:22
af0815 hat geschrieben:
Mo 30. Aug 2021, 12:33

Vor allen bei Datenmodulen kann es zu blöden Situationen kommen, wenn zB. das Datenmodul Parameter benötigt, diese erst aber nach dem Erstellen der Mainform bereitstehen. Wenn dann die Reihenfolgen nicht stabil sind, ist ärger vorprogrammiert.
Hi!

Die definitive Stelle, bei der alles initialisiert ist ist

Code: Alles auswählen

TForm1.onActivate
Dabei muss man beachten, dass sich onActivate bei den Betriebssystemen verschieden verhält:

Linux führt es nur einmal beim ersten show aus.
Windows führt es bei jedem show aus - also auch wenn der WindowState von minimized wieder auf normal oder maximized geht.

Um Betriebssystem übergreifende Kompatibilität zu erzeugen, muss man also folgendes coden:

Code: Alles auswählen

procedure TForm1.FormActivate(Sender: TObject);
begin
...
onActivate := Nil;
end;
Dann wird es nur einmal ausgeführt.

Winni
TForm.OnActivate wird aufgerufen wenn immer ein Form aktiviert wird. Bei einem Ein-Form-Anwendung wird es einmal aufgerufen, wenn man mehr als ein Form im Programm hat, dann jedesmal beim Form-Wechsel. Bei Windows ist es so und ich glaube bei anderen Betriebssystemen musste es auch so sein.

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1435
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Aufruf Form1.Komponente in Form2 ok?

Beitrag von fliegermichl »

Soner hat geschrieben:
Di 31. Aug 2021, 21:23
TForm.OnActivate wird aufgerufen wenn immer ein Form aktiviert wird. Bei einem Ein-Form-Anwendung wird es einmal aufgerufen, wenn man mehr als ein Form im Programm hat, dann jedesmal beim Form-Wechsel. Bei Windows ist es so und ich glaube bei anderen Betriebssystemen musste es auch so sein.
Stimmt, kann ich bestätigen.

Antworten