![]() |
fehler bei timage.destroy
hallo leute
probier gerade mit grafiken rum und bin auf ein problem gestossen. kurze erklärung. ich öffne bilder und plaziere sie auf einem panel in timage's welche ich dynamisch erzeuge. da die bilder recht klein sind erzeuge ich beim anklicken ein grösseres vorschaubild. klappt auch alles ganz gut. jetzt möchte ich aber das vorschaubild wieder weghaben, was auch durchs anklicken realisiert werden soll. öffne ich mit dem prog nur 3 bilder dann gibt es keine probleme, sind es mehr als 3 dann kommt ein fehler - ' zugriffsverletzung bei adresse ...' - . kann mir das ganze nicht erklären. wohlgemerkt, der fehler kommt erst beim versuch das vorschaubild zu schliessen.
Delphi-Quellcode:
unit prog;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls, ExtDlgs, FileCtrl, jpeg; type Tfenster = class(TForm) back: TPanel; oeffnen: TButton; beenden: TButton; open: TOpenPictureDialog; laufwerk: TDriveComboBox; ordner: TDirectoryListBox; datei: TFileListBox; procedure beendenClick(Sender: TObject); procedure oeffnenClick(Sender: TObject); procedure klicken(Sender: TObject); procedure weg(Sender :TObject); procedure FormCreate(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var fenster: Tfenster; implementation {$R *.dfm} procedure Tfenster.beendenClick(Sender: TObject); begin close end; {grösseres vorschaubild erzeugen} procedure Tfenster.klicken(Sender: TObject); var w :string; bild :TImage; begin if sender is timage then begin w := (sender as timage).HelpKeyword; end; bild:=TImage.Create(back); bild.Parent := back; bild.Picture.LoadFromFile(w); bild.IncrementalDisplay := true; bild.Stretch := true; bild.Top := 150; bild.Left := 150; if bild.Picture.Graphic.Height > bild.Picture.Graphic.Width then begin bild.Height := 300; bild.Width := 227; end else begin bild.Height := 227; bild.Width := 300; end; bild.HelpKeyword := inttostr(bild.ComponentIndex); bild.OnClick := weg; end; {vorschaubild entfernen} procedure Tfenster.weg(Sender :TObject); var b :integer; begin if sender is timage then begin b := strtoint((sender as timage).HelpKeyword); back.Components[b].destroy; end; end; procedure Tfenster.oeffnenClick(Sender: TObject); var img :TImage; i,links,z,oben :integer; begin {vorhandene bilder entfernen} for z := back.ComponentCount-1 downto 0 do begin back.Components[z].Free; end; {bilder öffnen und anordnen} if open.Execute then begin links := 5; img.Top := 5; oben := img.Top; for i := 0 to open.Files.count-1 do begin img:=TImage.Create(back); img.Parent := back; img.Picture.LoadFromFile(open.Files[i]); img.IncrementalDisplay := true; img.Stretch := true; img.Hide; img.HelpKeyword := open.Files[i]; img.OnClick := klicken; if links + 75 > back.Width then begin links := 5; oben := oben + 80; end; {bildgrösse und position anpassen} if img.Picture.Graphic.Height > img.Picture.Graphic.Width then begin img.Height := 70; img.width := 53; if i >= 1 then begin img.Left := links; links := links + img.Width + 5; img.Top := oben; end else begin img.Left := links; links := links + img.Width + 5; img.Top := oben; end; img.Transparent := true; img.Show; end else begin img.Height := 53; img.Width := 70; if i >= 1 then begin img.Left := links; links := links + img.Width + 5; img.Top := oben; end else begin img.Left := links; links := links + img.Width + 5; img.Top := oben; end; img.Transparent := true; img.Show; end; end; end; end; {componenten anordnen} procedure Tfenster.FormCreate(Sender: TObject); begin ordner.Left := screen.WorkAreaWidth - ordner.Width - datei.Width - 20; datei.Left := screen.WorkAreaWidth - datei.Width - 20; laufwerk.Left := datei.Left; back.Top := oeffnen.Top + (oeffnen.Height *2); ordner.Top := back.Top; datei.Top := back.Top; fenster.Width := screen.WorkAreaWidth; fenster.Height := screen.WorkAreaHeight; fenster.Left := 0; fenster.top := 0; back.Height := screen.WorkAreaHeight - (back.Top + 30); back.Width := screen.WorkAreaWidth - ordner.Width - datei.Width - 28; ordner.Height := back.Height; datei.Height := ordner.Height; beenden.Top := oeffnen.top; end; end. nicht wundern, drivecombo,directorylistbox und filelistbox will ich erst später einbinden, sind nur visuell vorhanden. das mit dem img.helpkeyword ist ein versuch von mir, habe bisher keine andere möglichkeit gefunden den pfad mit dateinamen zu übermitteln, bin noch nicht so belesen in delphi. danke schon im voraus. mato |
Re: fehler bei timage.destroy
Du solltest niemals Destory direkt aufrufen. Dafür ist die Free-Methode zuständig.
Noch sicherer ist es mit FreeAndNil zu arbeiten. Damit wird auch der Zeiger auf nil gesetzt, so das man nicht versehentlich mehrmals ein Objekt freigibt. |
Re: fehler bei timage.destroy
danke für den tip, der fehler tritt aber trotzdem noch auf.
mato |
Re: fehler bei timage.destroy
Hoi, in welcher Zeile bleibt der Debugger denn stehen?
|
Re: fehler bei timage.destroy
also wie gesagt, bin noch nicht soweit in delphi. aber wenn ich das richtig interpretiere, hier.
Delphi-Quellcode:
{vorschaubild entfernen}
procedure Tfenster.weg(Sender :TObject); var b :integer; begin if sender is timage then begin b := strtoint((sender as timage).HelpKeyword); [i]back.Components[b].Free;[/i] end; end; |
Re: fehler bei timage.destroy
habe gerade nochmal probiert, der fehler tritt auch manchmal bei weniger als 4 geöffneten bildern auf, aber eben nur manchmal. habe auch mal andere grafiken geöffnet, kam immer ein fehler. könnte das was mit der grösse der geöffneten bilder zu tun haben?
mato |
Re: fehler bei timage.destroy
Was für einen Index speicherst du in HelpKeyword? Versuch mal nicht den Weg über Indizes zu gehen, speichere stattdessen den Zeiger auf das Objekt .
Du kannst auch einen neuen Typ von TImage ableiten, der so ein Feld besitzt:
Delphi-Quellcode:
In LinkedObj kannst du dann den Zeiger auf ein beliebiges Objekt speichern:
type
TLinkedImage = class(TImage) private FLinkedObj: TObject; published LinkedObj: TObject read FLinkedObj write FLinkedObj; end;
Code:
[edit=Luckie]Tags korrigiert. fg, Luckie[/edit]
procedure TForm1.Button1Click(Sender: TObject);
begin with TLinkedImage.Create(Self) begin; Bild.Parent := EinPanel; Bild.LinkedObj := Sender; {...} end; end; |
Re: fehler bei timage.destroy
Zitat:
noch innerhalb eines Events befindet (OnClick). siehe Code-library: ![]() |
Re: fehler bei timage.destroy
in helpkeyword speichere ich nur den index des vorschaubildes welches sich ja auch auf dem panel befindet. dadurch kann ich auf das teil zugreifen und somit auch entfernen (oder auch nicht).
werde deinen vorschlag mal aufgreifen, muss mich dann aber erst mal belesen, wie gesagt, so toll kenne ich mich noch nicht aus. mato |
Re: fehler bei timage.destroy
Zitat:
mato |
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:09 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 by Thomas Breitkreuz