Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Cross-Platform-Entwicklung (https://www.delphipraxis.net/91-cross-platform-entwicklung/)
-   -   Delphi Verständnisprobleme mit FMX (https://www.delphipraxis.net/185000-verstaendnisprobleme-mit-fmx.html)

Ookami 6. Mai 2015 20:42

Verständnisprobleme mit FMX
 
Hallo Gemeinde,

Ich wollte ein lange gepflegtes Tool auf einen neuen Stand bringen und den Schritt zur Cross-Plattform-Entwicklung beschreiten.
In einigen Bereichen war ich schon erfolgreich damit, andere bringen mich zur Verzweiflung. Daher ich wende mich mal wieder hilfesuchend an alle, speziell diejenigen, die bereits Erfahrung mit FMX und Cross-Plattform-Entwicklung haben.
Da dieses Gebiet für mich Neuland ist, habe ich wie es der Titel anzeigt noch einige Probleme damit.

Jetzt aber zu den Problemen. Generell geht es mir darum, auf die Standard-Komponenten von Delphi XEx Font/Fontfarbe sowie Hintergründe zuzugreifen, also zu verändern. Hintergrund ist der, dass ich manchmal die eingestellten Styles übergehen muss.

Manche Komponenten wie TText kann ich über Textsettings einstellen. Font und Farbe. Dann geht aber irgendwie keine Hintergrundfarbe.
Andere Komponenten wie TRoundrect kann ich den Hintergrund füllen, bringe aber keinen Text zur Anzeige.

Ich würde mich auch nicht scheuen, das was nicht geht durch TPaintbox zu ersetzen. Da geht's aber auch nicht. (zumindest nicht bei mir)
Wie im Netz zu sehen, haben andere Leute auch riesenprobleme damit, aber keine Lösungen, die funktionieren.

Das hier funktioniert
Code:
     RoundRect1.BeginUpdate;
     RoundRect1.Fill.Color := MainForm.EvenRowColor;
     RoundRect1.EndUpdate;
     RoundRect1.Repaint;
Das funktioniert bei Auswahl nur für den 1. Fall. Wähle ich einen 2., 3. usw. geht es nicht mehr. Zurück wieder zu 1. und es geht.
Code:
     TText(ExamplePanelEven).BeginUpdate;
     TText(ExamplePanelEven).Color := FontColor;
     TText(ExamplePanelEven).Font.Family := Fontname;
     TText(ExamplePanelEven).Font.Style := FontStyle;
     TText(ExamplePanelEven).Font.Size  := FontSize;
     TText(ExamplePanelEven).EndUpdate;
     TText(ExamplePanelEven).Repaint;
Das einzige was sich ändert, sind Font und der Text, der angezeigt werden soll.
Habe es bereits TText, TLabel usw ausprobiert, mit und ohne Textsettings versucht. Resultat bleibt gleich.

auch das Beispiel mit einer PaintBox war nicht erfolgreich.

Code:
procedure TFontDialogFrame.PaintBox1Paint(Sender: TObject; Canvas: TCanvas);
begin
     with PaintBox1.Canvas do
     begin
          BeginScene();

          Stroke.Kind:= tBrushKind.Solid;
          Fill.Color := MainForm.EvenRowColor;
          FillRect(PaintBox1.BoundsRect, 1,1, AllCorners, 1);

          FontColor := FontColor;
          Font.Family := Fontname;
          Font.Size  := FontSize;
          Font.Style := FontStyle;
         
          FillText(PaintBox1.BoundsRect, fExample, True, 1, [], TTextAlign.Center, TTextAlign.Center);

          EndScene;
     end;    
end;
Hintergrundfarbe ändert sich wie gewünscht. Nur Text, kommt keiner. Die Daten erreichen alle absolut korrekt ihr vorbestimmtes Ziel,
die Darstellung aber funktioniert nicht. Wenn dann schon mal ein Text angezeigt wird, dann kann ich aber den Font nicht ändern.

Alle Komponenten haben einen Canvas, auf den man doch eigentlich zugreifen können sollte.

Ich wäre dankbar für ein kleines Beispiel, das bei euch so funktioniert, dann kann ich wenigstens von dem dann ausgehen und schauen, warum es bei mir nicht geht.

Ich danke schon mal vorab, und entschuldige mich für den langen Text, wusste es nicht besser abzukürzen.

Harry Stahl 6. Mai 2015 21:44

AW: Verständnisprobleme mit FMX
 
Ganz wichtig ist erst mal, dass Du die verwendete Delphi-Version dabei schreibst, denn gerade bei den von Dir beschriebenen Sachverhalten hat sich von XE2-XE8 in FMX so einiges verändert.

Beispiel: Die Font-Farbe eines TLabels hat man in XE2 noch mit Styles gelöst, später kann man die Farbe direkt mit FontColor setzen (wobei dafür bei Styledsettings FontColor deaktiviert sein muss).

Da die Properties teilweise verschoben wurden (eben FontColor nun als Unterpunkt von Textsettings) kann man das halbwegs verständlich nur erläutern, wenn man weiß um welche Delphi-Version es sich handelt (und wie gesagt, teilweise ist die Lösung je nach Delphi-Version unterschiedlich).

Ookami 6. Mai 2015 22:06

AW: Verständnisprobleme mit FMX
 
Hallo Harry,

tschuldige, du hast ja recht. Ich hab so viel geschrieben, aber das total übersehen.

Ich arbeite derzeit mit Delphi XE6, möchte aber baldmöglichst zur Version XE8 wechseln.
Für den Moment wäre ich aber für Antworten zur XE6 dankbar.

Harry Stahl 6. Mai 2015 23:20

AW: Verständnisprobleme mit FMX
 
Liste der Anhänge anzeigen (Anzahl: 2)
OK.

TText ist direkt von TControl abgeleitet und hat als Komponente keine (veröffentlichte) Hintergrundeigenschaft, insofern kannst Du da nirgendwo etwas zur Desingn-Time oder Runtime einstellen. Insofern bietet es sich an, hier das Onpaint-Event zu nehmen, dann kannst Du die Komponente selber und abweichend von dem verwendeten Style zeichnen (was Du ja wolltest, wenn ich Dich richtig verstanden habe):

Delphi-Quellcode:
procedure TForm10.Text1Paint(Sender: TObject; Canvas: TCanvas;
  const ARect: TRectF);
begin
  canvas.BeginScene;
  canvas.Fill.Color := TAlphaColorRec.Yellow;
  canvas.FillRect(Arect, 1,1, AllCorners,1);
  canvas.Fill.Color := TAlphaColorRec.Black;
  canvas.FillText (ARect, TText (Sender).Text, True, 1, [], TTextAlign.Center, TTextAlign.Center);
  canvas.EndScene;
end;
Aber bei FireMonkey gilt der Spruch "Viele Wege führen nach Rom" ganz besonders. Hier sind meistens mehrere Varianten an Lösungen möglich.

So könnte man auch das TText-Element in ein TRectangle packen und dann die Hintergrundfarbe des Rectangles zur Laufzeit (bzw. auch vorher schon zur Designzeit) manipulieren:

Delphi-Quellcode:
procedure TForm10.FormCreate(Sender: TObject);
begin
  Rectangle1.Fill.Color := TAlphaColorRec.Lime;
  Rectangle1.Fill.Kind := TBrushKind.solid;
end;
In den anliegenden Screenshots siehst Du zur Designzeit oben nur die TText-Komponente, unten eine TText-Komponente in einem TRectangle. Zur Laufzeit haben beide eine andere Farbe, auf unterschiedlichen Wegen gelöst.

[Edit: Noch ein Hinweis: Wenn man den Rahmen von TRectangle nicht haben will, muss man unter Stroke,Thickness den Wert von 1 auf 0 setzen.]

Harry Stahl 6. Mai 2015 23:33

AW: Verständnisprobleme mit FMX
 
Zitat:

Zitat von Ookami (Beitrag 1300508)
auch das Beispiel mit einer PaintBox war nicht erfolgreich.

Code:
procedure TFontDialogFrame.PaintBox1Paint(Sender: TObject; Canvas: TCanvas);
begin
     with PaintBox1.Canvas do
     begin
          BeginScene();

          Stroke.Kind:= tBrushKind.Solid;
          Fill.Color := MainForm.EvenRowColor;
          FillRect(PaintBox1.BoundsRect, 1,1, AllCorners, 1);

          FontColor := FontColor;
          Font.Family := Fontname;
          Font.Size  := FontSize;
          Font.Style := FontStyle;
         
          FillText(PaintBox1.BoundsRect, fExample, True, 1, [], TTextAlign.Center, TTextAlign.Center);

          EndScene;
     end;    
end;
Hintergrundfarbe ändert sich wie gewünscht. Nur Text, kommt keiner.

Das liegt daran, dass die Farbe noch auf EvenRowColor steht, wenn Du den Text malst. Du musst vorher also wieder die Textfarbe wählen (vor Filltext z.B. mit
Delphi-Quellcode:
Fill.Color := TAlphaColorRec.Black;
und dann funktioniert auch das Beispiel hier.

Ookami 6. Mai 2015 23:46

AW: Verständnisprobleme mit FMX
 
Hallo Harry,

erst mal danke, ich hab's jetzt noch ein bisschen anpassen müssen,

Code:
  canvas.BeginScene;
  canvas.Fill.Color := MainForm.EvenRowColor;
  canvas.FillRect(Arect, 1,1, AllCorners,1);
  Canvas.Font.Family := Fontname; (weil ich doch den Font anpassen muss)
  Canvas.Font.Style := FontStyle;
  Canvas.Font.Size  := FontSize;
  canvas.Fill.Color := FontColor;
  canvas.FillText (ARect, TText (Sender).Text, True, 1, [], TTextAlign.Center, TTextAlign.Center);
  canvas.EndScene;
und was soll ich sagen, es läuft ... zumindest bis ich die Fonteinstellungen wechsle.
dann bin ich wieder soweit wie bisher.
Für den Fall 1 läuft es, für Fall 2-6 nicht. Wieder zurück auf Fall 1 geht wieder.
Bei Fall 1..6 handelt es sich nur um verschiedene Texte, bzw. Font-Einstellungen.
Beispiel Fall 1: Text = 'Hallo Welt', Font=Arial, Size=24, Style=[], ... usw., eigentlich nichts dramatisches.


und gleich nochmal danke, in der Zwischenzeit hast du ja gleich nochmal geantwortet. jep, ein Teil des Fauxpas ist mir aufgefallen.
Der wirklich wichtige (canvas.Fill.Color := Color;) vor jedem Schritt der zeichnet aber nicht. Danke auch hierfür

Harry Stahl 7. Mai 2015 01:06

AW: Verständnisprobleme mit FMX
 
Liste der Anhänge anzeigen (Anzahl: 1)
Also ich habe hier in der Demo mal einen Button eingebaut, der nach Click die Fontfamily (AFName) ändert und dann die Paintbox neu zeichnet. Wird neu gezeichnet und mit dem neuen Font.

Habe das Demo hier mal als Zip angehängt, kannst ja mal vergleichen.

Ookami 7. Mai 2015 13:47

AW: Verständnisprobleme mit FMX
 
Hallo Harry,

ich hab das heute Morgen mal probiert. Da war aber nicht der von dir erwähnte Button drin.
Wenn's nicht zuviel verlangt ist, sei doch so nett und häng das bitte noch mal dran.

Ausgehend von dem was ich hatte und hab selber noch mal getestet. Das Resultat ist aber bei mir dasselbe.

Harry Stahl 7. Mai 2015 17:18

AW: Verständnisprobleme mit FMX
 
Liste der Anhänge anzeigen (Anzahl: 2)
Oh, da hatte ich die letzten Änderungen wohl noch nicht gespeichert.

Hier anliegend jetzt eine Version, wo man Font und Size noch auswählen kann und dann per Klick auf den Button die Änderung ansehen kann. Das funktioniert immer und nicht nur einmal.

Ookami 7. Mai 2015 17:46

AW: Verständnisprobleme mit FMX
 
Hallo Harry,

grüß dich und vielen, vielen Dank.

Ich bin mir noch nicht ganz sicher, bin aber dran es zu verstehen

Code:
  with PaintBox1.Canvas do
    begin
         BeginScene();

         Stroke.Kind:= tBrushKind.Solid;
         Fill.Color := TAlphaColorRec.Yellow;
         FillRect(PaintBox1.BoundsRect, 1,1, AllCorners, 1);

         [Font.Family := ComboBox1.Items[combobox1.ItemIndex];
         Font.Size := SpinBox1.Value;
         Font.Style := fFontStyle;
         Fill.Color := FontColor;

         FillText(PaintBox1.BoundsRect, 'Test', True, 1, [], TTextAlign.Center, TTextAlign.Center);

         EndScene;
    end;
ich denke, mein Fehler war wie folgt:
ich habe nicht immer eine Aktion komplett abgeschlossen sondern am Anfang alles zu einzustellen.
Fill.Color := TAlphaColorRec.Yellow;
FillRect(PaintBox1.BoundsRect, 1,1, AllCorners, 1);

Anhand deines Codes aber sehe ich, dass ich bei (FillRect / FillText / usw... jeweils Werte zuweisen, dann die Aktion ausführen muss.

Ookami 7. Mai 2015 18:44

AW: Verständnisprobleme mit FMX
 
Liste der Anhänge anzeigen (Anzahl: 1)
So sorry, aber das Problem hat sich doch noch nicht gelöst.

Ich habe ein paar Bilder ausgeschnitten, die das Problem zeigen.

Im kleineren linken Bildausschnitt stelle ich die Sprache per Combobox ein. Ein Event wird durch den Button "Landesschrift" ausgelöst. Der wiederum zeigt ein Frame (rechtes Bild, in dem die Einstellung der Sprache zu sehen sein soll. (Einstellung "Deutsch" funktioniert)

Darunter habe ich die erwähnte Combobox auf "Englisch" eingestellt. Ich drücke wieder den Button "Landesschrift". Das Resultat (rechtes Bild) ist das Problem, von dem ich rede, also die omimösen Fälle die ich immer erwähne.

Die ganzen Einstellungen kommen ganz korrekt an, die Darstellung in FillRect ist auch noch korrekt. Lediglich der Beispieltext der oben rechts angezeigt wird, wird eben nicht angezeigt. Beim Debuggen habe ich alle Informationen korrekt vorliegen. Die Anzeige des Textes aber wird verweigert.

Harry Stahl 7. Mai 2015 19:09

AW: Verständnisprobleme mit FMX
 
Es ist natürlich nicht ganz so leicht, ohne den konkreten Source-Code und die Implementation da den Fehler zu finden.

Aber eine wesentliche Information lieferst Du glaube ich erst jetzt, nämlich, dass Du den Code in Frames verwendest, also in mehreren Instanzen.

Da ist es schlecht das so zu machen (bzw. es ist immer schlecht, das so zu machen):
Delphi-Quellcode:
with PaintBox1.Canvas do
  begin
    BeginScene();
Der absolute Bezug auf PaintBox1 kann leicht zur Falle werden.

Daher solltest Du z.B.

Delphi-Quellcode:
with TPaintBox (Sender).Canvas do
  begin
    BeginScene();
verwenden, damit auch auf der richtigen Instanz gemalt wird. Wie gesagt, ob da ein Fehler auftaucht oder nicht, hängt von der konkreten Implementation ab (also z.B. ob die Implementation der Zeichenaktion im Frame erfolgte oder in der Form).

Wenn Dir das nicht hilft, bliebe aus meiner Sicht nur ein isolierter Upload der Form hier in das Forum, so dass man sich das konkret ansehen kann. Sonst spekuliert man hier nur so rum.:wink:

Ookami 7. Mai 2015 19:43

AW: Verständnisprobleme mit FMX
 
Ok, das habe ich so zur Kenntnis genommen, etwas zerknirscht, da sich die Frames bislang eigentlich als sehr gut funktional erwiesen haben.
In meinem Prototypen (auf VCL-Basis) hat das sehr gut funktioniert. Daher verstehe ich das Problem nicht ganz.

Der Frame selbst wird nur einmal instanziiert, also denke ich dass das nicht wirklich das Problem sein sollte.
Ich wollte bewusst nicht mit mehreren Instanzen arbeiten.

Code:
     if FontDialogFrame=NIL then
     begin
          FontDialogFrame := TFontDialogFrame.Create(Self);
         
          FontDialogFrame.Setup;
     end;
     if FontDialogFrame<>NIL then
     begin
          FontDialogFrame.AssignLabels;

          FontDialogFrame.Position.X := LessonMenuFrame.Position.X + LessonMenuFrame.Width + 50;
          FontDialogFrame.Position.Y := LessonMenuFrame.Position.Y + 150;

          FontDialogFrame.onChangeFont := FontChange;
     end;

wenn ich den Button "Landesschrift" (linkes Bild im vorherigen Post) drücke, wird ein Event ausgelöst,

Code:
     MyFont := TMBFontFMX.Create;
     
     MyFont.FontName := MainForm.Vocabulary[cBxLanguages.ItemIndex].LanguagePack.Lang1FontName;
     MyFont.FontSize := StrToInt(MainForm.Vocabulary[cBxLanguages.ItemIndex].LanguagePack.Lang1FontSize);
     MyFont.FontStyle := MBTools.ReturnFontStyle(StrToInt(MainForm.Vocabulary[cBxLanguages.ItemIndex].LanguagePack.Lang1FontStyle));
     MyFont.FontColor := StrToInt64(MainForm.Vocabulary[cBxLanguages.ItemIndex].LanguagePack.Lang1FontColor);
     
     if Assigned(onWantToChangeFont) then onWantToChangeFont(Sender, cBxLanguages.ItemIndex, 1, hlp, MyFont);
     MyFont.Free;
Der wiederum ruft dann den "Dialog" (rechtes Bild)

Code:
Procedure TSettingsFrm.CallChangeFontFrame(Sender: TObject; Language, Track : Integer; Value : String; Font: TMBFontFMX);
begin
     FontDialogFrame.Parent := TC;
     FontDialogFrame.fFontColor := Font.FontColor;
     FontDialogFrame.Fontname := Font.FontName;
     FontDialogFrame.FontSize := Font.FontSize;
     FontDialogFrame.FontStyle := Font.FontStyle;
     FontDialogFrame.Example := Value;
     FontDialogFrame.LanguageNum := Language;
     FontDialogFrame.FontNum := Track;
     
     FontDialogFrame.ShowFrame;
end;
Der wiederum sollte dann eigentlich das ausführen, was wir da vorher gemacht haben.

Code:
procedure TFontDialogFrame.ExamplePanelEvenPaint(Sender: TObject; Canvas: TCanvas);
Var      aRect : TRectF;
begin
     aRect := TPaintBox (Sender).BoundsRect;
     
     with TPaintBox (Sender).Canvas Do
     begin
          BeginScene;
           Fill.Color := MainForm.EvenRowColor;
           FillRect(Arect, 1,1, AllCorners,1);

           Font.Family := Fontname;
           Font.Style := FontStyle;
           Font.Size  := FontSize;
           Fill.Color := FontColor;
           FillText (ARect, fExample, True, 1, [], TTextAlign.Center, TTextAlign.Center);

          EndScene;
     end;
end;
Nachdem die Hintergrundfarben ja stimmen und alle anderen Daten auch korrekt ankommen, wundere ich mich doch, warum keine der Komponenten reagiert.
bzw. die Anzeige reagiert dann, wenn ich das mache - also auskommentiere
Code:
          // Font.Family := Fontname;
          //  Font.Style := FontStyle;
          //  Font.Size  := FontSize;
aber dann zeigt es mir natürlich keinen Font mehr korrekt an.

ansonsten ist das Ergebnis:
Versuch 1: Starte ich neu und stelle gleich "Französisch" ein, kommt nix. Wechsle ich auf "Deutsch" wird es angezeigt.
Versuch 2: Starte ich neu und stelle gleich "Deutsch" ein, wird das angezeigt. Wechsle ich auf "Französisch" wird es nicht angezeigt. wieder zurück auf "Deutsch" - funktioniert.

Harry Stahl 7. Mai 2015 20:16

AW: Verständnisprobleme mit FMX
 
Liste der Anhänge anzeigen (Anzahl: 2)
Also, da Du 2 Frames auf dem Formular hast, hast Du ja auch 2 Instanzen von dem Frame. Da ist dann drauf zu achten, dass da jeweils dir richtigen Variablen der jeweiligen Instanz verwendet werden.

Habe also die PaintBox nun mal in ein Frame gelegt und davon dann 2 auf die Form gelegt. Wie Du im anliegenden Screenshot sehen kannst, werden in beiden Frames unterschiedliche Fontfamilys und Fontgrößen angezeigt.

Anliegend auch das Code-Beispiel.

Ookami 7. Mai 2015 20:32

AW: Verständnisprobleme mit FMX
 
Klar, du hast gewonnen. Natürlich sind des verschiedene Instanzen vom Typ TFrame.

Ich muss das jetzt einfach nochmal genau durchprüfen und das kann dauern.
Werde jetzt an der Stelle erstmal schließen und mich an die Arbeit machen. Vielleicht komme ich über diesen Weg weiter.

By the Way - Bist du zufällig der Buchautor Harry Stahl?

ich bin da vor einigen Tagen bei Amazon auf ein paar Bücher gestoßen, die deinen Namen tragen.

Bis jetzt aber erstmal noch ein großes Danke für deine Geduld und Hilfsbereitschaft.

Harry Stahl 7. Mai 2015 20:43

AW: Verständnisprobleme mit FMX
 
Zitat:

Zitat von Ookami (Beitrag 1300696)
Ich muss das jetzt einfach nochmal genau durchprüfen und das kann dauern.
Werde jetzt an der Stelle erstmal schließen und mich an die Arbeit machen. Vielleicht komme ich über diesen Weg weiter.

Wahrscheinlich ist da irgendwo nur ein kleiner Denkfehler. Vermute eine Variable, die eben doch anderen Inhalt hat, als erwartet.

Zitat:

Zitat von Ookami (Beitrag 1300696)
By the Way - Bist du zufällig der Buchautor Harry Stahl?

ich bin da vor einigen Tagen bei Amazon auf ein paar Bücher gestoßen, die deinen Namen tragen.

Bis jetzt aber erstmal noch ein großes Danke für deine Geduld und Hilfsbereitschaft.

Ja, das bin ich. Helfe gerne, habe aber auch was davon, denn die hier im Forum geschilderten FMX-Probleme können dann z.T. auch Problemlösungen für die Bücher sein.:wink:

Rollo62 10. Mai 2015 09:33

AW: Verständnisprobleme mit FMX
 
Hallo Harry,

würdest du Frames empfehlen ?

Ich habe das vor vielen Jahren mal als super Feature gesehen und eingesetzt (unter VCL), leider gab es aber Probleme an allen Ecken und Kanten.
Z.B. Bei Änderungen konnte einiges verloren gehen, und der ReUse in mehreren Projekten war schwierig.

Seitdem habe ich es liegen gelassen.

Ich bin mittlerweile auf dem Standpunkt das nicht alles RAD sein muss, und das man viele Funktionen besser in übersichtlichen, lesbaren Funktionen auslagert.

ZB. Habe ich statt der Frames direkt Forms jeweils einmalig
in Container geladen, ungefähr so:
Code:
LoadFormInContainer(FormNeu1, PanelTgt);
        LoadFormInContainer(FormNeu2, TabSheetTgt);
        etc.
Das funktionierte sehr gut unter VCL, und man behält die Übersicht und Kontrolle wenn die IDE mal abstürzt und nicht alles korrekt speichert.
Ich vermute mal das es unter Fmx ähnliches Verhalten geben sollte, habe es aber noch nicht ausprobiert.

Rollo

Harry Stahl 10. Mai 2015 12:49

AW: Verständnisprobleme mit FMX
 
Das Einbinden von Forms in andere Forms / Container funktioniert ohne Probleme in FMX. Wenn die Programmlogik nicht unbedingt für Frames spricht, würde ich immer eine Form vorziehen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:55 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