Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi erzeugts IImage Löschen? (https://www.delphipraxis.net/89914-erzeugts-iimage-loeschen.html)

smart 8. Apr 2007 14:14


erzeugts IImage Löschen?
 
Hallo Alle!

Wenn ich so ein TImage erzeuge:
Delphi-Quellcode:
I := I + 1;
Mein_Bild[I] := TImage.Create(Form1);
  With Mein_Bild[I] do
    begin
      Parent := Form1;
        ......
Wie kann ich es dann wider löschen?

Mit z.B.
Delphi-Quellcode:
Mein_Bild[0].Free
bekomme ich eine Fehlermeldung: Zugriffsverletzung bei Adresse ...

Gruß
Heike

Neutral General 8. Apr 2007 14:32

Re: erzeugts IImage Löschen?
 
Hi,

Also normalerweise dürfte das kein Problem sein. Zeig mal bisschen Code. Folgendes funktioniert nämlich ohne Probleme...

Delphi-Quellcode:
var
  Test: Array[0..1] of TImage;

procedure TForm1.Button1Click(Sender: TObject);
var i: Integer;
begin
  for i:= 0 to 1 do
  begin
    Test[i] := TImage.Create(Self);
    with Test[i] do
    begin
      Parent := Self;
      Picture.Bitmap := ABitmap;
      Left := i* 100;
    end;
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var i: Integer;
begin
  for i:= 0 to 1 do
   Test[i].Free
end;

Blackheart 8. Apr 2007 14:36

Re: erzeugts IImage Löschen?
 
Mein_Bild[0].Free - i wird wohl bei 0 anfangen schätz Ich mal dann gibt es 0 nicht Mein_Bild[1].Free.

smart 8. Apr 2007 14:44

Re: erzeugts IImage Löschen?
 
Hi.

Ich erzeuge (wie oben) z.B. 10 TImages (von 0 bis 9).
Also:
Mein_Bild[0]
Mein_Bild[1]
Mein_Bild[2]
Mein_Bild[3]
.....

Dann möchte ich z.B. Mein_Bild[2] löschen. Und genau das klappt nicht?

Gruß
Heike

inherited 8. Apr 2007 15:16

Re: erzeugts IImage Löschen?
 
Mit welchem Wert wird I initialisiert?
Wenn 0, dann fängt er erst bei 1 an Bilder zu erzeugen, weil ja vorher I erhöht wird. Zeig mal ein wenig mehr Code.

smart 8. Apr 2007 18:45

Re: erzeugts IImage Löschen?
 
Hi.

So erzeuge ich die Images:
Delphi-Quellcode:
Var I:Integer;
...

I := 0;
...

I := I + 1;
Mein_Bild[I] := TImage.Create(Form1);
  With Mein_Bild[I] do
    begin
      Parent := Form1;
      Width := Bild.Width div 5;
      Height := Bild.Height div 5;
      Tag := I;
      Stretch := True;
      Picture.Bitmap := Bild;
      OnClick := LosClick;
    end;
Wenn ich mit der Maus auf dem entsprechende Bild klicke soll es löschen:
Delphi-Quellcode:
procedure TForm1.LosClick(Sender: TObject);
begin
   Mein_Bild[TImage(Sender).Tag].Free;
end;
Gruß
Heike

inherited 8. Apr 2007 19:14

Re: erzeugts IImage Löschen?
 
Zum löschen: Warum so kompliziert? Gib doch direkt den Sender frei.
Zu deinem Problem: Mein_Bild[0] wird nie erzeugt, das erste erzeugte Bild ist Mein_bild[1]

Blackheart 8. Apr 2007 19:17

Re: erzeugts IImage Löschen?
 
Und das zum Dritten mal. :wink:

smart 9. Apr 2007 09:22

Re: erzeugts IImage Löschen?
 
Hi!

Zitat:

Zitat von inherited
Zum löschen: Warum so kompliziert? Gib doch direkt den Sender frei.

Wie meinst Du das, den Sender frei geben?
Zitat:

Zitat von inherited
Zu deinem Problem: Mein_Bild[0] wird nie erzeugt, das erste erzeugte Bild ist Mein_bild[1]

Das wa auch nur ein Beispiel, bei 0 hatte ich natürlich (I := -1; ). Wie Du den obigen Code entnehmen kannst, wird immer automatisch
der richtge Sender übergeben. Trozdem bekomme ich die Fehlermeldung. Da komme ich einfach nicht dahinter.

Gruß
Heike

xaromz 9. Apr 2007 09:38

Re: erzeugts IImage Löschen?
 
Hallo,

sehe ich das richtig, dass Du in der Click-Methode eines TImage selbiges freigeben möchtest? Das kann nicht funktionieren. Nachdem die Routine fertig ist, geht es ja zurück in den Code von TImage. Leider existiert das TImage aber jetzt nicht mehr. Also krachts.

Gruß
xaromz

smart 9. Apr 2007 09:42

Re: erzeugts IImage Löschen?
 
Zitat:

Zitat von xaromz
Das kann nicht funktionieren. Nachdem die Routine fertig ist, geht es ja zurück in den Code von TImage. Leider existiert das TImage aber jetzt nicht mehr. Also krachts.

Ja, Du hast Recht, dass hatte ich nicht bedacht. Wie würdest Du das lösen?

Gruß
Heike

mkinzler 9. Apr 2007 09:54

Re: erzeugts IImage Löschen?
 
Du könntest das Image im .onClick nur markieren bzw deren Index wegschreiben und dann aüßerhalb des Images freigeben.

marabu 9. Apr 2007 10:01

Re: erzeugts IImage Löschen?
 
Hallo,

die Freigabe einer visuellen Komponente im OnClick() ist für sich genommen kein Problem. Vielleicht liegt der Fehler an einer anderen Stelle?

Freundliche Grüße

xaromz 9. Apr 2007 11:10

Re: erzeugts IImage Löschen?
 
Hallo,

Zitat:

Zitat von marabu
die Freigabe einer visuellen Komponente im OnClick() ist für sich genommen kein Problem.

Grundsätzlich nicht. Aber schau mal, was passiert, wenn die Komponente in ihrem OnClick freigegeben wird:
Delphi-Quellcode:
procedure TControl.Click; (vereinfacht)
begin
  if Assigned(FOnClick) then
    FOnClick(Self); // OnClick aufrufen, Self wird freigegeben
  // Jetzt sind wir hier, in einem nicht mehr existirenden Objekt. Irgendwie blöd, oder?

end; // Zurück nach TControl.WMLButtonUp -> Upps, AV!
Gruß
xaromz

marabu 9. Apr 2007 12:01

Re: erzeugts IImage Löschen?
 
Hallo Martin,

es wird nichts passieren, solange kein Zugriff auf Daten des freigegebenen Objektes erfolgt. Ziehe TImage-Komponenten auf eine Form und verwende diesen gemeinsamen event handler:

Delphi-Quellcode:
procedure TDemoForm.ImageClick(Sender: TObject);
begin
  with Sender as TComponent do
    Free;
end;
Es funktioniert, aber Borland (D7 VCL) warnt pauschal vor einer solchen Vorgehensweise.

Um auch einmal dieses wundervolle Wort zu verwenden: Grundsätzlich würde ich es ganz anders machen. Ich habe schon mit der von Markus erwähnten Vormerkung gearbeitet und im Event OnIdle() die Komponenten freigegeben, aber besser noch gefällt mir der Ansatz über eine eigene application message (PostMessage) und einen speziellen message handler.

Freundliche Grüße

xaromz 9. Apr 2007 12:31

Re: erzeugts IImage Löschen?
 
Hallo,
Zitat:

Zitat von marabu
es wird nichts passieren, solange kein Zugriff auf Daten des freigegebenen Objektes erfolgt.

Du hast Recht, solange Du keine weiteren Speicheroperationen durchführst. Die VCL greift dann nämlich immer auf Daten zu. Aber sie greift auf den bereits freigegebenen, aber immer noch mit den richtigen Werten gefüllten Speicher zu.

Versuche mal folgendes:
Delphi-Quellcode:
procedure TForm1.Image1Click(Sender: TObject);
var
  P: Pointer;
begin
  P := Pointer(Sender);
  TControl(Sender).Free;

  FillChar(P^, 4, 0); // Objektspeicher überschreiben
end;
Das ist jetzt zwar konstruiert, aber wenn zufälllig ein neues Objekt erzeugt wird, das den Speicher des zerstörten verwendet (moderne Speichermanager machen sowas gerne), dann hast Du ein Problem.

Zitat:

Zitat von marabu
... aber besser noch gefällt mir der Ansatz über eine eigene application message (PostMessage) und einen speziellen message handler.

Genau so mache ich das auch immer. Ist meiner Ansicht nach das einzig saubere.

Gruß
xaromz

smart 9. Apr 2007 13:08

Re: erzeugts IImage Löschen?
 
Hi xaromz!

Zitat:

Zitat von xaromz
..Genau so mache ich das auch immer. Ist meiner Ansicht nach das einzig saubere.

So habe ich das noch nicht gemacht. Kannst Du mir bitte einmal einen Ansatz geben?

Gruß
Heike

Hawkeye219 9. Apr 2007 13:15

Re: erzeugts IImage Löschen?
 
Hallo Heike,

in diesem Beitrag findest du alles, was du benötigst. Dort wird zwar ein Button entfernt, aber das Prinzp ist das gleiche.

Gruß Hawkeye

smart 9. Apr 2007 13:32

Re: erzeugts IImage Löschen?
 
Zitat:

Zitat von Hawkeye219
Hallo Heike,

in diesem Beitrag findest du alles, was du benötigst. Dort wird zwar ein Button entfernt, aber das Prinzp ist das gleiche.

Gruß Hawkeye

Danke, für den Hinweis!
Klappt wunderbar und vorallen ohne Fehler ;-)

Gruß
Heike


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:36 Uhr.

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