![]() |
dynamisches Menü mit labels Konfiguration durch INI-File
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,
ich bin gerade dabei ein Menü zu erstellen, das man komplett über eine INI-Datei konfigurieren kann. Sprich die Labels werden erst zur Laufzeit erstellt. Das funktioniert auch schon wunderbar. Jetzt kann ich auch einmal auf einen Menüeintrag klicken. Klicke ich jedoch wieder auf einen Menüeintrag, bekomme ich einen Fehler: Access violation. Was mache ich beim Löschen bzw. beim Erstellen der Labels falsch. Ich denke zumindest, dass der Fehler daran liegt. Habe im Anhang mal das komplette Projekt. |
Re: dynamisches Menü mit labels Konfiguration durch INI-File
Hallo,
beim Starten der kompilierten Anwendung tritt bei mir die AV beim Navigieren im Menü auf. Ich habe nun die Label1.Left Anweisung entfernt, damit ich das Projekt kompilieren kann, doch habe ich dann keine AV und alles läuft wie es soll. :gruebel: |
Re: dynamisches Menü mit labels Konfiguration durch INI-File
Hallo,
wenn ich bei mir das Label1.left entferne bekomme ich immer noch die selbe Fehlermeldung, wenn ich im Menü navigiere: --------------------------- Debugger Exception Notification --------------------------- Project Project1.exe raised exception class EAccessViolation with message 'Access violation at address 0040341A in module 'Project1.exe'. Read of address 00000166'. Process stopped. Use Step or Run to continue. --------------------------- OK Help --------------------------- |
Re: dynamisches Menü mit labels Konfiguration durch INI-File
Nach langem herumversuchen habe ich jetzt herrausgefunden, dass der Fehler nicht beim Löschen der Labels liegt.
Wenn ich die Funktion MenueAktualisieren beim editEvent herrausnehme, dann bekomme ich keinen Fehler. In dieser Funktion werden die Labels ja wieder erstellt. Wenn ich jetzt auf ein Edit klicke, sind alle Labels weg. Die Funktion MenueAktualisieren muss aber nach dem Löschen der Labels aufgerufen werden, damit ich das entsprechende Menü wieder sehe. Habe jetzt versucht, die Funktion in einem TimerEvent auszuführen, doch da bekomm ich die selbe Fehlermeldung. Hier mal mein der aktuelle Code:
Delphi-Quellcode:
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, IniFiles, StdCtrls, ComCtrls, jpeg, ExtCtrls, DateUtils; const WM_DESTROY_LBL = WM_USER + 1; type TForm1 = class(TForm) Panel1: TPanel; Panel2: TPanel; Image1: TImage; Button1: TButton; Button2: TButton; Label1: TLabel; Edit1: TEdit; procedure FormCreate(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private declarations } procedure editEvent(sender : TObject); procedure Label_erstellen(aname, text: String; tmpleft, tmptop, LabelIndex: Integer; Komponent : TComponent; WinKontrol: TWinControl); procedure DestoryLabel(var msg : TMessage); message WM_DESTROY_LBL; public { Public declarations } end; var Form1: TForm1; LabelArray: array of TLabel; implementation {$R *.dfm} function Teilstring_Ersetzen(Text, Suchen, Ersetzen:String):String; var Flags: TReplaceFlags; begin Flags:=[]; Flags:=[rfIgnoreCase]; // ohne rfReplaceAll wird nur die erste Fundstelle ersetzt // durch rfIgnoreCase wird Groß- und Kleinschreibung ignoriert result:=StringReplace(Text, Suchen, Ersetzen, Flags); // 'Suchen' ist der zu ersetzende Teil, 'Ersetzen' der neu eingefügte Teil end; function Zeichen_Ersetzen(Text: String; altZeichen: char; neuZeichen: char):String; begin while Pos(altZeichen, Text) > 0 do Text[Pos(altZeichen, Text)] := neuZeichen; result:= Text; end; procedure LinkFarbe(Index: Integer); var i: Integer; begin //Farben für den Link bestimmen, wenn man die For schleife weg lässt werden alle Unterpunkte grau for i:=0 to 29 do begin if LabelArray[i] <> nil then begin LabelArray[i].Font.Color := clBlue; end; end; LabelArray[Index].Font.Color := clGray; end; procedure Bild_Laden(Pfad: String); var tmpFloat: Extended; begin Pfad := Teilstring_Ersetzen(Pfad, 'Jahr', IntToSTr(YearOf(now))); Pfad := Teilstring_Ersetzen(Pfad, 'Monat', FormatDateTime('mmmmm', now)); if FileExists(pfad) then Form1.Image1.Picture.LoadFromFile(Pfad) else Form1.Image1.Picture.LoadFromFile('C:\Dokumente und Einstellungen\Hans\Desktop\Diagramme\Foto\fehler.jpg'); //Bildgröße an Bildschirmgröße anpassen tmpFloat := Form1.Image1.Picture.Width / 100; tmpFloat := Form1.Image1.Width / tmpFloat; tmpFloat := (Form1.Image1.Picture.Height / 100) * tmpFloat; Form1.Image1.Height := Trunc(tmpFloat); { Form1.Button1.Top := Form1.Image1.Top + Form1.Image1.Height + 5; Form1.Button2.Top := Form1.Image1.Top + Form1.Image1.Height + Form1.Button1.Height + 10;} end; procedure MenueAktualisieren(Komponent : TComponent; WinKontrol: TWinControl; aktLink: String); var LinkAnzahl1, LinkAnzahl2, LinkAnzahl3, LinkAnzahl4, LinkAnzahl5, LinkAnzahl6, LinkAnzahl7: Integer; a, b, c, d, e, f: Integer; tmpLink1, tmpLink2, tmpLink3, tmpLink4, tmpLink5, tmpLink6, tmpLink7: String; LabelIndex, top: Integer; ini: TiniFile; Dauer, tmp: Integer; sl: TStringList; i, oben: Integer; tmpStr, tmpPfad, pfad: String; begin LabelIndex := 0; top := 60; pfad := ExtractFilePath(ParamStr(0)); pfad := pfad + 'CockpitChart.ini'; ini:=TIniFile.Create(pfad); LinkAnzahl1 := ini.ReadInteger('RootItems','RootItemsCount', LinkAnzahl1); for a:=1 to LinkAnzahl1 do //Menü Stufe 1 begin tmpStr := ini.ReadString('RootItems', 'Item' + IntToStr(a), tmpStr); tmpLink1 := 'Link' + IntToStr(a); Form1.Label_erstellen(tmpLink1, tmpStr, 5, top, LabelIndex, Komponent, WinKontrol); inc(LabelIndex); top := top + 20; LinkAnzahl2 := ini.ReadInteger(tmpLink1,'ItemsCount', LinkAnzahl2); if copy(aktLink, 1, 5) = tmpLink1 then begin tmpPfad := ini.ReadString('RootItems', 'Image' + IntToStr(a), tmpPfad); Bild_Laden(tmpPfad); LinkFarbe(LabelIndex-1); for b:=1 to LinkAnzahl2 do //Menü Stufe 2 begin tmpStr := ini.ReadString(tmpLink1, 'Item' + IntToStr(b), tmpStr); tmpLink2 := 'Link' + IntToStr(a) + '.' + IntToStr(b); Form1.Label_erstellen(tmpLink2, tmpStr, 15, top, LabelIndex, Komponent, WinKontrol); inc(LabelIndex); top := top + 20; LinkAnzahl3 := ini.ReadInteger(tmpLink2,'ItemsCount', LinkAnzahl2); if copy(aktLink, 1, 7) = tmpLink2 then begin tmpPfad := ini.ReadString(tmpLink1, 'Image' + IntToStr(b), tmpPfad); Bild_Laden(tmpPfad); LinkFarbe(LabelIndex-1); for c:=1 to LinkAnzahl3 do //Menü Stufe 3 begin tmpStr := ini.ReadString(tmpLink2, 'Item' + IntToStr(c), tmpStr); tmpLink3 := 'Link' + IntToStr(a) + '.' + IntToStr(b) + '.' + IntToStr(c); Form1.Label_erstellen(tmpLink3, tmpStr, 25, top, LabelIndex, Komponent, WinKontrol); inc(LabelIndex); top := top + 20; LinkAnzahl4 := ini.ReadInteger(tmpLink3,'ItemsCount', LinkAnzahl4); if copy(aktLink, 1, 9) = tmpLink3 then begin tmpPfad := ini.ReadString(tmpLink2, 'Image' + IntToStr(c), tmpPfad); Bild_Laden(tmpPfad); LinkFarbe(LabelIndex-1); for d:=1 to LinkAnzahl4 do //Menü Stufe 4 begin tmpStr := ini.ReadString(tmpLink3, 'Item' + IntToStr(d), tmpStr); tmpLink4 := 'Link' + IntToStr(a) + '.' + IntToStr(b) + '.' + IntToStr(c) + '.' + IntToStr(d); Form1.Label_erstellen(tmpLink4, tmpStr, 35, top, LabelIndex, Komponent, WinKontrol); inc(LabelIndex); top := top + 20; LinkAnzahl5 := ini.ReadInteger(tmpLink4,'ItemsCount', LinkAnzahl5); if copy(aktLink, 1, 11) = tmpLink4 then begin tmpPfad := ini.ReadString(tmpLink3, 'Image' + IntToStr(d), tmpPfad); Bild_Laden(tmpPfad); LinkFarbe(LabelIndex-1); for e:=1 to LinkAnzahl5 do //Menü Stufe 5 begin tmpStr := ini.ReadString(tmpLink4, 'Item' + IntToStr(e), tmpStr); tmpLink5 := 'Link' + IntToStr(a) + '.' + IntToStr(b) + '.' + IntToStr(c) + '.' + IntToStr(d) + '.' + IntToStr(e); Form1.Label_erstellen(tmpLink5, tmpStr, 45, top, LabelIndex, Komponent, WinKontrol); inc(LabelIndex); top := top + 20; LinkAnzahl6 := ini.ReadInteger(tmpLink5,'ItemsCount', LinkAnzahl6); if copy(aktLink, 1, 13) = tmpLink5 then begin tmpPfad := ini.ReadString(tmpLink4, 'Image' + IntToStr(d), tmpPfad); Bild_Laden(tmpPfad); LinkFarbe(LabelIndex-1); for f:=1 to LinkAnzahl6 do //Menü Stufe 6 begin tmpStr := ini.ReadString(tmpLink5, 'Item' + IntToStr(f), tmpStr); tmpLink6 := 'Link' + IntToStr(a) + '.' + IntToStr(b) + '.' + IntToStr(c) + '.' + IntToStr(d) + '.' + IntToStr(e) + '.' + IntToStr(f); Form1.Label_erstellen(tmpLink6, tmpStr, 55, top, LabelIndex, Komponent, WinKontrol); inc(LabelIndex); top := top + 20; LinkAnzahl7 := ini.ReadInteger(tmpLink6,'ItemsCount', LinkAnzahl7); if copy(aktLink, 1, 15) = tmpLink6 then begin tmpPfad := ini.ReadString(tmpLink5, 'Image' + IntToStr(f), tmpPfad); Bild_Laden(tmpPfad); LinkFarbe(LabelIndex-1); end; end; end; end; end; end; end; end; end; end; end; end; end; procedure TForm1.Label_erstellen(aname, text: String; tmpleft, tmptop, LabelIndex: Integer; Komponent : TComponent; WinKontrol: TWinControl); var Test: TLabel; begin aname := Zeichen_Ersetzen(aname, '.', '_'); LabelArray[LabelIndex] := TLabel.Create(Komponent); with LabelArray[LabelIndex] do begin parent := WinKontrol; left := tmpleft; top := tmptop; name := aname; Caption := text; onClick := editEvent; //Font.style := [fsBold]; if Screen.Width <= 1360 then font.size := 8 else font.size := 12; font.color := clBlue; end; end; procedure TForm1.DestoryLabel(var msg: TMessage); begin if msg.Msg = WM_DESTROY_LBL then TLabel(msg.WParam).Free; end; procedure TForm1.editEvent(sender : TObject); var name: String; i: Integer; begin name := TLabel(sender).Name; name := Zeichen_Ersetzen(name, '_', '.'); //Versuch1 for i:=0 to 29 do begin if LabelArray[i] <> nil then begin if LabelArray[i].Name <> TLabel(sender).Name then begin LabelArray[i].Free; LabelArray[i] := nil; end else begin SendMessage(self.Handle, WM_DESTROY_LBL, Integer(LabelArray[i]), 0); LabelArray[i] := nil; end; end; end; Edit1.Text := name; //MenueAktualisieren(self, self, name); end; procedure TForm1.FormCreate(Sender: TObject); var Fensterbreite, tmp: Integer; begin SetLength(LabelArray, 30); MenueAktualisieren(self, self, 'Link2.2'); //Objekte an Größe anpassen if Screen.Width <= 1360 then begin Image1.Left := 150; end else Image1.Left := 240; Fensterbreite := Screen.Width; Label1.Left := (Fensterbreite div 2) - (Label1.Width div 2); Form1.Panel1.Left := 0; Form1.Panel1.Width := Fensterbreite; Image1.Width := (Fensterbreite - Image1.Left) - 10; tmp := Fensterbreite - Image1.left; tmp := tmp div 2; tmp := tmp + Image1.Left - (Button1.Width div 2); Button1.Left := tmp ; tmp := Fensterbreite - Image1.left; tmp := tmp div 2; tmp := tmp + Image1.Left - (Button2.Width div 2); Button2.Left := tmp ; //Hintergrundfarbe Form1.Color := RGB(15, 185, 185); Form1.Panel1.Color := RGB(15, 185, 185); Button1.Top := Image1.Top + Image1.Height + 50; Button2.Top := Image1.Top + Image1.Height + 80; //Fenster maximieren Form1.WindowState := wsMaximized; end; procedure TForm1.Button2Click(Sender: TObject); begin MenueAktualisieren(self, self, Edit1.Text); end; end. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:48 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