|
![]() |
|
Registriert seit: 26. Nov 2004 Ort: Dresden 283 Beiträge Delphi 10.3 Rio |
#1
In diesem Testprojekt ist der EListerror weg aber von Paint wird nichts ausgegeben nur die Zeile "Zurück mit << ENTER > >> ...'
Delphi-Quellcode:
@venice2:
program Project3;
{$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils,System.Classes,Contnrs; type TGridColumn = class(Tobject) private FWidth: Integer; FHeight: Integer; public constructor Create; property Width: Integer read FWidth write FWidth; property Height: Integer read FHeight write FHeight; end; TCustomGrid = class(TObject) private FCols: Integer; FRows: Integer; FRowsContainer: TObjectList; procedure SetCols(AValue: Integer); procedure SetRows(AValue: Integer); public constructor Create; destructor Destroy; override; procedure Paint; property Cols: Integer read FCols write SetCols; property Rows: Integer read FRows write SetRows; end; { TGridColumn } constructor TGridColumn.Create; begin inherited Create; end; { TCustomGrid } constructor TCustomGrid.Create; begin inherited Create; FRowsContainer := TObjectList.Create; end; destructor TCustomGrid.Destroy; begin FRowsContainer.Free; inherited; end; procedure TCustomGrid.SetCols(AValue: Integer); var ACol,ARow: Integer; gridColumn: TGridColumn; begin if FCols=AValue then Exit; FCols:=AValue; for ARow := 0 to FRows -1 do begin for ACol := 0 to FCols-1 do begin gridColumn := TGridColumn.Create; gridColumn.Width := 200; gridColumn.Height := 20; TStringList(FRowsContainer.Items[ARow]).AddObject(' ', gridColumn); if ACol >= FCols-1 then break; end; end; end; procedure TCustomGrid.SetRows(AValue: Integer); var ARow: Integer; AList: TStringList; begin if FRows=AValue then Exit; FRows:=AValue; for ARow := 0 to FRows-1 do begin AList := TStringList.Create; AList.Capacity := 5; AList.Duplicates:=dupAccept; FRowsContainer.Add(AList); end; end; procedure TCustomGrid.Paint; var ACol,ARow,w,h,l,t,r,b: Integer; gc: TGridColumn; sl: TStringList; rc: TObjectList; begin for ARow:=0 to FRowsContainer.Count-1 do begin for ACol:=0 to TStringList(FRowsContainer.Items[ARow]).Count-1 do begin rc := FRowsContainer; sl := TStringList(rc.Items[ARow]); gc := TGridColumn(sl.Objects[ACol]); if (ACol<TStringList(FRowsContainer.Items[ARow]).Capacity) and Assigned(gc) then begin w := gc.Width; //TGridColumn(TStringList(FRowsContainer.Items[ARow]).Objects[ACol]).Width; h := gc.Height; //TGridColumn(TStringList(FRowsContainer.Items[ARow]).Objects[ACol]).Height; // l := gc.Left; //TGridColumn(TStringList(FRowsContainer.Items[ARow]).Objects[ACol]).Left; //aus Originalcode übernommen // t := gc.Top; //TGridColumn(TStringList(FRowsContainer.Items[ARow]).Objects[ACol]).Top; //aber hier weggelassen end; // DrawRectangleClip(vscreen,l,t,l+w,t+h,ToColor(colBlack)); writeln('Breite: ',w); //wird nicht angezeigt, warum? writeln('Höhe : ',h); //wird nicht angezeigt, warum? //writeln('Links : ',l); //writeln('Oben : ',t); { t := t + h; //t (Top soll um h (Zeilenhöhe) nach unten, nachdem Gridrahmenlinie oben gezeichnet ist l := l + w; //l (Left) soll um w (Spaltenbreite) nach rechts, nachdem Gridrahmenlinie links gezeichnet ist } inc(t, h); inc(l, w); end; if ARow >= FRows then break; end; end; var Grid: TCustomGrid; begin try { TODO -oUser -cConsole Main : Code hier einfügen } Grid:=TCustomGrid.Create; Grid.Cols := 9; Grid.Rows := 5; Grid.Paint; writeln('Zurück mit << ENTER >> > >>> ... '); readln; except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; end. Mein Code:
Delphi-Quellcode:
Damit werden doch die Variablen l,t,w und h in der DrawRectangleClip Prozedur verwendet. Aber der EListError verhindert, dass ich dorthin komme.
DrawRectangleClip(vscreen,l,t,l+w,t+h,ToColor(colBlack));
{ t := t + h; l := l + w; } inc(t, h); inc(l, w); end; if ARow >= FRows then break; //Diese Zeile habe ich hinzugefügt, damit nach Zeile 5 keine weitere hinzugefügt wird. Ich weiß zwar, dass die FOR Schleife automatisch abbricht, ja abbrechen sollte, //wenn der Endwert erreicht ist, aber ich habe nun mal den EListError. Übrigens mit Freepascal geschrieben, der Code, aber auch dort ist mir kein Fehler im Compiler bekannt, deshalb habe ich das //bisher nicht erwähnt. l=Left und t=Top werden zwar mit erhöht, aber da sollte ich ddoch wenigstens die erste Gridspalte sehen, so wie der Code hier aussieht. ![]() // t wird anschließend incrementiert aber nicht mehr benutzt weil die Variable t nicht global definiert ist und vorher nicht zugewiesen wird.
Der von mir gesuchte Fehler muss hier liegen:
Delphi-Quellcode:
Wenn es das ist, wie kann ich solche Zuweisung zuverlässiger erreichen. Schließlich werden auch in meinem Testprojekt Breite und Höhe nicht angezeigt.
rc := FRowsContainer;
sl := TStringList(rc.Items[ARow]); //das hier nicht Assigned oder gc := TGridColumn(sl.Objects[ACol]); //das hier nicht Assigned if (ACol<TStringList(FRowsContainer.Items[ARow]).Capacity) and Assigned(gc) then Geändert von delphifan2004 (21. Mai 2022 um 20:44 Uhr) |
![]() |
venice2
(Gast)
n/a Beiträge |
#2
![]() In diesem Testprojekt ist der EListerror weg aber von Paint wird nichts ausgegeben nur die Zeile "Zurück mit << ENTER > >> ...'
Springt gar nicht erst in deine schleife rein. Prüfe das nochmal.. for ACol:=0 to TStringList(FRowsContainer.Items[ARow]).Count-1 do Count ist -1 sorry das kann so nichts werden. Geändert von venice2 (21. Mai 2022 um 21:35 Uhr) |
![]() |
venice2
(Gast)
n/a Beiträge |
#3
Ok du hast Rows und Cols vertauscht.. deshalb wurde deine TStringliste nicht gefüllt in deinem Beispiel!
Versuche das hier. Habe keinen ElistError läuft wie es soll.
Delphi-Quellcode:
program Project3;
{$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, System.Classes, Contnrs; type TGridColumn = class(Tobject) private FWidth: Integer; FHeight: Integer; FLeft: Integer; FTop: Integer; public constructor Create; property Width: Integer read FWidth write FWidth; property Height: Integer read FHeight write FHeight; property Left: Integer read FLeft write FLeft; property Top: Integer read FTop write FTop; end; TCustomGrid = class(Tobject) private FCols: Integer; FRows: Integer; FRowsContainer: TObjectList; procedure SetCols(AValue: Integer); procedure SetRows(AValue: Integer); public constructor Create; destructor Destroy; override; procedure Paint; property Cols: Integer read FCols write SetCols; property Rows: Integer read FRows write SetRows; end; var l, t, w, h: Integer; { TGridColumn } constructor TGridColumn.Create; begin inherited Create; end; { TCustomGrid } constructor TCustomGrid.Create; begin inherited Create; FRowsContainer := TObjectList.Create; end; destructor TCustomGrid.Destroy; begin FRowsContainer.Free; inherited; end; procedure TCustomGrid.SetCols(AValue: Integer); var ACol, ARow: Integer; gridColumn: TGridColumn; begin if FCols = AValue then Exit; FCols := AValue; for ARow := 0 to FRows - 1 do begin for ACol := 0 to FCols - 1 do begin gridColumn := TGridColumn.Create; gridColumn.Width := 200; gridColumn.Height := 20; gridColumn.Left := 10; gridColumn.Top := 10; TStringList(FRowsContainer.Items[ARow]).AddObject(' ', gridColumn); end; end; end; procedure TCustomGrid.SetRows(AValue: Integer); var ARow: Integer; AList: TStringList; begin if FRows = AValue then Exit; FRows := AValue; if FRowsContainer.Count > 0 then FRowsContainer.Clear; // falls mehrfacher Aufruf von SetRows Container löschen; for ARow := 0 to FRows - 1 do begin AList := TStringList.Create; AList.Capacity := 5; AList.Duplicates := dupAccept; FRowsContainer.Add(AList); end; end; procedure TCustomGrid.Paint; var ACol, ARow { , r, b } : Integer; gc: TGridColumn; sl: TStringList; rc: TObjectList; begin for ARow := 0 to FRowsContainer.Count - 1 do begin for ACol := 0 to TStringList(FRowsContainer.Items[ARow]).Count - 1 do begin rc := FRowsContainer; sl := TStringList(rc.Items[ARow]); gc := TGridColumn(sl.Objects[ACol]); if (ACol < TStringList(FRowsContainer.Items[ARow]).Capacity) and Assigned(TGridColumn(TStringList(FRowsContainer.Items[ARow]).Objects[ACol])) then begin // TGridColumn(TStringList(FRowsContainer.Items[ARow]).Objects[ACol]).Width; w := gc.Width; // TGridColumn(TStringList(FRowsContainer.Items[ARow]).Objects[ACol]).Height; h := gc.Height; // TGridColumn(TStringList(FRowsContainer.Items[ARow]).Objects[ACol]).Left; //aus Originalcode übernommen l := l + gc.Left; // TGridColumn(TStringList(FRowsContainer.Items[ARow]).Objects[ACol]).Top; //aber hier weggelassen t := t + gc.Top; end; writeln('Top: ', t); writeln('Left: ', l); inc(t, h); inc(l, w); end; end; end; var Grid: TCustomGrid; begin try { TODO -oUser -cConsole Main : Code hier einfügen } Grid := TCustomGrid.Create; Grid.Rows := 5; // zuerst Rows initialisieren dann Cols. Grid.Cols := 9; Grid.Paint; writeln('Zurück mit << ENTER >> > >>> ... '); readln; except on E: Exception do writeln(E.ClassName, ': ', E.Message); end; end. ![]() Warum müssen diese vars global definiert sein. Ich will doch lokal zeichnen?
![]() Wie Uwe schon schrieb.. ![]() Warum überhaupt dieses Hochzählen, wo die Werte doch im nächsten Durchlauf wieder gesetzt werden?
Und ignoriere keine Warnungen vom Compiler! w, h müssen ebenfalls global definiert werden weil diese ansonsten nicht initialisiert sind. Alternativ kannst du die auch local definieren mußt diese dann aber selbst initialisieren und zwar vor der schleife for ARow := 0 to FRowsContainer.Count - 1 do
Delphi-Quellcode:
EDIT:
w := 0;
h := 0; Nebenbei das kann auch nicht stimmen. DrawRectangleClip(vscreen,l,t,l+w,t+h,ToColor(colBlack)); Das DrawRectangleClip(vscreen,l,t,w,h,ToColor(colBlack)); ist korrekt. Hochladen tu ich hier nichts mehr da die kompilierte EXE wieder mal als ![]() Da die Administration so freundlich ist alle meine Projekte hier zu Untergraben spare ich mir das. Geändert von venice2 (22. Mai 2022 um 13:37 Uhr) |
![]() |
Registriert seit: 26. Nov 2004 Ort: Dresden 283 Beiträge Delphi 10.3 Rio |
#4
[QUOTE=venice2;1506171]Ok du hast Rows und Cols vertauscht.. deshalb wurde deine TStringliste nicht gefüllt in deinem Beispiel!
Versuche das hier. Habe keinen ElistError läuft wie es soll.
Delphi-Quellcode:
Danke wie verrückt! Brett vorm Kopp gehabt, bei den vertauschten Dimensionen. Oh Mann, manchmal ist es einfach zum Verzweifeln, man findet den Fehler nicht und dann ist es so ne simple Sache.
program Project3;
{$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, System.Classes, Contnrs; type TGridColumn = class(Tobject) private FWidth: Integer; FHeight: Integer; FLeft: Integer; FTop: Integer; public constructor Create; property Width: Integer read FWidth write FWidth; property Height: Integer read FHeight write FHeight; property Left: Integer read FLeft write FLeft; property Top: Integer read FTop write FTop; end; TCustomGrid = class(Tobject) private FCols: Integer; FRows: Integer; FRowsContainer: TObjectList; procedure SetCols(AValue: Integer); procedure SetRows(AValue: Integer); public constructor Create; destructor Destroy; override; procedure Paint; property Cols: Integer read FCols write SetCols; property Rows: Integer read FRows write SetRows; end; var l, t, w, h: Integer; { TGridColumn } constructor TGridColumn.Create; begin inherited Create; end; { TCustomGrid } constructor TCustomGrid.Create; begin inherited Create; FRowsContainer := TObjectList.Create; end; destructor TCustomGrid.Destroy; begin FRowsContainer.Free; inherited; end; procedure TCustomGrid.SetCols(AValue: Integer); var ACol, ARow: Integer; gridColumn: TGridColumn; begin if FCols = AValue then Exit; FCols := AValue; for ARow := 0 to FRows - 1 do begin for ACol := 0 to FCols - 1 do begin gridColumn := TGridColumn.Create; gridColumn.Width := 200; gridColumn.Height := 20; gridColumn.Left := 10; gridColumn.Top := 10; TStringList(FRowsContainer.Items[ARow]).AddObject(' ', gridColumn); end; end; end; procedure TCustomGrid.SetRows(AValue: Integer); var ARow: Integer; AList: TStringList; begin if FRows = AValue then Exit; FRows := AValue; if FRowsContainer.Count > 0 then FRowsContainer.Clear; // falls mehrfacher Aufruf von SetRows Container löschen; for ARow := 0 to FRows - 1 do begin AList := TStringList.Create; AList.Capacity := 5; AList.Duplicates := dupAccept; FRowsContainer.Add(AList); end; end; procedure TCustomGrid.Paint; var ACol, ARow { , r, b } : Integer; gc: TGridColumn; sl: TStringList; rc: TObjectList; begin for ARow := 0 to FRowsContainer.Count - 1 do begin for ACol := 0 to TStringList(FRowsContainer.Items[ARow]).Count - 1 do begin rc := FRowsContainer; sl := TStringList(rc.Items[ARow]); gc := TGridColumn(sl.Objects[ACol]); if (ACol < TStringList(FRowsContainer.Items[ARow]).Capacity) and Assigned(TGridColumn(TStringList(FRowsContainer.Items[ARow]).Objects[ACol])) then begin // TGridColumn(TStringList(FRowsContainer.Items[ARow]).Objects[ACol]).Width; w := gc.Width; // TGridColumn(TStringList(FRowsContainer.Items[ARow]).Objects[ACol]).Height; h := gc.Height; // TGridColumn(TStringList(FRowsContainer.Items[ARow]).Objects[ACol]).Left; //aus Originalcode übernommen l := l + gc.Left; // TGridColumn(TStringList(FRowsContainer.Items[ARow]).Objects[ACol]).Top; //aber hier weggelassen t := t + gc.Top; end; writeln('Top: ', t); writeln('Left: ', l); inc(t, h); inc(l, w); end; end; end; var Grid: TCustomGrid; begin try { TODO -oUser -cConsole Main : Code hier einfügen } Grid := TCustomGrid.Create; Grid.Rows := 5; // zuerst Rows initialisieren dann Cols. Grid.Cols := 9; Grid.Paint; writeln('Zurück mit << ENTER >> > >>> ... '); readln; except on E: Exception do writeln(E.ClassName, ': ', E.Message); end; end. ![]() ![]() ![]() w, h müssen ebenfalls global definiert werden weil diese ansonsten nicht initialisiert sind.
Alternativ kannst du die auch local definieren mußt diese dann aber selbst initialisieren und zwar vor der schleife |
![]() |
venice2
(Gast)
n/a Beiträge |
#5
![]() Das also ist es, warum die Variablen global definiert sein müssen
Du weist(Initialisierst) einer variable den wert innerhalb einer Schleife zu. Der Compiler erkennt das aber nicht und gibt die Warnung aus das deine variable nicht initialisiert ist. w, h kann also einen imaginären wert enthalten. Definierte Variablen innerhalb deiner procedure, function können sich nicht selbst initialisieren das mußt du schon selber tun wenn der Compiler die Warnung ausgibt. Und zwar immer vor der entsprechenden Schleife innerhalb nutzt es nichts, wie schon gesagt der Compiler kennt den wert nicht. Deshalb sollte man Warnungen nicht einfach ignorieren. Mit t, l verhält es sich wie folgt. Diese Variablen in der procedure, function zu initialisieren macht keinen sinn weil du diese ja hochzählen willst "Außerhalb der Funktion" deshalb muß diese global oder zumindest innerhalb der Class definiert werden damit diese den Standard wert erhält in diesen Fall 0. Nur außerhalb deiner procedure, function können diese Hochgezählt werden damit die neuen Werte beim nächsten Aufruf erhalten bleiben. Innerhalb dieser wären sie wieder nicht initialisiert. Dein Aufruf! l := l + gc.Left; ergibt also das Ergebnis l = 0 + 10 inkrementiert mit width l := 220 + 200 usw.. Wäre l in deiner Procedure definiert könnte das Ergebnis so aussehen l = 12345 + 10 (weil deine Variable l nicht initialisiert bzw. global definiert wurde) Ein hochzählen der Variable l bringt nichts wenn diese nicht global definiert ist da diese innerhalb der Schleife immer wieder neu zugewiesen wird und somit immer den wert "Irgendeine Zahl + 10" erhält. Wenn dir irgendein Informatiker das hier besser erklären kann. Bitte schön! EDIT: Wenn du nicht möchtest das man von außen global auf die Variablen zugreifen kann dann addiere diese zu deiner TCustomGrid Class
Delphi-Quellcode:
TCustomGrid = class(Tobject)
private FCols: Integer; FRows: Integer; FRowsContainer: TObjectList; l, t, w, h: Integer; // hier! procedure SetCols(AValue: Integer); procedure SetRows(AValue: Integer); public constructor Create; destructor Destroy; override; procedure Paint; property Cols: Integer read FCols write SetCols; property Rows: Integer read FRows write SetRows; end; Geändert von venice2 (24. Mai 2022 um 12:04 Uhr) |
![]() |
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 |
![]() |
![]() |