Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Prism Problem beim Zugriff auf Komponenten (https://www.delphipraxis.net/75803-problem-beim-zugriff-auf-komponenten.html)

gfjs 25. Aug 2006 05:41


Problem beim Zugriff auf Komponenten
 
Guten Morgen, Allerseits.

Leider ist mir kein aussagekräftigerer Titel eingefallen - hier nun mein Problem:

Auf einem Panel werden zur Laufzeit 27x27 Labels erzeugt. Wird ein Label angeklickt, sollen in allen Labels der selben Spalte, die den gleichen Text enthalten wie das angeklickte Label, der Text gelöscht werden. Ich habe das so gelöst:

Delphi-Quellcode:
begin
  TempLabel           := System.Windows.Forms.&Label.Create;
  // speichert das angeklickte Label in TempLabel
  TempLabel           := Sender as System.Windows.Forms.&Label;

  for I := 0 to Self.Panel1.Controls.Count - 1 do
  begin
    if (Panel1.Controls[i].Left = TempLabel.Left)
    AND (TempLabel.Text = Panel1.Controls[i].Text) then
    begin
      Panel1.Controls[i].Text := '';
    end;
    // Kontrollanzeige
    TBText.Text := TBText.Text + i.ToString + ': ' + TempLabel.Text + ' - ' + Panel1.Controls[i].Text + #13#10;
  end;
Dabei tritt folgendes Problem auf:

Wenn der erste Vergleich "true" ist, wird auch TempLabel.Text verändert und enthält dann einen leeren String, so dass alle weiteren Vergleiche "false" ergeben.

Ich kann mir das nicht erklären, da m.E. die Zuweisung des angeklickten Labels an TempLabel ausserhalb der Schleife vorgenommen wird und in der Schleife keine weitere Zuweisung erfolgt. Das scheint aber offensichtlich doch nicht so zu sein. Wo liegt mein Denkfehler?

Für jeden Hinweis bin ich wie immer dankbar.

mfg gfjs;

mkinzler 25. Aug 2006 05:48

Re: Problem beim Zugriff auf Komponenten
 
Zitat:

Delphi-Quellcode:
TempLabel           := System.Windows.Forms.&Label.Create;

Warum erzeugst du hier ein neues Label?

gfjs 25. Aug 2006 05:51

Re: Problem beim Zugriff auf Komponenten
 
Um mir das wiederholte
Delphi-Quellcode:
(Sender as System.Windows.Forms.&Label).irgendwas
zu ersparen. Ich dachte, das wäre einfacher.

nfg gfjs

mkinzler 25. Aug 2006 05:53

Re: Problem beim Zugriff auf Komponenten
 
Dazu mußt du dir aber doch kein neues Label erzeugen.

gfjs 25. Aug 2006 06:02

Re: Problem beim Zugriff auf Komponenten
 
Dank eines "Gestesblitzes" habe ich mein Problem vorerst so gelöst:
Delphi-Quellcode:
begin
  TempLabel           := System.Windows.Forms.&Label.Create;
  TempLabel           := Sender as System.Windows.Forms.&Label;
  s                   := TempLabel.Text; // <<<<<<<
  for I := 0 to Self.Panel1.Controls.Count - 1 do
  begin
    if (Panel1.Controls[i].Left = TempLabel.Left)
    AND [b](Panel1.Controls[i].Text = s)[/b] then // <<<<<<<
    begin
      Panel1.Controls[i].Text := '';
    end;
TBText.Text := TBText.Text + i.ToString + ': ' + TempLabel.Text + ' - ' + Panel1.Controls[i].Text +  ' > ' + s + #13#10;
  end;
Das löst aber noch nicht mein Verständnisproblem, warum TempLabel.Text in der ersten Version der Procedur verändert wird. - Wer kann mir da weiterhelfen?

mfg Jürgen

@ mkinzler

Danke für Deine Mithilfe. Ich bin aber noch ein ziemlicher Anfänger, so dass ich sicher manches Problem auf etwas umständlich angehe. Wie sollte ich es Deinem Meinung nach machen?

mkinzler 25. Aug 2006 07:09

Re: Problem beim Zugriff auf Komponenten
 
Das erzeugen einer neuen Label-Komponente kannst du dir aber wirklich sparen. Das führt wirklich nur zu Speicher-Leaks. Bei jedem Aufruf der Methode, wird ein neues Label-Objekt erzeugt, was nie verwendet wird!

gfjs 25. Aug 2006 08:35

Re: Problem beim Zugriff auf Komponenten
 
@ mkinzler

Wie schon erwähnt bin ich noch Anfänger und hatte mir folgendes überlegt:

Auf dem Panel befinden sich 27x27=729 zur Laufzeit erzeugte Labels. Wenn ich jetzt in der Click-Prozedur auf Eigenschaften zugreife (was relativ häufig vorkommt), muss ich jedesmal (sender as System.Windows.Forms.&Label).Eigenschaft eingeben. Das wollte ich mir dadurch ersparen. Die einzige andere Lösung, die mir noch einfällt, wäre:
Delphi-Quellcode:
with (sender as System.Windows.Forms.&Label) do
begin
  do something;
end;
Da müsste ich jetzt aber ziemlich viel in meinem Quelltext ändern. Deshalb meine Frage: Kann ich bei meinem TempLabel bleiben, wenn ich es am Ende der Prozedur explizit freigebe (und wenn ja mit welcher Anweisung)? Oder soll ich auf die o.a. Lösung umsteigen? Oder ist beides ein "Schmarrn" (wie man bei uns in Bayern sagt)?

Ausserdem habe ich noch immer nicht herausgefunden, warum in der Prozedur meines ersten Posts innerhalb der Schleife der Wert von TempLabel.Text verändert wurde.

Ich hoffe, ich strapziere Deine (bzw. Euere) Geduld nicht zu sehr mit meinen Anfängerfragen.

Servus aus München

Jürgen

mkinzler 25. Aug 2006 08:41

Re: Problem beim Zugriff auf Komponenten
 
Ja, schon klar funktioniert auch so, aber die erste Zeile ist unnötig!!! laß sie doch einfach mal weg, und du wirst sehen es funktioniert trotzdem.
Zitat:

Deshalb meine Frage: Kann ich bei meinem TempLabel bleiben, wenn ich es am Ende der Prozedur explizit freigebe (und wenn ja mit welcher Anweisung)?
Wie gesagt, keines erzeugen, dann mußt du auch keines freigeben. Im Gegenteil, wenn du versuchst das refernzierte Objekt freizugeben gibtst du nicht das am Anfang erzeugte frei, sondern den Sender!

gfjs 25. Aug 2006 09:03

Re: Problem beim Zugriff auf Komponenten
 
@ mkinzler

Danke! Hab' zwar nicht alles verstanden, aber Deinen Rat befolgt.

mfg Jürgen

mkinzler 25. Aug 2006 09:17

Re: Problem beim Zugriff auf Komponenten
 
Objektvariablen sind Referenzen (Zeiger).
Ein Create erzeugt nun ein neues Label-Objekt im Speicher (ein 730.) und liefert einen Zeiger auf dessen Speicherbereich zurück. das neu erzeugt Label hat weder Owener noch Parent und ist namenlos.
Im nächsten Schritt weist du der Objektvariable den Sender zu, das heißt die Variable zeigt jetzt auf den Sender.
Gibst du nun das Objekt frei, wird das Objekt auf den die Variable zeigt freigegeben. Das neu erzeugte Label kannst du so gar nicht mehr freigeben, da du ja keinen Zugriff mehr darauf hast.
Beim jedem Aufruf wird also ein neues Label im Speicher erstellt, was keine Funktion hat aber Speicher belegt.


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:44 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz