Entwickler-Ecke

Multimedia / Grafik - fehlermeldung beim schliessen wenn timage dynamisch erstellt


Lemon - Sa 20.03.04 16:42
Titel: fehlermeldung beim schliessen wenn timage dynamisch erstellt
hallo,

habe hier ein script, dass erst in einem verzeichnis alle bilder auslesen soll und dann die moeglichkeit bietet, diese mit zwei button (vor und zurueck) anzuzeigen.
macht es auch alles.
aber wenn ich dann die scrollbox mit den TImage fuer die thumbnails erstelle, dann kommt beim schliessen des programms die fehlermeldung:

Exception EInvalidPointer in Modul Projekt1.exe
Ungültige Zeigeropreation

vorher nicht.
die thumbnails in der scrollbox werden auch richtig erstellt, da gibt es auch keine probleme, nur die fehlermeldung stoert.

und dann geht das ereignis ondblclick, dass beim dynamischen erstellen der timage erstellt werden soll nicht. da steht dann immer
Inkobpatible Typen: TNotifyEvent und procedure.

vielleicht hilft ja der quelltext.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
  //deklaration der variablen fuer allen prozeduren
  private
    { Private-Deklarationen }
    pics : TStrings;
    aktuell : Integer;
    bilder : Array of TImage;
  end;



procedure TForm1.FormCreate(Sender: TObject);
var
  gefunden: TSearchRec;
  i : Integer;
begin

  aktuell := 0;

  ChDir(ExtractFilePath(ParamStr(0)));

  pics := TStringList.Create;


  //bildernamen auslsen und in pics speichern 
  if (FindFirst('galerie\pictures\*.jpg',faDirectory,gefunden)=0then
  begin
    repeat
      if (gefunden.Name<>'.'and (gefunden.Name<>'..'then pics.Add(gefunden.Name);
    until FindNext(gefunden)<>0;
    FindClose(gefunden);
  end;

  //vorschaubilder in scrollbox anzeigen
  SetLength(bilder,pics.Count-1);

  for i := 0 to pics.Count-1 do
  begin
    bilder[i] := TImage.Create(ScrollBox1);
    bilder[i].Name := 'Image' + InttoStr(i);
    bilder[i].Parent := ScrollBox1;
    bilder[i].Left := 0;
    bilder[i].Top := i * 80;
    bilder[i].Center := True;
    //bilder[i].OnDblClick := bildladen(i);
    try
      bilder[i].Picture.LoadFromFile('galerie\thumbnails\' + pics[i]);
    except
      on EInvalidGraphic do bilder[i].Picture.Graphic := nil;
    end;
  end;
end;

//naechstes bild
procedure TForm1.Button2Click(Sender: TObject);
begin
  if aktuell < pics.Count-1 then inc(aktuell)
  else aktuell := 0;
  bildladen(-1);
end;

//vorhergehendes bild
procedure TForm1.Button1Click(Sender: TObject);
begin
  if aktuell > 0 then dec(aktuell)
  else aktuell := pics.Count-1;
  bildladen(-1);
end;

//bild auf  bildanzeige anzeigen lassen 
procedure TForm1.bildladen(index: Integer);
begin
  if index <> -1 then aktuell := index;
  try
    bildanzeige.Picture.LoadFromFile('galerie\pictures\' + pics[aktuell]);
  except
    on EInvalidGraphic do bildanzeige.Picture.Graphic := nil;
  end;
end;


vielen dank schon mal im vorraus.


derDoc - Sa 20.03.04 17:31

Ganz einfach:

Du setzt die Länge des Feldes bilder auf x

Delphi-Quelltext
1:
SetLength(bilder, pics.Count-1); // z.B. 6                    

und erzeugst x+1 (denn du fängst bei 0 an) Bilder

Delphi-Quelltext
1:
for i := 0 to pics.Count-1 do // z.B. 0 bis 6 = 7                    

daher kommt der Fehler. Zum Korrigieren einfach

Delphi-Quelltext
1:
SetLength(bilder, pics.Count); // im Beispiel 7                    

benutzen.


Lemon - So 21.03.04 12:00

gut, das funktioniert!!
und zu meinem doppelklickproblem??


derDoc - So 21.03.04 12:38

Das Problem dabei ist, dass du eine Prozedur mit dem Parameter Sender: TObject benötigst, um sie einem Ereignis zuzuweisen.

Delphi-Quelltext
1:
2:
3:
4:
5:
TForm1 = class(TForm)
  ...
  procedure BildLaden(Sender: TObject; Index: Integer);
private
  ...


Keldorn - So 21.03.04 12:42

dblclick hat doch nur einen paramter, einen index kannst du da nicht übergeben


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
type
  TForm1 = class(TForm)
...
  private
    { Private-Deklarationen }
    procedure Bildladen(Sender: TObject);
  public
...

procedure TForm1.Bildladen(Sender: TObject);
begin
  if sender is Timage then
    (sender as Timage).Picture.LoadFromFile(wasweißichwas);
end;

...

    bilder[i] := TImage.Create(ScrollBox1);
...
    bilder[i].OnDblClick := bildladen;

...


Mfg Frank


derDoc - So 21.03.04 13:04

Sorry, mein Fehler.

Hier nun die Lösung für den konkreten Fall:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
type
  TForm1 = class(TForm)
    ...
    procedure ImgDblClick(Sender: TObject);
  private
    ...

implementation

...

procedure TForm1.ImgDblClick(Sender: TObject);
begin
  if (Sender is TImage) then
    Image1.Picture := (Sender as TImage).Picture; // Image1 ist das große Image (bildanzeige bei dir)
end;

...
  Bilder[i].OnDblClick := ImgDblClick;
...


Lemon - So 21.03.04 14:42

das hilft mir jetzt leider gar nicht, da ich ja den bildindex als parameter mitgeben will, um ihn dann aktuell zuzuweisen.
geht das nicht ander???


raziel - So 21.03.04 14:58

speicher halt den index im Tag:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
  for i := 0 to pics.Count-1 do
  begin
    bilder[i] := TImage.Create(ScrollBox1);
(...)
    bilder[i].Tag := i;
  end;


Auslesen kannstes später so:

Delphi-Quelltext
1:
2:
3:
4:
5:
procedure TForm1.Bildladen(Sender: TObject);
begin
  if sender is Timage then
    (sender as Timage).Picture.LoadFromFile('galerie\pictures\' + pics[(Sender as TImage).Tag)]);
end;



raziel


derDoc - So 21.03.04 17:24

Ich glaube du verstehst nicht, was ich meine.

Du bleibst bei deiner Bildladen Prozedur, fügst jedoch eine neue (ImgDblClick) ein, die du nur zum Doppelklicken benutzt. Darin kannst du doch auch aktuell zuweisen, z.B. über den Tag, oder über ein weiteres Feld.


Lemon - So 21.03.04 21:52

danke, jetzt geht alles wie ich das wollte...