Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Konstantenausdruck erwartet (https://www.delphipraxis.net/199487-konstantenausdruck-erwartet.html)

Delbor 26. Jan 2019 11:33

Delphi-Version: 10.2 Tokyo

Konstantenausdruck erwartet
 
Hi zusammen
Folgende Prozedure löst den Fehler aus:
Delphi-Quellcode:
procedure TRadioButtonsFrame.RadioButtonPosition;
  var i, x, y: Integer;
begin
  x := FRadioButtonList.Count -1;
  For i := 0 to FRadioButtonList.Count -1 do
  begin
    Case i of
    0: begin
          FRadioButtonList.Items[i].Left := 12;
          FRadioButtonList.Items[i].Top := 12;
          FRadioButtonList.Items[i].AlignWithMargins := true;
          FRadioButtonList.Items[i].Margins.Top := 5;
          FRadioButtonList.Items[i].Margins.Bottom := 5;
          FRadioButtonList.Items[i].Margins.Left := 80;
          FRadioButtonList.Items[i].Margins.Right := 25;
          FRadioButtonList.Items[i].Top := 12;
        end;
    x: begin                 // x löst den Fehler aus
          FRadioButtonList.Items[i].Left := 12;
          FRadioButtonList.Items[i].Top := 12;
          FRadioButtonList.Items[i].AlignWithMargins := true;
          FRadioButtonList.Items[i].Margins.Top := 5;
          FRadioButtonList.Items[i].Margins.Bottom := 5;
          FRadioButtonList.Items[i].Margins.Left := 80;
          FRadioButtonList.Items[i].Margins.Right := 25;
        end;
    else
      begin
          FRadioButtonList.Items[i].Left := 12;
          FRadioButtonList.Items[i].Top := 12;
          FRadioButtonList.Items[i].AlignWithMargins := true;
          FRadioButtonList.Items[i].Align := alTop;
          FRadioButtonList.Items[i].Margins.Left := 80;
          FRadioButtonList.Items[i].Margins.Right := 25;
          FRadioButtonList.Items[i].Margins.Bottom := 12;
      end;
    end;

  end;
end;
Zur Zeit enthält der Frame 4 Radiobuttons. Das soll aber je nach Bedarf (und Projekt) anders sein können, ohne viel anpassen zu müssen.
if-Abfragen wollte ich bewusst nicht verwenden. Gibts da trotzdem eine Lösung?

Gruss
Delbor

Delphi.Narium 26. Jan 2019 13:05

AW: Konstantenausdruck erwartet
 
Case geht nicht mit Variabeln, links vom Doppelpunkt muss eine Konstante stehen.
Delphi-Quellcode:
if i = 0 then ...
else if i = FRadioButtonList.Count -1 then ...
else der Rest
ist genauso flexibel wie Dein Case. Zwei Werte (1. und letztes Element) werden explizit abgefragt, der Rest geht in die Else am Ende.
Delphi-Quellcode:
procedure TRadioButtonsFrame.RadioButtonPosition;
  var i, x, y: Integer;
begin
  x := FRadioButtonList.Count - 1;
  For i := 0 to x do
  begin
    FRadioButtonList.Items[i].Left := 12;
    FRadioButtonList.Items[i].Top := 12;
    FRadioButtonList.Items[i].AlignWithMargins := true;
    FRadioButtonList.Items[i].Margins.Top := 5;
    FRadioButtonList.Items[i].Margins.Bottom := 5;
    FRadioButtonList.Items[i].Margins.Left := 80;
    FRadioButtonList.Items[i].Margins.Right := 25;
    if (i > 0) and (i < x) then FRadioButtonList.Items[i].Align := alTop;
  end;
end;
Wenn man dann noch in allen Fällen identische Codeteile nicht mehrfach aufführt, wird das schon deutlich kürzer.

Dennis07 27. Jan 2019 09:24

AW: Konstantenausdruck erwartet
 
Oder du indizierst die Werte im Array/Set und prüfst den wert im
Delphi-Quellcode:
case
:

Delphi-Quellcode:
function IndexInt(const AValue: Integer; const AArray: TArray<Integer>): Integer;
begin
  for Result := Low(AArray) to High(AArray) do
  begin
    if AArray[Result] = AValue then
    begin
      Exit;
    end;
  end;
  Result := Pred(Low(AArray));
end;

var
  X: Integer = 45;
begin
  case IndexInt(X, [0, 45]) of
    0: {...}; //(x = 0)
    1: {...}; //(x = 45)
  end;
end.
Wenn du Lina Components installiert hast, dann hast du in der Unit
Delphi-Quellcode:
uSysTools
dafür die überladenen Routinen
Delphi-Quellcode:
ArrayPos({...})

Delbor 27. Jan 2019 18:59

AW: Konstantenausdruck erwartet
 
Liste der Anhänge anzeigen (Anzahl: 2)
Hi zusammen

Zitat:

Zitat von Delphi.Narium (Beitrag 1424197)
Wenn man dann noch in allen Fällen identische Codeteile nicht mehrfach aufführt, wird das schon deutlich kürzer.

Das hab ich mir mal ganz schnell zu Herzen genommen so ganz nach dem DRY-Prinzip.
Damitsieht eine Umsetzung - es ist nicht die einzige - jetzt so aus:
Delphi-Quellcode:
procedure TRadioButtonsFrame.RadioButtonPosition2;
  var i, x, y, LHeight: Integer;
begin
  x := FRadioButtonList.Count - 1;

  For i := 0 to x do
  begin
    LHeight := (i+1) * FRadioButtonList.Items[i].Height;
    FRadioButtonList.Items[i].Left := 12;
    FRadioButtonList.Items[i].Top := LHeight;
    FRadioButtonList.Items[i].AlignWithMargins := true;
    FRadioButtonList.Items[i].Margins.Top := 5;
    FRadioButtonList.Items[i].Margins.Right := 25;
    FRadioButtonList.Items[i].Margins.Bottom := 5;
    FRadioButtonList.Items[i].Margins.Left := 80;

//    if i = 0 then
//      FRadioButtonList.Items[i].Top := PnlRadioButtons.ClientHeight div 4;
//    if i = x then
//      FRadioButtonList.Items[i].Align := alTop;
  end;
end;
Die auskommentierten Zeilen sind
  • Im ersten Fall 'versuchsweise' auskommentiert
  • Im zweiten Fall kontraproduktiv, da <Align:=alTop> gesetzte Elemente über den bereits alTop gesetzten Elementen angeordnnet werden
Das Ergebnis :
Anhang 50625

Eine weitere Version, aufgrund des obigen Ergebnisses:

Delphi-Quellcode:
procedure TRadioButtonsFrame.RadioButtonPosition3;
  var i, x, y, LHeight : Integer;
begin
  x := FRadioButtonList.Count -1;
  i := 0;
  FRadioButtonList.First;

  While i <= X do
  begin
    FRadioButtonList.Items[i].Left := 12;
    FRadioButtonList.Items[i].AlignWithMargins := true;
    FRadioButtonList.Items[i].Margins.Top := 5;
    FRadioButtonList.Items[i].Margins.Bottom := 5;
    FRadioButtonList.Items[i].Margins.Left := 80;
    FRadioButtonList.Items[i].Margins.Right := 25;
    LHeight := (i+1) * FRadioButtonList.Items[i].Height;
    if i = 0 then
      FRadioButtonList.Items[i].Top := LHeight+PnlRadioButtons.Height div 4
    else
      FRadioButtonList.Items[i].Top := LHeight;


//    if i = x then
//      FRadioButtonList.Items[i].Align := alTop;
    inc(i);
    FRadioButtonList.NextRec;
  end;
Und das Resultat:
Anhang 50626

Die Radiobuttons befinden sichin einer Objectliste:
Delphi-Quellcode:
constructor TRadioButtonsFrame.Create(AOwner: TComponent);
begin
  inherited;
  FRadioButtonList := TDataObjectList<TRadioButton>.Create();
  FRadioButtonList.OwnsObjects := True;
  FRadioButtonList.Capacity := 5;
  FRadioButtonList.insert(0,RadBtnPdf);
  FRadioButtonList.Insert(1, RadBtnBitmap);
  FRadioButtonList.Insert(2, RadBtnExif);
  FRadioButtonList.Insert(3, RadBtnJpeg);
//  RadioButtonPosition3;
end;
Die Elemente sollen mit deutlichem Abstand zum Left und Top des Containers (Hier Panel) angeordnet werden.


Gruss
Delbor

jaenicke 27. Jan 2019 19:19

AW: Konstantenausdruck erwartet
 
Etwas übersichtlicher würde es ja schon, wenn das Innere der Schleife in eine Prozedur ausgelagert wäre.

Wie soll die Anordnung denn eigentlich aussehen? Vielleicht lässt sich da ja auch etwas mit flowpanel oder ähnlichem machen.

Delbor 27. Jan 2019 19:36

AW: Konstantenausdruck erwartet
 
Hi jaenicke

Es sollte in etwa so aussehen, wie im 1. Anhang, wobei die Reihenfolge so sein sollte, wie in der Objectliste, wobei alle die selben Leftwerte haben sollten, aber nur das erste Element einen grösseren Topwert.
Wieso eines der Elemente in meiner While-Schleife "verschluckt" (überzeichnet?) wird, kann ich mir im Moment nicht erklären.

Gruss
Delbor

Delbor 28. Jan 2019 08:41

AW: Konstantenausdruck erwartet
 
Liste der Anhänge anzeigen (Anzahl: 2)
Hi zusammen

Inzwischen hat sich einiges geändert, und das Ziel ist schon fast erreicht:
Delphi-Quellcode:
procedure TRadioButtonsFrame.RadioButtonPosition2;
  var i, x, y, LHeight, LLeft: Integer;
begin
  For i := 0 to x do
  begin
    FRadioButtonList.Items[i].Width := 50;
    LLeft := (PnlRadioButtons.ClientWidth div 2) - (FRadioButtonList.Items[i].Width div 2);
    LHeight := (i * FRadioButtonList.Items[i].Height) + PnlRadioButtons.ClientHeight div 3;
    FRadioButtonList.Items[i].Left := LLeft;
    FRadioButtonList.Items[i].Top := LHeight;
  end;
end;
Mein Test sah/sieht inzwischen so aus:
Anhang 50627
Der Frame (grosses Radiobuttonfeld)soll das kleine Radiobutton-Panel links unten ersetzen, erledigt diese Aufgabe jeoch noch nicht wirklich zur Zufriedenheit:
Anhang 50628
Das erste Element sitzt zu tief. Ausserdem sollen dem Frame ohne grosse weitere Bearbeitung weitere Elemente hinzugefügt werden können und dann allenfalls die Scrollbalken des Frames aktiviert werden.
wobei ich mich allerdings frage, ob sich hier nicht die Verwendung einer Scrollbox empfehlen würde.

Gruss
Delbor

Delphi.Narium 28. Jan 2019 10:56

AW: Konstantenausdruck erwartet
 
Wenn ich mehrere Sachen auf ein Panel pappe (automatisch) und zwischen Panelrand und Element ein Platz sein soll, dann setze ich im Panel zuerstmal BorderWidth auf 4. Man kann aber auch mehr oder weniger nehmen.

Dann werden die Elemente (meist Speedbuttons) mit Align := alTop "nach oben" gesetzt. Da das aber zu einer "umgekehrten" Reihenfolge führt, setzte ich Top dann auf die Höhe des Panels. Durch diese Kombination werden die Elemente schön von oben nach unten auf dem Panel angeordnet. Sollte eigentlich auch mit jedem anderen Container funktionieren.

Und das Panel hat bei mir immer die Breite, die die Elemente haben sollen + 2 * den Wert, den ich bei BorderWidth haben möchte. Ggfls. wird das Panel mit diesen Abmaßen dann auf einen anderen Container gepappt, um an die "richtige" Position zu kommen.

ungefähr sowas:
Delphi-Quellcode:
procedure TRadioButtonsFrame.RadioButtonPosition2;
  var i, x: Integer;
begin
  PnlRadioButtons.BorderWidth := (PnlRadioButtons.ClientWidth                              - FRadioButtonList.Items[0].Width) div 2;
  x := FRadioButtonList.Count - 1;
  For i := 0 to x do
  begin
    FRadioButtonList.Items[i].Top  := PnlRadioButtons.Height;
    FRadioButtonList.Items[i].Align := alTop;
  end;
end;
Da in der Regel das letzte Element, das per Align := alTop eingefügt wird, ganz oben landet, kann man die Reihenfolge beim Ordnen auch einfach umkehren:
Delphi-Quellcode:
procedure TRadioButtonsFrame.RadioButtonPosition2;
  var i, x: Integer;
begin
  PnlRadioButtons.BorderWidth := (PnlRadioButtons.ClientWidth                              - FRadioButtonList.Items[0].Width) div 2;
  x := FRadioButtonList.Count - 1;
  for i := x downto 0 do FRadioButtonList.Items[i].Align := alTop;
end;
Kommt dabei jetzt das raus, was Du Dir vorstellst?

Uwe Raabe 28. Jan 2019 13:27

AW: Konstantenausdruck erwartet
 
Zitat:

Zitat von Delphi.Narium (Beitrag 1424297)
Wenn ich mehrere Sachen auf ein Panel pappe (automatisch) und zwischen Panelrand und Element ein Platz sein soll, dann setze ich im Panel zuerstmal BorderWidth auf 4.

Na ja, heutzutage verwendet man da wohl eher AlignWithMargins und passende Werte für Margins und Padding. Da müssen schon ganz exotische Anforderungen kommen, bevor man mit dem bordeigenen Alignment an die Grenzen stößt. Und dann gibt es ja auch noch TGridPanel, TFlowPanel, TRelativePanel, TStackPanel und TCardPanel. Da sollte doch für fast jeden Anwendungsfall was dabei sein.

Delbor 28. Jan 2019 17:56

AW: Konstantenausdruck erwartet
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hi zusammen

Ich hab die ganzen Align-Dinger rausgekippt, und ich bin überzeugt, das war richtig so.
Zur Zeit habe ich allerdings folgendes Problem in der kleinen Frameinstanz:
Anhang 50629
Wie man sieht: vom dritten Radiobutton sieht man gerade mal noch einen kleinen Rest des Kreises; ausserdem sind ab da die Radiobuttons eingerückt.

Aus einem Reportfile:
Zitat:

28.01.2019 18:21:15
----------------
procedure TRadioButtonsFrame.RadioButtonPosition2 - 1
LLeft := 7
LHeight := 30
LLeft := 7
LHeight := 49
LLeft := 16
LHeight := 72
LLeft := 16
LHeight := 93
procedure TRadioButtonsFrame.RadioButtonPosition2 - 1
LLeft := 371
LHeight := 55
LLeft := 371
LHeight := 74
LLeft := 371
LHeight := 97
LLeft := 371
LHeight := 118
Die Zahlen hinter den Prozedurköpfen zählen die OnResize-Events. Im aktuellen Fall habe ich gerade mal kompilliert und wieder beendet. Im erstten Prozedurblock sieht man den Verlauf der LLeft-Werte sehr gut; die ersten beiden haben den Wert 7, die letzten zwei den Wert 16.

Ich hatte auch schon Reports obiger Art mit deutlich mehr als 8000 Zeilen; probehalber hatte ich gestartet und dann die Form in verschiedene Richtungen grösser gezogen. Und da ja offenbar OnReze für jedes Steuerelement aufgerufen wird, kommt auch schon bei einem kleinen Programm was zusammen...

Woher die unterschiedlichen LLeftwerte im ersten Block allerdings kommen, ist mir rätselhaft. Einige Fehler breruhten darauf, das irgendwelche Align- oder Margins-Werte im OI noch gesetzt waren. Aber da ist mittlerweile alles bereinigt. Ansonsten habe ich keinen blassen Schimmer, wie die verschiedenen Werte entstehen.

Gruss
Delbor


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:47 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz