Frame

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
Benutzeravatar
juelin
Beiträge: 297
Registriert: Sa 24. Jul 2021, 18:03
OS, Lazarus, FPC: Linux Ubuntu 22. Windows 10 Delphi 11.3 (L 0.9.xy FPC 2.2.z)
CPU-Target: 64Bit
Wohnort: Mannheim

Frame

Beitrag von juelin »

Hallo Lazarusfreaks,
Habe im Internet und im Forum nix gefunden.
Weiss nicht, ab das Problem schon Jemand hatte?
ich benutze jetzt zum ersten mal Frames in meinem Programm.
Habe eine Form (unit1) und ein Frame (unit2).

Unit1

Code: Alles auswählen

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs,
  StdCtrls, Menus, Eingabe, LCLType, ExtCtrls, FileCtrl,
  PrintersDlgs, Printers, Math, unit2;

type

  { TForm1 }

  TForm1 = class(TForm)
    FileListBox1: TFileListBox;
    Frame1_1: TFrame1;
    .................
  
  // Starten Frame
          if Assigned(Frame1_1) then TFrame1(FindComponent('Frame1_1')).Free;
        Frame1_1:=TFrame1.Create(self);
        Frame1_1.parent:=self;
        Frame1_1.Top:=62;
        Frame1_1.Left:=0;
        Frame1_1.Height:=742;
        Frame1_1.Width:=1595;
        Frame1_1.Name:='Frame1_1';
unit2

Code: Alles auswählen

unit Unit2;

{$mode ObjFPC}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, StdCtrls, Eingabe;

type

  { TFrame1 }

  TFrame1 = class(TFrame)
    Button1: TButton;
    Edit1: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure Edit1KeyPress(Sender: TObject; var Key: char);
    procedure Edit1KeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
  private
  public
     constructor Create(Eigner: TComponent); override;
  end;

implementation

{$R *.lfm}

uses Unit1;

{ TFrame1 }

constructor TFrame1.Create(Eigner: TComponent);
begin
  Eigner:=Eigner;
  [b][color=#FF0000]Form1.Frame1_1.Label2.Caption:='';[/color][/b]
  Form1.Frame1_1.Edit1.Enabled:=True;
  Form1.Frame1_1.Edit1.Color:=$0080FFFF;
  Form1.Frame1_1.Edit1.Font.Color:=$000000FF;
  Form1.Frame1_1.Edit1.ReadOnly:=False;
  Form1.Frame1_1.Edit1.Text:='';
  Form1.Frame1_1.Edit1.AutoSelect:=True;
  ialpha:='';
  inummer:=0;
  iart:=1;
  inumkom:=0;
  ikomma:=0;
  izeich:=3;
Bekomme im Befehl (Rot) ]Form1.Frame1_1.Label2.Caption:=''; folgenden Fehler (siehe Anhang fehlerbild).
Habe anstatt ]Form1.Frame1_1.Label2.Caption:=''; auch schon ]Label2.Caption:=''; probiert, kommt der gleiche Fehler.

Kann mir da Jemand helfen?

Danke und Gruß
Jürgen
Dateianhänge
fehler.jpg
fehler.jpg (19.9 KiB) 1113 mal betrachtet

charlytango
Beiträge: 1097
Registriert: Sa 12. Sep 2015, 12:10
OS, Lazarus, FPC: Laz stable (2.2.6, 3.x)
CPU-Target: Win 32/64, Linux64
Wohnort: Wien

Re: Frame

Beitrag von charlytango »

Also: wir hatten das Thema mit dem Testprojekt schon ;-)

Aber wie kommst du auf die Idee dass so eine Zeile

Code: Alles auswählen

Form1.Frame1_1.Label2.Caption:=''
In der Definition des Frames funktionieren kann?

Du hast schon mal etwas richtig gemacht indem du das Frame im Quellcode erzeugst und einhängst.
Aber vom Frame auf ein unbekanntes Form zugreifen klappt wohl nicht.
Zudem ist das kontraproduktiv, denn wenn mich nciht alles täuscht ist die größte Stärke eines Frames die Kapselung.
Im wesentlichen kann man das mit Forms auch erreichen, aber Frames sind natürlich eleganter.

Mit

Code: Alles auswählen

constructor Create(Eigner: TComponent); override;
überschreibst du den Constructor manuell (in einem TFrame gibt es kein OnCreate Event) und benutzt eine andere Parameterbezeichnung.

Und im Constructor fehlt mir noch ein

Code: Alles auswählen

inherited create(Eigner); 
da wird das Frameobjekt gar nicht erzeugt und dann kannst du auch nicht auf Label2 zugreifen.

Hast du im Debugger durchgestepped wo du nach dem

Code: Alles auswählen

Frame1_1:=TFrame1.Create(self);
landest?


Diese Zeile verstehe ich nicht:

Code: Alles auswählen

 if Assigned(Frame1_1) then Frame1(FindComponent('Frame1_1')).Free;
Sorge einfach dafür dass das Frame an der richtigen Stelle erzeugt wird und benutze es dann. Gerne auch in einen try/except Block verpackt.
Dateianhänge
project1.zip
(139.95 KiB) 60-mal heruntergeladen

Benutzeravatar
Zvoni
Beiträge: 408
Registriert: Fr 5. Jul 2024, 08:26
OS, Lazarus, FPC: Windoof 10 Pro (Laz 2.2.2 FPC 3.2.2)
CPU-Target: 32Bit
Wohnort: BW

Re: Frame

Beitrag von Zvoni »

Zumal er im ersten Code-Block (Seine Form) folgende Zeile hat:

Code: Alles auswählen

Frame1_1:=TFrame1.Create(self);
Er übergibt ja schon die Form als "Eigner" an seine Unit2.

Heisst: Sein "Uses Unit1" in der Implementation der Unit2 kann raus,
und der Code weiter sollte dann lauten:

Code: Alles auswählen

Eigner.Frame1_1.Label2.Caption:='';
//blabblabla
Und richtig mit dem Override bzw. fehlendem Inherited
Ein System sie alle zu knechten, ein Code sie alle zu finden,
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.

Benutzeravatar
juelin
Beiträge: 297
Registriert: Sa 24. Jul 2021, 18:03
OS, Lazarus, FPC: Linux Ubuntu 22. Windows 10 Delphi 11.3 (L 0.9.xy FPC 2.2.z)
CPU-Target: 64Bit
Wohnort: Mannheim

Re: Frame

Beitrag von juelin »

Danke für die Antworten.
Das ist ganz schön Tricky.
Aber mit dem Beispielprogramm in Projekt habe ich es geschafft.
Ich spreche Label2 als self.Label2 an.
Das funktioniert.
Nur hatte ich noch ein Problem mit dem Frame beim Schlissen.
Obwohl ich das Frame mit TFrame1(FindComponent('Frame1_1')).Free; wieder frei gab
blieb das Fenster im Bildschirn immer zu sehen.
Habe ich gelössr, inden ich Frame1_1.Visible auf Fase gesetzt habe.
Danke und Gruß
Jürgen
:wink:

Benutzeravatar
juelin
Beiträge: 297
Registriert: Sa 24. Jul 2021, 18:03
OS, Lazarus, FPC: Linux Ubuntu 22. Windows 10 Delphi 11.3 (L 0.9.xy FPC 2.2.z)
CPU-Target: 64Bit
Wohnort: Mannheim

Re: Frame

Beitrag von juelin »

Hallo charlytango,
Du hast mir ja prima geholfen.
Noch eine Frage.
Auf dem Frame habe ich ein TEdit.
Wie kann ich dem TEdit im Frame den Focus geben?
Ein ActiveControl wie bei Form gibt es ja nicht.

self.Edit1.AutoSelect:=True;
self.Edit1.SetFocus;
haben auch nichts gebracht.

Danke und Gruß
Jürgen

Mathias
Beiträge: 6969
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Frame

Beitrag von Mathias »

Du hast schon mal etwas richtig gemacht indem du das Frame im Quellcode erzeugst und einhängst.
Aber vom Frame auf ein unbekanntes Form zugreifen klappt wohl nicht.
Zudem ist das kontraproduktiv, denn wenn mich nciht alles täuscht ist die größte Stärke eines Frames die Kapselung.
Im wesentlichen kann man das mit Forms auch erreichen, aber Frames sind natürlich eleganter.
Da wurde ich auch mal belernt. Mir wurde empfohlen, ein Frames immer dynamisch einzubinden. Ich hatte auch mal Konflikt mit der Grösse, wen man das Eltern oder das Framefenster in der Grösse ändert.
Seit ich es immer dynamische mache, ist das Problem weg.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
juelin
Beiträge: 297
Registriert: Sa 24. Jul 2021, 18:03
OS, Lazarus, FPC: Linux Ubuntu 22. Windows 10 Delphi 11.3 (L 0.9.xy FPC 2.2.z)
CPU-Target: 64Bit
Wohnort: Mannheim

Re: Frame

Beitrag von juelin »

hi,
habe mein Problem gelöst.
Bevor ich in das Frame gehe (nach Frame.Create) setze ich in Unit1 den Edit im Frame mit
Form1.ActiveControl:=Frame1.Edit1;
Weil das im constructor Create(AOwner1: TComponent); override; nicht geht.
Wenn ich dann auf ein anderes Eingabefeld gehen will kannich im Unit2
z.B. in der Procedure Edit1.KeyDown den Befehl
Form1.ActiveControl:=Form1.Frame1.Edit2;
absetzen.
Das funktioniert.

Ja Lazarus unterscheidet, was Frame angeht, doch sehr vom Delphi.

Danke und Gruß
Jürgen

charlytango
Beiträge: 1097
Registriert: Sa 12. Sep 2015, 12:10
OS, Lazarus, FPC: Laz stable (2.2.6, 3.x)
CPU-Target: Win 32/64, Linux64
Wohnort: Wien

Re: Frame

Beitrag von charlytango »

juelin hat geschrieben: Do 24. Okt 2024, 19:42 Ja Lazarus unterscheidet, was Frame angeht, doch sehr vom Delphi.
Ich denke nicht dass sich das so wahnsinnig unterscheidet weil ja doch auf die Delphi-Kompatibilität geachtet wird (meiner unmaßgeblichen Meinung nach manchmal zuviel).

Frames waren eigentlich schon unter Delphi eher ein Drama (oder ich hab es einfach nicht richtig verstanden)
Deswegen habe ich auch einfach komplette Forms benutzt und diese dann auch in andere Controls eingeklebt. Dann hast du auch wieder die üblichen Events

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

Beitrag von af0815 »

charlytango hat geschrieben: Do 24. Okt 2024, 23:38 Frames waren eigentlich schon unter Delphi eher ein Drama (oder ich hab es einfach nicht richtig verstanden)
Die Probleme waren teilweise gleich. Es hängt damit zusammen das Frames eine spitzen Kapselung sind, die an den Platz den man ihnen gibt, vereinfacht ausgrückt - hinengeblendet werden. Damit kann es, wenn man es im Editor zur Designzeit macht, zu Effekten kommen.
Beispiel: Normalerweise wird der Event von Frame verwendet, nehmen wir an ich habe dort einen Button OHNE einem Button1Click. Ich habe jetzt ein im Designer eingebundenes Frame, mache dort einen Doppelklick auf den Button und der Designer erstellt mir einen ButtonClick Event in der Mainform - nicht im Frame. Der Event im Frame wird quasi überschrieben. Wird aber im Objektinspektor dem eingebundenen Frame zugeordnet, aber quasi nur der lokalen Kopie - im Frame selbst ändert sich nicht, nur in der lokalen Überladung. Lösche ich den Event im Form wieder, bleibt im lfm der Form folgendes gespeichert
inherited Button2: TButton
OnClick = nil
end
Damit ist der Event im Frame noch immer überschrieben, durch einen quasi nil-Event also wird zu Überraschung nicht zur Laufzeit ausgeführt. Das und das nicht nachladen iin der Form bei Änderungen im FRame, machen das verwenden im Designer fast unmöglich. Das Verhalten kenne ich aber von Delphi Versionen. Das müsste man in Lauarus mal angehen. Ich weis nicht ob das bei aktuellen Delphi Versionen besser ist ? Ich habe bei D7 und D8 aufgehört.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Antworten