Autor Beitrag
wolfproductsInc
Hält's aus hier
Beiträge: 6



BeitragVerfasst: Do 03.04.14 00:30 
Hallo, ich versuche bilder über eine "if" schleife in mein Imageliste einzutragen.
Jedoch kommt da die fehlermeldung: EAccesviolation (Acces violation at adress 0045937E)

Queltext:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
procedure TForm2.ComboBox2Change(Sender: TObject);
var  Bilderverzeichnis:Array[1..16of TBitMap; x:integer;
begin
x:=1;
case Combobox2.ItemIndex of
0begin
form1.imglist.Clear;
for x:=min to max do
bilderverzeichnis[x].loadfromfile('BILDER\'+inttostr((x-1div 2));
Form1.imglist.Add(bilderverzeichnis[X],nil) ;
inc(x);  end;


Wobei die Bilddateien 1 bis 8 benannt sind. Es soll jeweils 2 mal das gleiche bild eingetragen werden.
Syntax ist in ordnung, aber wenn ich den Combobox ändere stürtzt das Programm ab. Imagelist gehört zu ein andere form
als der wo Procedure comboboxchange deklariert ist.

Hilfe wäre höchst willkommen, ich versuche schon 2 stunden das hinzubekommen, vvl kann jemand von euch mich weiterhelfen

Moderiert von user profile iconMartok: Delphi-Tags hinzugefügt
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: Do 03.04.14 10:11 
Erste Maßnahme sollte sein, den Quelltext korrekt einzurücken, damit Du siehst, welche Anweisungen in der Schleife stehen und welche nicht. Wo sind min und max definiert und welche Werte haben die? Die Variable x wird in der Schleife schon mit Werten versorgt, das musst Du weder vorher machen, noch selber den Wert erhöhen.

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
Perlsau
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Do 03.04.14 12:08 
Was mir als erstes auffällt: Du schreibst von einer IF-Schleife. Sowas gibt jedoch es nicht. Schleifen sind Programmstrukturen, die bestimmte Befehle wiederholen, bis eine Abbruchbedingung zutrifft. Das IF-THEN-Konstrukt stellt lediglich eine Bedingung dar, nach der etwas ausgeführt wird oder auch nicht.

Als nächstes fällt mir auf, daß du offenbar drei Befehle in einer FOR-NEXT-Schleife abarbeiten willst. Dazu mußt du diese drei Befehle in einen BEGIN-END-Block einschließen, sonst wird nur der erstte Befehl nach DO ausgeführt.

Dann fällt noch auf, daß du in der FOR-NEXT-Schleife x als Zähler verwendest und x in der Schleife noch einmal erhöhst. Wenn du alle x abarbeiten willst, ist das Unsinn.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
procedure TForm2.ComboBox2Change(Sender: TObject);
var
  Bilderverzeichnis : Array[1..16of TBitMap; 
  x                 : integer;
begin
  x := 1;
  case Combobox2.ItemIndex of
  0 : begin
        form1.imglist.Clear;
        for x := min to max do
        begin
          bilderverzeichnis[x].loadfromfile('BILDER\'+inttostr((x-1div 2));
          Form1.imglist.Add(bilderverzeichnis[x],nil) ;
          // inc(x);
        end// For-Schleife
      end// 0 : begin
  end// Case-Block
end// Procedure-Ende


An diesem Quelltext kannst du nun auch gleich sehen, wie man lesbar formatiert.
wolfproductsInc Threadstarter
Hält's aus hier
Beiträge: 6



BeitragVerfasst: Do 03.04.14 12:32 
In mein Projekt ist die Queltext schon übersichtlicher gestalten, ist beim Kopieren verloren gegangen. Es stimmt schon das mein Queltext unübersichtlich war

Min und Max sind beide Konstante die in Form 1 Global deklariert wurden. Bis jetzt hab ich die Bilder direkt in das imagelist eingetragen, also Doppelklick auf das Icon.
Ich möchte die Bilderliste Ändern mit einen Combobox, die sich auf ein anderen Formular befindet (Ueinstellungen). Beim Ändern der Combo box wird geprüft welchen
itemindex vorhanden ist, und dann sollten die jeweiligen Bilder in die Imagelist eingetragen werden. Es gibt immer 8 bilder pro Thema, also Thema 1 hat 8 Bilder mit unterschiedlichen Fahnen,
Thema 2 dann 8 Bilder mit Unterschiedlichen periodischen Elemente. Nachdem ich dann ein neues Thema über der Combobox gewählt habe sollten die jeweiligen Bilder automatisch in die Imagelist
eingetragen werden.

Im Grunde genommen habe ich so gesehen, beim Änderung des Comboboxes wird die Itemindex geprüft, dann wird zuerst der Imgagelist wieder freigegeben (Imagelist.clear), von min zu max (1 zu 16)
die Bilder in ein Array geladen da Imagelist nur schon vorhandene Bitmaps verwenden kann, und dann über Form1.imgList.add die Bilder des arrays eingetragen. Ich habe wahrscheinlich einige Denkfehler, aber habe sie
bis jetzt noch nicht gefunden. Als 2. wert braucht imagelist.add ein mask (Tbitmap), was wird damit gemeint? Der Fehlermeldung Kommt allerdings schon bei: bilderverzeichnis[x].loadfromfile('STARWARS\'+inttostr((x-1) div 2));

Und Danke für euren Antworten, ich suche immer noch nach eine lösung aber ihr habt mir schon weitergeholfen
Perlsau
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Do 03.04.14 12:37 
user profile iconwolfproductsInc hat folgendes geschrieben Zum zitierten Posting springen:
Der Fehlermeldung Kommt allerdings schon bei: bilderverzeichnis[x].loadfromfile('STARWARS\'+inttostr((x-1) div 2));

This error message is top secret! After we told you we have to kill you!
wolfproductsInc Threadstarter
Hält's aus hier
Beiträge: 6



BeitragVerfasst: Do 03.04.14 12:40 
Einen Acces violation auf mein rechner wäre kaum "Top secret" :D
zuma
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 660
Erhaltene Danke: 21

Win XP, Win7, Win 8
D7 Enterprise, Delphi XE, Interbase (5 - XE)
BeitragVerfasst: Do 03.04.14 12:48 
was hälst du davon, ein Objekt vor dessen benutzung erstmal zu erzeugen ?
Accesviolation deutet fast immer darauf hin, das man auf etwas zugreift, was nicht da ist ;)

zuma

_________________
Ich habe nichts gegen Fremde. Aber diese Fremden sind nicht von hier! (Methusalix)
Warum sich Sorgen ums Leben machen? Keiner überlebts!
Perlsau
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Do 03.04.14 12:55 
Deshalb hast du die Fehlermeldung ja auch geheim gehalten, nicht wahr?. Mit anderen Worten: Hinweise wie "es funktioniert nicht" oder "es kommt eine Fehlermeldung" sind nicht besonders hilfreich, wenn der Inhalt der Fehlermeldung zurückgehalten wird.

Du erhältst also eine Zugriffsverletzung, wenn du auf ein TBitmap in deinem Array zugreifen willst. Das ist nicht weiter verwunderlich, denn dort befindet sich keine entsprechende Objekt-Struktur. Weißt du, was ein Objekt ist?

Objekte verwaltet man in einer TObjectList, nicht in einem Array. Das benötigst du aber nicht wirklich, um dein Problem zu lösen.

Ein TBitmap muß vor der Verwendung erst einmal erzeugt werden. Da sich die zu landenden Bilder sowieso auf deiner Festplatte befinden, speicherst du lediglich die jeweiligen Dateinamen und lädst sie in ein Array of String oder besser in eine Stringliste. Oder du wählst für deine Bitmaps gleich sprechende Bezeichnungen wie z.B. Thema01_01.bmp, Thema01_02.bmp usw. Die lädst du dann in ein zuvor erzeugtes TBitmap und weist dieses Bitmap mit TImageList.Add zu.

Ich will dir jetzt aber nicht das ganze Procedere schreiben, das kriegst du sicher alleine hin.
Blup
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 173
Erhaltene Danke: 43



BeitragVerfasst: Do 03.04.14 13:05 
Du definierst ein Array mit Plätzen für 16 Objekten vom Typ TBitmap.
Das Array ist zwar da, aber wo ist der Inhalt?
Tatsächlich ist der Inhalt undefiniert, da den einzelnen Plätzen noch nichts zugewiesen wurde.
ausblenden Delphi-Quelltext
1:
2:
  for x := Low(bilderverzeichnis) to High(bilderverzeichnis)
    bilderverzeichnis[x] := TBitmap.Create;

Dein Array ist nur lokal in der Methode ComboBox2Change definiert, das heist es verschwindet sobald die Methode verlassen wird.
Vorher müssen unbedingt die erzeugten Objekte freigegeben werden, sonst ist das ein mächtiges Speicherleck.
ausblenden Delphi-Quelltext
1:
2:
  for x := Low(bilderverzeichnis) to High(bilderverzeichnis)
    bilderverzeichnis[x].Free;


Die Methode "imglist.Add()" erzeugt intern eine Kopie des Bitmap-Inhalts.
Deshalb ist es für die hier vorgesehene Funktionalität eigentlich nicht notwendig gleich ein ganzes Array von Bitmaps zu erzeugen.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
procedure TForm2.ComboBox2Change(Sender: TObject);
var
  bmp: TBitmap;
  x: Integer;
begin
  bmp := TBitmap.Create;
  try
    for x := 0 to 7 do
    begin
      bmp.loadfromfile('BILDER\' + IntToStr(x));
      Form1.imglist.Add(bmp, nil);
      Form1.imglist.Add(bmp, nil);
    end;
  finally
    bmp.Free;
  end;
wolfproductsInc Threadstarter
Hält's aus hier
Beiträge: 6



BeitragVerfasst: Do 03.04.14 13:18 
Danke! Nach ein paar modifikationen funktioniert es, ich musste nur noch dafür sorgen das Form1 erneuert wurde. Wisst ihr auch wie man
dafür sorgt das die Bilder auf "stretch" setzt? Sie sind alle 45 pixel zu gross für die Images. Ansonsten habt ihr wir wirklich weitergeholfen, jetzt kann
ich endlich weiter machen ^^

edit: ich weiss was objekte sind, habe jedoch nur sehr wenig erfahrung mit OOP, und meide es wo ich es kann. Ich wäre nie darauf gekommen das man das Objekt nochmal manuel erstellen muss, dachte
das macht er automatisch. Nachhinein betrachtet auch logisch, man braucht ja objekte nur zu bestimmten zeitpunkten
Perlsau
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Do 03.04.14 13:50 
user profile iconwolfproductsInc hat folgendes geschrieben Zum zitierten Posting springen:
... habe jedoch nur sehr wenig erfahrung mit OOP, und meide es wo ich es kann.

Wenn du es meidest, wo du kannst, wirst du's nie lernen ... :twisted:
wolfproductsInc Threadstarter
Hält's aus hier
Beiträge: 6



BeitragVerfasst: Do 03.04.14 13:54 
Hm stimmt allerdings, aber da OOP öffters der einzigste weg ist etwas zu lösen, muss ich es auch ab und zu verwenden, aber dann verwende ich pro object eine neue Unit damit es übersichtlich bleibt, und dann war es logisch das Objekt zu erstellen wenn ich in fmMain brauchte

Ich habe jetzt versucht diese methode mehrmals zu verwendenden:
ausblenden volle Höhe 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:
procedure TForm2.ComboBox2Change(Sender: TObject);
var
  bmp: TBitmap;
  x: Integer;
begin
form1.BtnStartClick(Self);
case combobox2.ItemIndex of
0begin

  form1.imglist.clear;                                                          
  bmp := TBitmap.Create;                                                       
  try
    for x := 1 to 8 do                                                          
    begin
      bmp.loadfromfile('STARWARS\' + IntToStr(x)+'.bmp');                     
      Form1.imglist.Add(bmp, nil);                                            
    end;
  finally
    bmp.Free;
  end;
 end;

1begin
  form1.imglist.clear;                                                        
  bmp := TBitmap.Create;                                                     
  try
    for x := 1 to 8 do                                                        
    begin
      bmp.loadfromfile('Auto\' + IntToStr(x)+'.bmp');                          
      Form1.imglist.Add(bmp, nil);                                            
    end;
  finally
    bmp.Free;
  end;
 end;


  end;

end;

Jedenfall kommt immer der Fehlermeldung "Invalid image size", obwohl alle bilder gleich groß sind (105x105 pixels um genau zu sein
das der queltext wieder gleich nacheinander geschrieben ist liegt am editor
Perlsau
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Do 03.04.14 14:50 
user profile iconwolfproductsInc hat folgendes geschrieben Zum zitierten Posting springen:
Jedenfall kommt immer der Fehlermeldung "Invalid image size", obwohl alle bilder gleich groß sind (105x105 pixels

Hast du denn auch die Properties TImageList.Height und TImageList.Width auf 105 gestellt? Liegen die Bilder denn auch alle im selben Format vor? Beinhalten sie dieselbe Farbpalette? In einer TImageList werden die einzelnen Bilder als ein einziges großes Bild gespeichert, daher müssen die Einzelbilder in vielerlei Hinsicht gleichförmig sein. Zudem ist die Größe der Einzelbilder beschränkt auf 255 x 255 Pixel.

Übrigens kannst du dir Codezeilen sparen, wenn du dein Case-Konstrukt innerhalb des Try-Finally-Blocks platzierst. Du mußt dann nämlich das Bitmap nur einmal erzeugen und freigeben.
wolfproductsInc Threadstarter
Hält's aus hier
Beiträge: 6



BeitragVerfasst: Do 03.04.14 15:16 
Ja imagelist hat 105x105. Die Bilder sind ein 24bit farben bitmap. Es gibt kein problem die Bilder manuel in Imagelist zu laden. Es war leichter erstmal copy paste zu machen und um zu überprüfen ob es Functioniert

EDIT ich habe es jetzt hinbekommen, vielen dank an alle die mich geholfen haben