Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi fehler bei timage.destroy (https://www.delphipraxis.net/38365-fehler-bei-timage-destroy.html)

mato 18. Jan 2005 10:01


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

Bernhard Geyer 18. Jan 2005 10:06

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.

mato 18. Jan 2005 10:11

Re: fehler bei timage.destroy
 
danke für den tip, der fehler tritt aber trotzdem noch auf.

mato

Dani 18. Jan 2005 10:16

Re: fehler bei timage.destroy
 
Hoi, in welcher Zeile bleibt der Debugger denn stehen?

mato 18. Jan 2005 10:29

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;

mato 18. Jan 2005 10:35

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

Dani 18. Jan 2005 10:59

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:
type
 TLinkedImage = class(TImage)
  private
   FLinkedObj: TObject;
  published
   LinkedObj: TObject read FLinkedObj write FLinkedObj;
 end;
In LinkedObj kannst du dann den Zeiger auf ein beliebiges Objekt speichern:
Code:
procedure TForm1.Button1Click(Sender: TObject);
begin
 with TLinkedImage.Create(Self)
  begin;
   Bild.Parent := EinPanel;
   Bild.LinkedObj := Sender;
   {...}
  end;
end;
[edit=Luckie]Tags korrigiert. fg, Luckie[/edit]

shmia 18. Jan 2005 11:07

Re: fehler bei timage.destroy
 
Zitat:

Zitat von mato
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?

Es hat eher was damit zu tun, dass du ein Steuerelement (Control) zerstörst, obwohl das Programm sich
noch innerhalb eines Events befindet (OnClick).
siehe Code-library: http://www.delphipraxis.net/internal...ct.php?t=29732

mato 18. Jan 2005 11:11

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

mato 18. Jan 2005 11:15

Re: fehler bei timage.destroy
 
Zitat:

Es hat eher was damit zu tun, dass du ein Steuerelement (Control) zerstörst, obwohl das Programm sich noch innerhalb eines Events befindet (OnClick).
danke erstmal, klingt logisch, man muss nur drauf kommen.

mato


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:34 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