AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Cross-Platform-Entwicklung Texthöhen-Berechnung fehlerhaft in FMX auf Android

Texthöhen-Berechnung fehlerhaft in FMX auf Android

Ein Thema von AuronTLG · begonnen am 19. Sep 2018 · letzter Beitrag vom 30. Sep 2018
Antwort Antwort
AuronTLG

Registriert seit: 2. Mai 2018
Ort: Marburg
239 Beiträge
 
Delphi 12 Athens
 
#1

Texthöhen-Berechnung fehlerhaft in FMX auf Android

  Alt 19. Sep 2018, 11:40
Hallo,

ich habe ein äußerst nerviges Problem auf einer App, mit dem ich mich gerade rumschlagen muss:

Ich verwende eine TreeView, deren Nodes mehrzeiligen Text beinhalten können, und deren Größe dementsprechend angepasst werden muss.
Mein Problem ist, dass Firemonkey auf Android anscheinend für einen gewissen Textlängen-Bereich nach einem erfolgten WordWrap die Texthöhe nicht richtig berechnet und von einem einzeiligen Text ausgeht, wodurch der zweizeilige Text in der Node abgeschnitten ist.
Dies tritt nach bisherigem Stand nur auf Android auf.

Ich hatte erst angenommen, dass meine manuelle Berechnung falsch sein könnte und habe die Standard-TreeView durch die TMSFMXTreeView ersetzt, welche die Node-Höhe automatisch kalkuliert, doch bescheuerterweise tritt derselbe Fehler dort genauso auf, was natürlich Sinn machen würde bei meiner Vermutung, denn letztendlich benutzt diese Komponente natürlich auch an irgendeinem Punkt die normalen Delphi-Methoden wie z.B. MeasureText etc...
TMS haben mir auch nach Prüfung bestätigt, dass das wohl ein Firemonkey-Problem ist und sie daran nichts ändern können.

Nur um sich den Fehler mal visuell vorstellen zu können:
Angenommen, man fügt zu der TreeView sukzessiv immer mehr Nodes hinzu, die jedesmal einen kleinfügig längeren Text enthalten (z.B. immer ein kurzes 'l' mehr), dann sieht man, dass die ersten paar zweizeiligen Nodes immer noch diesselbe Größe wie die einzeiligen haben und der Text dementsprechend abgeschnitten ist. Dann nach ein paar fehlerhaften Nodes ist die Berechnung dann plötzlich korrekt und es wird richtig angezeigt.
Dies setzt sich natürlich auch so weiter fort beim Übergang zu dreizeilig etc...

In der Praxis bedeutet das, dass ein TreeView-Eintrag, der eine Textlänge hat, die in solch einen Fehlerbereich reinfällt, mit abgeschnittenem Text angezeigt wird, was zwar relativ selten vorkommt, aber absolut hässlich aussieht, wenn es dann mal passiert.

Ich bin schon seit geraumer Zeit am rumwühlen und experimentieren, aber ich bekomme diesen Fehler einfach nicht vollständig weg.

Ich habe z.B. schon probiert, ein unsichtbares Label irgendwohin zu legen, dem ich die Breite, Einstellungen und Font der Node verpasse und dann der Node die Höhe vom Label verpasse, was den Fehlerbereich reduziert, aber nicht vollständig auflöst.

Ebenso hab ich auch schon versucht, mit TTextLayouts rumzuspielen, womit ich den Fehler leider auch nicht komplett weg bekomme.

Momentan bin ich dabei, tief in den Eingeweiden der Delphi-Klassen rumzuwühlen, in der Hoffnung dort irgendwo eine Möglichkeit zur Behebung zu finden, aber bis jetzt ohne Erfolg.

Da mich das Ganze langsam in den Wahnsinn treibt, wollte ich hier mal nachfragen, ob jemand schonmal dasselbe oder ein ähnliches Problem hatte, und eventuell eine Lösung bzw einen Workaround gefunden hat.
  Mit Zitat antworten Zitat
knaeuel

Registriert seit: 2. Jul 2007
110 Beiträge
 
Delphi 10.3 Rio
 
#2

AW: Texthöhen-Berechnung fehlerhaft in FMX auf Android

  Alt 19. Sep 2018, 13:41
ich hab von treeviews jetzt nicht die dicke ahnung, aber trotzdem habe ich ideen, wie du evtl. einen workaround hinbekommen könntest.

1. hast du es schonmal statt mit TLabel mit TText probiert? (Geht das mit Treeview?) Oder bleibt das Problem bestehen?

2. Bei TText und vermutlich auch beim Label kannst du die Maße in ein TRectF ausgeben lassen. MeasureText hattest du ja bereits selber erwähnt.

Delphi-Quellcode:
var Textfeld: TText; //oder ggf. aus Komponente
    R: TRectF;

  //evtl. selbst erzeugen? mit Treeview als Parent?
  Textfeld:= TText.Create(DeinTreeView);

  Textfeld.Canvas.Font.Size := FontSize; //Schriftgrad eintragen!!
  Textfeld.Canvas.MeasureText(R, 'mein Text', {wordwrap:} False, [], TTextAlign.Leading, TTextAlign.Leading);
wenn die Ergebnisse immer nur einzeilige Abmessungen ergeben, dann hast du zumindest den Platz, den eine Zeile benötigt. Damit müsste sich doch arbeiten lassen, oder?
Wolfgang
  Mit Zitat antworten Zitat
AuronTLG

Registriert seit: 2. Mai 2018
Ort: Marburg
239 Beiträge
 
Delphi 12 Athens
 
#3

AW: Texthöhen-Berechnung fehlerhaft in FMX auf Android

  Alt 19. Sep 2018, 14:20
Das MeasureText scheint ja genau das Problem zu sein.
Sowohl die TMS-Komponente als auch meine vorige manuelle Lösung verwenden ja genau diese Methode.

Das MeasureText macht nämlich auch nichts anderes als ein TTextlayout zu erzeugen, dieses mit den entsprechenden Einstellungen zu füttern und das TRectF, was dabei rauskommt, in die Variable zu schreiben.

Das habe ich bereits manuell probiert, behebt das Problem aber leider auch nicht.

Und wie gesagt, das Problem tritt nur auf Android auf, nicht auf IOS, weswegen ich vermute, dass das sehr tief versteckt ist.

Der Trick, mit dem ich der Lösung am nächsten gekommen bin, ist wie gesagt die Methode mit dem Label. D.h. Label-Width auf Node-Width setzen, Einstellungen angleichen, Text reinsetzen und die dadurch entstandene Label.Höhe zurück an die Node übergeben.
Das begrenzt das Problem bei mir auf einen winzigen Bereich, schließt es aber leider nicht vollkommen aus.

Ich kann das Problem sogar komplett beheben, indem ich auf einem bestimmten Smartphone die Width manuell reinreguliere (Label.Width := Node.Width - 4; z.B.), aber auf einem anderen Smartphone stimmt diese Feinregulierung dann nicht mehr, was für mich ein weiteres Indiz ist, dass da ganz grundsätzlich was falsch läuft bei der Kalkulation.
Wie gesagt, es ist nur ein verhältnismäßig kleiner Bereich, in dem es schief geht, aber leider ist das bereits zu viel.
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#4

AW: Texthöhen-Berechnung fehlerhaft in FMX auf Android

  Alt 19. Sep 2018, 14:23
Dann versuche es über Umwege mit GDIPlus.

bsp..

Delphi-Quellcode:
function GetTextBound(UseText: WideString; UseFont: WideString; UseSize: single; var bW: integer;
   var bH: integer; FontCollection: Pointer; UseStrFormat: integer): GPSTATUS; stdcall;
var
   Graphics: LONG_PTR;
   Fam: GpFontFamily;
   TempFont: GpFont;
   DC: HDC;
   strFormat: GPSTRINGFORMAT;
   boundingBox, layoutRect: TGPRectF;
begin
   Result := GenericError;
   strFormat := nil;
   Fam := nil;
   TempFont := nil;
   Graphics := 0;

   // Create matching font
   try
     GdipCheck(GdipCreateFontFamilyFromName(PWideChar(UseFont), FontCollection, Fam));
     if Assigned(Fam) then
     begin
       GdipCheck(GdipCreateFont(Fam, UseSize, 0, 2, TempFont));
       if Assigned(TempFont) then
       begin
         DC := GetDC(GetDesktopWindow);

         GdipCheck(GdipCreateStringFormat(0, 0, strFormat));
         GdipCheck(GdipCreateFromHDC(DC, Graphics));

         FillChar(boundingBox, SizeOf(boundingBox), 0);
         FillChar(layoutRect, SizeOf(layoutRect), 0);

         GdipCheck(GdipMeasureString(Graphics, PWideChar(UseText), Length(UseText), TempFont,
           @layoutRect, strFormat, @boundingBox, nil, nil));

         if Assigned(strFormat) then
           GdipCheck(GdipDeleteStringFormat(strFormat));

         bW := round(boundingBox.Width + 0.5);
         bH := round(boundingBox.Height + 0.5);

         if UseStrFormat <> 0 then
           Swap(bW, bH);

         if (bW <> 0) or (bH <> 0) then
           Result := OK;

         ReleaseDc(GetDesktopWindow, DC);
       end;
     end;
   finally
     if Graphics <> 0 then
       GdipCheck(GdipDeleteGraphics(Graphics));
     if Assigned(TempFont) then
       GdipCheck(GdipDeleteFont(TempFont));
     if Assigned(Fam) then
       GdipCheck(GdipDeleteFontFamily(Fam));
   end;
end;
Wie du das dann mit dem realen GDIPlus Wrapper umsetzt mag mal dahin gestellt sein.
Aber so in etwas sollte es gehen.

gruss
  Mit Zitat antworten Zitat
Benutzerbild von Sherlock
Sherlock

Registriert seit: 10. Jan 2006
Ort: Offenbach
3.762 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: Texthöhen-Berechnung fehlerhaft in FMX auf Android

  Alt 19. Sep 2018, 14:24
Gibt es GDI+ auf Android?

Sherlock
Oliver
Geändert von Sherlock (Morgen um 16:78 Uhr) Grund: Weil ich es kann
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#6

AW: Texthöhen-Berechnung fehlerhaft in FMX auf Android

  Alt 19. Sep 2018, 14:25
Gibt es GDI+ auf Android?

Sherlock
grrr...
Denke nicht. LOL

sollte vorher besser lesen. Schon das zweite mal Heute. Heheheee

gruss

Geändert von EWeiss (19. Sep 2018 um 14:28 Uhr)
  Mit Zitat antworten Zitat
knaeuel

Registriert seit: 2. Jul 2007
110 Beiträge
 
Delphi 10.3 Rio
 
#7

AW: Texthöhen-Berechnung fehlerhaft in FMX auf Android

  Alt 19. Sep 2018, 14:33
ich habe gerade die Toast-Message von Android für iOS/Windows nachprogrammiert und benutze dabei MeasureText. Ich habs nicht vollständig ergründet, aber es schien mir mit MeasureText nur das Problem zu geben, dass es die Textabmessungen immer einzeilig berechnet hat. Also habe ich bei mehrzeiligen Texten die Höhenberechnung auf basis der ein-Zeilen-Höhe selbst durchgeführt. das hat funktioniert.
Wolfgang
  Mit Zitat antworten Zitat
Rollo62

Registriert seit: 15. Mär 2007
3.896 Beiträge
 
Delphi 12 Athens
 
#8

AW: Texthöhen-Berechnung fehlerhaft in FMX auf Android

  Alt 19. Sep 2018, 14:46
Ich würde mir die OrginalSources.pas suchen wo MeasureText wirklich verwendet wird.
Wenn sich das Problem einfach überschreiben oder ableiten in eine neue Klasse lässt, dann mach das so.

Falls es komplizierter ist, dann
- fixe die OrginalSources.pas
- kopiere die Orginal-Source unter einem Fixes Verzeichnis
- und diese dann statt der OrginalUnit in die Projekt einbinden
- jetzt wird deine Fixes\OrginalSources.pas verwendet, statt der orginalen von Emba.
- dann editiere in deiner Fixes\Source.pas die Stelle wo das benutzt wird
- benutze MeasureText(Texts[0]) für die erste Zeile und multipliziere mit Length(Text) (so in der Art)
- oder bereche, und addiere MeasureText( Texts[I] ) für jede Zeile, und bilde die Summe
- arbeite dann mit der Summe über alle Zeilen weiter
- ! leider funktioniert das so nicht immer so problemlos, aber oft

Zum Glück hast du ja die Sourcen dabei (hoffe ich), um solche Probleme selber zu lösen

Rollo
  Mit Zitat antworten Zitat
TurboMagic

Registriert seit: 28. Feb 2016
Ort: Nordost Baden-Württemberg
2.809 Beiträge
 
Delphi 12 Athens
 
#9

AW: Texthöhen-Berechnung fehlerhaft in FMX auf Android

  Alt 30. Sep 2018, 20:52
Bitte auch dieses Berechnungsproblem, falls möglich inklusive einem simplen Demo Programm, in Quality Portal erfassen! Dann besteht zumindest eine Chance auf einen fix. Die erhaltene Report Nummer dann ruhig hier psoten, evtl. möchten das andere auch verfolgen und dafür stimmen.

=> quality.embarcadero.com, falls noch nicht bekannt benutzen.
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es 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

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:30 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