Hallo ihr Lieben,
danke nochmal für die Hilfe bis hier hin!
Allerdings hat sich mir nun ein weiteres Problem aufgetan. Ich habe mein Programm ein wenig erweitert, so dass ich den angeklickten Frame 1. überall anklicken kann und das onClick Ereignis auf jeder Komponente ausgelöst wird, 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:
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;
Und hier die FrameClick-Prozedur, in der der Frame als angeklickt markiert wird:
Delphi-Quellcode:
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;
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:
Delphi-Quellcode:
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;
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?
Das Createn der Frames funktioniert auch im Hauptprogramm einwandfrei. Aber jetzt kommt der Knackpunkt; Hier meine OnFrameClick Prozedur vom Hauptprogramm:
Delphi-Quellcode:
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;
Diese Prozedur ist sogar noch ähnlicher zu der FrameClick Prozedur vom Testprogramm.
Ich habe nun aber 2 Probleme in dieser Prozedur:
1. Das durchlaufen des Arrays, also folgende Code-passage erzeugt eine Zugriffsverletzung
Delphi-Quellcode:
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;
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.
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