Autor Beitrag
Happy_Penguin
Hält's aus hier
Beiträge: 9



BeitragVerfasst: Fr 11.03.16 15:57 
Hallo,

ich habe ein Programm, welches mehrzeilige Strings ähnlich wie eine PowerPoint-Präsentation anzeigen soll. Dabei besteht die entsprechende Form aus einem Label, der den gesamten Platz ausfüllt und den Text entsprechend umbricht (Align := alClient; WordWrap := True;). Nun möchte ich, dass, wenn der String zu lange ist und über das Fenster hinausgeht, die Schriftgröße des Labels so lange verkleinert wird, bis es passt.

Hat da jemand eine Idee? Signalisiert der Label, wenn der Platz nicht ausreicht?

Vielen Dank schon Mal für alle Antworten.

_________________
Linux 3.20 wäre ja langweilig...
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Fr 11.03.16 18:06 
Hier findest du eine Demo wie so etwas vom Prinzip her aussieht:
www.delphi-forum.de/viewtopic.php?p=557541
Mit einem Label funktioniert das analog, aber eventuell ist selbst zeichnen ohnehin für dich besser.
Happy_Penguin Threadstarter
Hält's aus hier
Beiträge: 9



BeitragVerfasst: Sa 12.03.16 22:42 
Hallo,

erst Mal Danke für die Antwort! Ich möchte aber an einem Label festhalten, da dort viele für mich nützliche Funktionen schon implementiert sind, wie automatischer Zeilenumbruch bzw. umfassende Ausrichtungsmöglichkeiten von Text. In einer PaintBox bzw. beim direkten Nutzen von Canvas müsste ich das doch größtenteils von Hand implementieren, oder?

Also ich brauche eigentlich nur eine Möglichkeit, dass der Label signalisiert, wenn sein Platz nicht mehr ausreicht.

Schönes Wochenende noch!

_________________
Linux 3.20 wäre ja langweilig...
ub60
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 762
Erhaltene Danke: 127



BeitragVerfasst: So 13.03.16 13:31 
Das sollte Dir weiterhelfen:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
procedure TForm1.Button1Click(Sender: TObject);
var s : String;
    MaxBreite, Breite, Schriftgroesse : Integer;
begin
  MaxBreite:=Label1.Width;
  Schriftgroesse:=32;
  Label1.Font.Name:='Arial';
  Label1.Canvas.Font.Name:='Arial';
  s:='Das ist ein sehr, sehr langer Text für das Label';
  Label1.Caption:=s;
  repeat
    Label1.Font.Size:=Schriftgroesse;
    Label1.Canvas.Font.Size:=Schriftgroesse;
    Breite:=Label1.Canvas.TextWidth(s);
    Application.ProcessMessages;
    Dec(Schriftgroesse);
    Sleep(100);
  until Breite<MaxBreite;
end;


Eventuell geht es auch einfacher, aber der Quelltext funktioniert bei mit zufriedenstellend.
Für das Wordwrapping musst Du Dir überlegen, wie groß Dein Text minimal sein soll. Dann muss der String (sich wortweise vergrößernd) untersucht werden.
Für die zeilenweise Anpassung benötigst Du dann noch TextHeight.

edit:
Und jetzt das Ganze noch einmal für ein komplettes Wordwrapping. Dazu missbrauche ich allerdings ein (unsichtbares zweites Label:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
var s : String;
    MaxHoehe, Hoehe, Schriftgroesse : Integer;
begin
  MaxHoehe:=Label1.Height;
  Schriftgroesse:=32;
  Label1.Font.Name:='Arial';
  Label2.Font.Name:='Arial';
  s:='Das ist ein sehr, sehr langer Text für das Label. Und der Text soll jetzt für das Label passend gemacht werden.';
  Label1.Caption:=s;
  // Das ist ein Dummy-Label, was man unsichtbar machen kann.
  Label2.Caption:=s;
  Label2.WordWrap:=True;
  Label2.Width:=Label1.Width;
  Label2.AutoSize:=True;
  //ShowMessage(IntToStr(Label2.Width));
  repeat
    Label2.Width:=Label1.Width;  // Die Zeile ist wichtig!
    Label2.Font.Size:=Schriftgroesse;
    Application.ProcessMessages;
    Dec(Schriftgroesse);
    Sleep(100);
    Hoehe:=Label2.Height;
  until Hoehe<MaxHoehe;
  Label1.Font.Size:=Schriftgroesse+1;
end;


ub60
WasWeißDennIch
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 653
Erhaltene Danke: 160



BeitragVerfasst: So 13.03.16 15:31 
Ich würde es so versuchen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
function TextFitsInRect(DestRect: TRect; const Text: string;
  DestCanvas: TCanvas): Boolean;
var
  tmpCanvas: TCanvas;
  R: TRect;
begin
  tmpCanvas := TCanvas.Create;
  try
    tmpCanvas.Handle := DestCanvas.Handle;
    tmpCanvas.Font.Assign(DestCanvas.Font);
    R := DestRect;
    DrawText(tmpCanvas.Handle, PChar(Text), -1, R, DT_TOP or DT_LEFT or
      DT_WORDBREAK or DT_CALCRECT);
    Result := R.Height <= DestRect.Height;
  finally
    tmpCanvas.Free;
  end;
end;

procedure TFormTest.ButtonTestClick(Sender: TObject);
begin
  while not TextFitsInRect(LabelTest.ClientRect, LabelTest.Caption, LabelTest.Canvas) do
    LabelTest.Font.Size := LabelTest.Font.Size - 1;
end;
Happy_Penguin Threadstarter
Hält's aus hier
Beiträge: 9



BeitragVerfasst: Mo 14.03.16 20:37 
Hallo,

danke für eure Antworten. Leider funktioniert es noch nicht :-(
ub60: Leider werden bei der Variante automatische Zeilenumbrüche nicht berücksichtigt. Gibt es da noch eine Möglichkeit, dies zu ändern?
WasWeißDennIch: Leider ist DrawText nur was für Windows-Nutzer. Deswegen kommt das für mich nicht in Frage.

Tut mir leid, dass ich euch mit dieser vielleicht nervigen Frage aufhalte. Aber ich habe auch nach langer Internetrecherche noch keine Lösung gefunden, die funktioniert. Im Prinzip soll der Label ja einfach nur bescheid sagen, wenn sein Platz nicht ausreicht.

_________________
Linux 3.20 wäre ja langweilig...
WasWeißDennIch
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 653
Erhaltene Danke: 160



BeitragVerfasst: Mo 14.03.16 20:45 
Geht es um Firemonkey? Dann ist der Thread in der VCL-Sparte wohl nicht ganz richtig. Sei' s drum: evtl. geht es mit einem TTextLayout und dessen TextHeight-Eigenschaft, aber das habe ich jetzt nicht ausprobiert.
Martok
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 3661
Erhaltene Danke: 604

Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
BeitragVerfasst: Mo 14.03.16 20:48 
Lazarus (bzw. die LCL) hat für Label eine Eigeneschaft "OptimalFill". Dort nimmt man eine einfache binäre Suche und TextExtent um eine passende Größe zu finden. Vielleicht kannst du ja da was klauen ;)

_________________
"The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."
ub60
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 762
Erhaltene Danke: 127



BeitragVerfasst: Di 15.03.16 19:28 
Ich kann das Problem nicht nachvollziehen. Bei mir funktioniert es (siehe Bilder).
Oder habe ich es falsch verstanden?

Label1

Label2

ub60
Einloggen, um Attachments anzusehen!