Einzelnen Beitrag anzeigen

venice2
(Gast)

n/a Beiträge
 
#18

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

  Alt 21. Mai 2022, 22:19
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.
Zitat:
Warum müssen diese vars global definiert sein. Ich will doch lokal zeichnen?
Habe ich doch hier schon erklärt.

Wie Uwe schon schrieb..
Zitat:
Warum überhaupt dieses Hochzählen, wo die Werte doch im nächsten Durchlauf wieder gesetzt werden?
Setze l,t,w,h local und prüfe dann das Ergebnis nochmal dann verstehst du warum.
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:
w := 0;
h := 0;
EDIT:
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 Trojan und Malware erkannt wurde.
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)
  Mit Zitat antworten Zitat