Shape schließen

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
Andy Nightingale
Beiträge: 408
Registriert: Mo 13. Jan 2025, 12:11

Shape schließen

Beitrag von Andy Nightingale »

Hallo Leute,
ich habe auf Form1 (Main). einen Button mit dem öffne ich eine Form (Kalender).

Code: Alles auswählen

procedure TForm1.BCMaterialDesignButtonKalenderClick(Sender: TObject);
begin
    if not Assigned(FKalender) then
    begin
    FKalender:= TFKalender.Create(Self); 
    BGRAShapeKalender.Visible := True; 
end;       
    
Soweit so gut. Nun möchte ich das wenn ich die Form Kalender schließe das sich das Shape in Form1schließt. Das machte ich so:

Code: Alles auswählen

procedure TFKalender.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
  (Application.MainForm as TForm1).BGRAShapeKalender.Visible := False;
end;          
Das funktioniert aber nicht. Auch nicht mit:

Code: Alles auswählen

 Form1.BGRAShapeKalender.Visible := False;
Ich kann ja nicht bei der Form Kalender in Uses die Form1 rein machen, da die Form Kalender ja schon in der Unit 1 drin ist. das gibt Error Circular...usw. Hat jemand eine Idee. (Ich traue mich fast nichts mehr hier zu schreiben, da man mich nicht versteht.) :roll:

Benutzeravatar
Zvoni
Beiträge: 659
Registriert: Fr 5. Jul 2024, 08:26
OS, Lazarus, FPC: Windoof 10 Pro (Laz/FPC fixes)
CPU-Target: 64Bit
Wohnort: BW

Re: Shape schließen

Beitrag von Zvoni »

Ein eigener Konstruktor, in welchem du zusätzlich eine Referenz auf das Shape mitlieferst?
Brauchst natürlich ein Feld in TFKalender, was dann die Referenz hält

Code: Alles auswählen

//In MainForm
procedure TForm1.BCMaterialDesignButtonKalenderClick(Sender: TObject);
begin
    if not Assigned(FKalender) then
    begin
    FKalender:= TFKalender.Create(Self, BGRAShapeKalender); 
    //BGRAShapeKalender.Visible := True; 
end;

//in TFKalender
Constructor TFKalender.Create(Owner:TObject; AShape:BGRAShapeDingensType);  //Braucht natürlich BGRADingensUnit in Uses
Begin
  Inherited Create(Owner);  //Oder war es Nil?
  FShape:=AShape;
  FShape.Visible:=True;
End;

procedure TFKalender.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
  FShape.Visible := False;
end;      
Alles ungetestet und ins Blaue geschossen.

Und übrigens gruselig: Ein "Kind" sollte nie ein Update auf ein "Parent" machen
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
af0815
Lazarusforum e. V.
Beiträge: 7289
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: Shape schließen

Beitrag von af0815 »

Ein Kind kann durchaus ein Update im Parent machen. Einfach einen geplanten Callback/Event machen. Siehe die ganzen On... Händler. Somit kann der Parent dem Kind sagen, wie er erreichbar ist, oder wer anderer der für das Ereignis zuständig ist.

BTW Ich finde in der Lazarus Wiki jetzt kein gutes Beispiel, wie man einen Event/Callback selbst erstellt.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Benutzeravatar
Zvoni
Beiträge: 659
Registriert: Fr 5. Jul 2024, 08:26
OS, Lazarus, FPC: Windoof 10 Pro (Laz/FPC fixes)
CPU-Target: 64Bit
Wohnort: BW

Re: Shape schließen

Beitrag von Zvoni »

af0815 hat geschrieben: Di 5. Mai 2026, 17:09 Ein Kind kann durchaus ein Update im Parent machen. Einfach einen geplanten Callback machen. Siehe die ganzen On... Händler. Somit kann der Parent dem Kind sagen, wie er erreichbar ist, oder wer anderer der für das Ereignis zuständig ist.
Hmmm…….stimmt.
In mainform einen OnClose-handler, das dem close-ereignis von TFKalender zuweisen, im handler closeaction setzen, shape auf invisible, fertich
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.

Andy Nightingale
Beiträge: 408
Registriert: Mo 13. Jan 2025, 12:11

Re: Shape schließen

Beitrag von Andy Nightingale »

Zvoni hat geschrieben: Di 5. Mai 2026, 17:24
af0815 hat geschrieben: Di 5. Mai 2026, 17:09 Ein Kind kann durchaus ein Update im Parent machen. Einfach einen geplanten Callback machen. Siehe die ganzen On... Händler. Somit kann der Parent dem Kind sagen, wie er erreichbar ist, oder wer anderer der für das Ereignis zuständig ist.
Hmmm…….stimmt.
In mainform einen OnClose-handler, das dem close-ereignis von TFKalender zuweisen, im handler closeaction setzen, shape auf invisible, fertich
Hallo Zvoni und af0815,
jepp das wars.-danke Euch es funktioniert. :D

Andy Nightingale
Beiträge: 408
Registriert: Mo 13. Jan 2025, 12:11

Re: Shape schließen

Beitrag von Andy Nightingale »

Zvoni hat geschrieben: Di 5. Mai 2026, 17:24
af0815 hat geschrieben: Di 5. Mai 2026, 17:09 Ein Kind kann durchaus ein Update im Parent machen. Einfach einen geplanten Callback machen. Siehe die ganzen On... Händler. Somit kann der Parent dem Kind sagen, wie er erreichbar ist, oder wer anderer der für das Ereignis zuständig ist.
Hmmm…….stimmt.
In mainform einen OnClose-handler, das dem close-ereignis von TFKalender zuweisen, im handler closeaction setzen, shape auf invisible, fertich
Hallo Zvoni und af0815,
damit man nachvollziehen kann was ich gemacht habe hier die Anpassungen:
In der Unit1 (Main):

Code: Alles auswählen

procedure KalenderFormClose(Sender: TObject; var CloseAction: TCloseAction);
   private
    FKalender: TFKalender;
  public
Dann die Prozedur selbst:

Code: Alles auswählen

procedure TForm1.KalenderFormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
  BGRAShapeKalender.Visible := False;
  //FKalender.Free; // das hab ich dann rausgenommen, da es nur einmal funktioniert hat
  FKalender := nil; // Zeiger zurücksetzen
end;
Dann noch der Code für den Button:

Code: Alles auswählen

procedure TForm1.BCMaterialDesignButtonKalenderClick(Sender: TObject);
begin
  if not Assigned(FKalender) then
  begin
    FKalender := TFKalender.Create(Self);
    FKalender.OnClose := @KalenderFormClose;// funktioniert nur mit dem Zeichen da die Methode direkt angesteuert wird. verstehe aber das Prinzip nicht genau
    BGRAShapeKalender.Visible := True;
  end
  else
  begin
    FKalender.Show;
    BGRAShapeKalender.Visible := True;
  end;
end;
Viele Grüße an alle Helfer......ich hoffe das ich es so richtig gemacht habe. :roll: Es funktioniert, aber ich weiß ja nicht was im Hintergrund sonst noch passiert....

Benutzeravatar
Zvoni
Beiträge: 659
Registriert: Fr 5. Jul 2024, 08:26
OS, Lazarus, FPC: Windoof 10 Pro (Laz/FPC fixes)
CPU-Target: 64Bit
Wohnort: BW

Re: Shape schließen

Beitrag von Zvoni »

Verbesserung:

Code: Alles auswählen

procedure TForm1.BCMaterialDesignButtonKalenderClick(Sender: TObject);
begin
  BGRAShapeKalender.Visible:=True;
  If Not Assigned(FKalender) Then
    Begin
      FKalender:=TFKalender.Create(Self);
      FKalender.OnClose:=@KalenderFormClose;
    end;
  FKalender.Show;
end;       
In deiner Version wird im ersten Entscheidungsast der FKalender nur created, aber nicht angezeigt.
und dein Shape,Visible:=True kommt in beiden Ästen vor, also raus damit (davor oder danach)

"@" ist der sogenannte "Address"-Operator --> nimm die Speicher-Adresse der genannten Variablen/Objekts
In dieser Zeile sagt du "FKalender", das es für sein OnClose-Ereignis den Programmcode an genannter Speicheradresse ausführen soll, welches eben die
nach Aussen "unsichtbare" Prozedur "KalenderFormClose" ist.
Vom Prinzip ist es die "manuelle" Zuweisung, was du sonst im Objekt-Inspektor machst.
Ist hier die einzige Möglichkeit, da FKalender in einer eigenen Unit liegt, und nichts von der MainForm weiss (Weil nicht in Uses wegen Zirkelbezug)

Code: Alles auswählen

procedure TMainForm.KalenderFormClose(Sender: TObject;
  var CloseAction: TCloseAction);
begin
  CloseAction:=caNone;
  FreeAndNil(FKalender);
  BGRAShapeKalender.Visible:=False;
end;            
FKalender.Free funzte bei mir tatsächlich auch nicht. FreeAndNil behebt das aber.

Achtung: WICHTIG: Da du FKalender NICHT modal anzeigst, kann es in o.g. Code zum Knall kommen (in meiner als auch in deiner Variante), und zwar wenn der User zwar den Kalender öffnet, aber dann bei offenem FKalender die MainForm schliesst (was er kann, da FKalender die MainForm nicht blockiert).
Wenn er DANN den FKalender schliesst, knallts, weil FKalender dann einen Code ausführen will, welcher nicht mehr im Speicher ist.

Ich habs nicht getestet, ist also Vermutung, da das Create des FKalender mit Owner MainForm ausgeführt wird.
Weiss jetzt aus dem Stegreif auch nicht mehr, ob die MainForm dann FKalender mit ins Grab nimmt, wenn der User MainForm schliesst.
Ausprobieren
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.

Andy Nightingale
Beiträge: 408
Registriert: Mo 13. Jan 2025, 12:11

Re: Shape schließen

Beitrag von Andy Nightingale »

Danke Zvoni. :D

Antworten