|
Registriert seit: 3. Apr 2019 41 Beiträge |
#1
Hallo ihr Lieben,
Ich habe ein Testprogramm geschrieben, in dem ich Frames per Laufzeit in ein Formular lade. Ich habe jeden Frame so ausgestattet dass ich den angeklickten Frame 1. überall anklicken kann und das onClick Ereignis auf jeder Komponente ausgelöst wird(, ich weise also jeder Komponente bei OnClick eine von mir geschriebene Prozedur zu), und ihn 2. über die Vergabe eines einheitlichen Tags aller Komponenten, der Identisch mit dem Index des Frame-Arrays ist identifizieren kann. Im Testprogramm funktioniert das alles einwandfrei. Hier der Code zum Erstellen der Frames und der Vergabe des Tags, sowie des OnClick Ereignises: (Frame ist in beiden Programmen eine globale Variable: array of TFrame)
Delphi-Quellcode:
Und hier die FrameClick-Prozedur, in der der Frame als angeklickt markiert wird:
procedure TDialog_MainUnit.CreateFrames();
var i, j: Integer; begin try for i := 0 to 2 do begin SetLength(Frame, length(Frame) + 1); //Frame bauen: Frame[i] := TFrame_ButtonTest.Create(Self); if Assigned(TFrame_ButtonTest(Frame[i])) then begin with Frame[i] do begin Name := 'Frame' + IntToStr(i); Parent := PnlFramesBack; Align := alLeft; Tag := i; end; TFrame_ButtonTest(Frame[i]).LblName.Caption := Frame[i].Name; for j := 0 to TFrame_ButtonTest(Frame[i]).ComponentCount - 1 do begin TFrame_ButtonTest(Frame[i]).Components[j].Tag := i; TButton(TFrame_ButtonTest(Frame[i]).Components[j]).OnClick := FrameClick; TButton(TFrame_ButtonTest(Frame[i]).Components[j]).Cursor := crHandPoint; end; TFrame_ButtonTest(Frame[i]).Show; end; end; except on e: Exception do begin ShowMessage('Fehler in CreateFrames(): ' + e.Message); end; end; end;
Delphi-Quellcode:
Wie gesagt, funktioniert das alles ohne Probleme. Also wollte ich den Code meines Testprogrammes auf mein Hauptprogramm anwenden, was dann so für das Erstellen der Frames so aussieht:
procedure TDialog_MainUnit.FrameClick(Sender: TObject);
var tmpIdx, i: Integer; begin try tmpIdx := TComponent(Sender).Tag; LblFramesAktiv.Caption := 'Aktiver Frame: '; for i := Low(Frame) to High(Frame) do begin TFrame_ButtonTest(Frame[i]).IsSelected := False; TFrame_ButtonTest(Frame[i]).PnlTop.BevelOuter := bvNone; TFrame_ButtonTest(Frame[i]).PnlTop.BevelWidth := 1; end; TFrame_ButtonTest(Frame[tmpIdx]).IsSelected := True; TFrame_ButtonTest(Frame[tmpIdx]).PnlTop.BevelOuter := bvRaised; TFrame_ButtonTest(Frame[tmpIdx]).PnlTop.BevelWidth := 3; LblFramesAktiv.Caption := 'Aktiver Frame: ' + TFrame_ButtonTest(Frame[tmpIdx]).Name; except on e: Exception do begin ShowMessage('Fehler in FrameClick(): ' + e.Message); end; end; end;
Delphi-Quellcode:
Diese Funktion ist also Quasi identisch mit der aus meinem Testprogramm, bis auf dass ich die Frames im richtigen Programm vorm Createn erst lösche und ich mit einer while schleife durch meine TmpQuery gehe und dabei i inkrementiere, anstatt wie im Testprogramm i direkt mit einer for-Schleife hochzuzählen. Aber das sollte ja keinen unterschied machen... Oder?
function TDialog_Hauptprogramm.CreateFrames(): Boolean;
var i, j: Integer; function DeleteFrames(): Boolean; var i: Integer; begin Result := False; try for i := Low(Frame) to High(Frame) do begin if Assigned(Frame) then FreeAndNil(Frame[i]); end; Result := True; except on e: Exception do begin Result := False; ShowMessage('Fehler in DeleteFrames(): ' + e.Message); end; end; end; begin Result := False; try //Erst alle Frames löschen if DeleteFrames() then begin TmpQuery.Close; TmpQuery.SQL.Clear; TmpQuery.SQL.Add('SELECT * FROM meine_tabelle'); TmpQuery.SQL.Add('WHERE ID_meine_tablle2 = ' + IntToStr(SpinEdit.Value)); TmpQuery.Open; try TmpQuery.First; i := 0; while not TmpQuery.Eof do begin SetLength(Frame, length(Frame) + 1); //Frame bauen: TMein_Frame(Frame[i]) := TMein_Frame.Create(self); if Assigned(TMein_Frame(Frame[i])) then begin with Frame[i] do begin Name := 'Mein_Frame'+IntToStr(i); Parent := PnlFramesBack; Tag := i; Align := alLeft; end; //Frame ausstatten: TMein_Frame(Frame[i]).IsSelected := False; TMein_Frame(Frame[i]).PnlBack.BevelOuter := bvNone; TMein_Frame(Frame[i]).PnlBack.BevelWidth := 1; //allen Frame-Komponenten den selben tag vergeben und anklickbar machen: for j := 0 to TMein_Frame(Frame[i]).ComponentCount - 1 do begin TMein_Frame(Frame[i]).Components[j].Tag := i; TButton(TMein_Frame(Frame[i]).Components[j]).OnClick := OnFrameClick; TButton(TMein_Frame(Frame[i]).Components[j]).Cursor := crHandPoint; end; Frame[i].Show; end; TmpQuery.Next; Inc(i); end; finally TmpQuery.Close; end; ScrollBoxFrames.Refresh; end else begin Result := False; Exit; end; Result := True; except on e: Exception do begin ShowMessage('Fehler in CreateFrames(): ' + e.Message); end; end; end; Das Createn der Frames funktioniert auch im Hauptprogramm einwandfrei. Aber jetzt kommt der Knackpunkt; Hier meine OnFrameClick Prozedur vom Hauptprogramm:
Delphi-Quellcode:
Diese Prozedur ist sogar noch ähnlicher zu der FrameClick Prozedur vom Testprogramm.
procedure TDialog_Hauptprogramm.OnFrameClick(Sender: TObject);
var tmpIdx, i: Integer; begin try tmpIdx := TComponent(Sender).Tag; //alle Frames demarkieren: for i := Low(Frame) to High(Frame) do begin TMein_Frame(Frame[i]).IsSelected := False; TMein_Frame(Frame[i]).PnlBack.BevelOuter := bvNone; TMein_Frame(Frame[i]).PnlBack.BevelWidth := 1; end; //Den angeklickten Frame markieren: TMein_Frame(Frame[tmpidx]).IsSelected := True; TMein_Frame(Frame[tmpidx]).PnlBack.BevelOuter := bvRaised; TMein_Frame(Frame[tmpidx]).PnlBack.BevelWidth := 3; //mache anders Zeug... except on e: Exception do begin ShowMessage('Fehler in OnFrameClick(): ' + e.Message); end; end; end; Ich habe nun aber 2 Probleme in dieser Prozedur: 1. Das durchlaufen des Arrays, also folgende Code-passage erzeugt eine Zugriffsverletzung
Delphi-Quellcode:
Wenn ich diesen Teil auskommentiere, Habe ich diesen Fehler schon mal nicht. Allerdings brauche ich diesen Code nunmal und im Testprogramm hat es ja einwandfrei funktioniert.
for i := Low(Frame) to High(Frame) do
begin TMein_Frame(Frame[i]).IsSelected := False; TMein_Frame(Frame[i]).PnlBack.BevelOuter := bvNone; TMein_Frame(Frame[i]).PnlBack.BevelWidth := 1; end; Nun zu Problem 2: Als Progammierer denkt man sich nach dem Zugriffsverletzngsfehler natürlich: "Na gut, dann debugge ich die Prozedur halt mal und setze nen Haltepunkt an den Anfang." Wenn man das nun tut und auf den Frame klickt, hängt sich das ganze Programm auf und ich bekomme nichtmal eine Fehlermeldung. Ich kann dann weder Delphi, noch das Programm schließen und muss Delphi per Taskmanager abschießen. Was ist da los??? Im Testprogramm hatte ich das alles nicht. Woran könnte es liegen? Danke nochmal im Voraus für eure Hilfe! MFG MorrisF |
![]() |
Ansicht |
![]() |
![]() |
![]() |
ForumregelnEs ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.
BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus. Trackbacks are an
Pingbacks are an
Refbacks are aus
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
![]() |
![]() |