Einzelnen Beitrag anzeigen

delphifan2004

Registriert seit: 26. Nov 2004
Ort: Dresden
266 Beiträge
 
Delphi 10.3 Rio
 
#16

AW: EListError, warum? ObjectList mit Daten füllen

  Alt 21. Mai 2022, 20:21
In diesem Testprojekt ist der EListerror weg aber von Paint wird nichts ausgegeben nur die Zeile "Zurück mit << ENTER > >> ...'

Delphi-Quellcode:
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.
@venice2:

Mein Code:

Delphi-Quellcode:
      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.
Damit werden doch die Variablen l,t,w und h in der DrawRectangleClip Prozedur verwendet. Aber der EListError verhindert, dass ich dorthin komme.
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.

Zitat von venice2:
// t wird anschließend incrementiert aber nicht mehr benutzt weil die Variable t nicht global definiert ist und vorher nicht zugewiesen wird.
Warum müssen diese vars global definiert sein. Ich will doch lokal zeichnen? Und nach meinem Verständnis ist doch DrawRectangleClip() innerhalb der Schleife. Einen Strich oder Punkt müsste ich doch dann wenigstens sehen? Leider ist mir hier gar nichts klar.


Der von mir gesuchte Fehler muss hier liegen:

Delphi-Quellcode:
      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
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.

Geändert von delphifan2004 (21. Mai 2022 um 20:44 Uhr)
  Mit Zitat antworten Zitat