StringGrid1->Canvas->Font->Style speichern



  • Hallo,
    ich möchte "StringGrid1->Canvas->Font->Style" speichern, wieder laden und zuweisen können.

    z.Bsp.den Wert für fsBold usw. ...
    StringGrid1->Canvas->Font->Style=TFontStyles()<< 0;
    oder
    StringGrid1->Canvas->Font->Style=0;
    geht nicht.

    Gruß Egbert



  • Hallo

    nicht schön, aber es funktioniert :

    StringGrid1->Canvas->Font->Style=TFontStyles()<< TFontStyle(0);
    

    bis bald
    akari



  • Hallo akari,
    wie komme ich an den Wert für fsBold ... usw. Da muß doch ein Wert vom Type Byte zurückkommen, den ich z.Bsp in einer Ini oder einem String speichern kann, um ihn wieder auszulesen.

    Egbert...



  • Hallo

    meinst du das?

    TFontStyle FontStyle = fsBold;
    int Test = int(FontStyle);
    

    bis bald
    akari



  • Ja, da kommen wir der Sache schon näher. Habe bisher mit Delphi programmiert und da war das überhaupt kein Problem TFont zu speichern. Mit

    TFontStyles(byte(StrToInt(s)));

    konnte ich den zuvor gespeicherten

    IntToStr(Byte(StringGrid1.Font.Style));

    Wert wieder zuweisen.

    Genau das, möchte ich hier auch machen.
    Gruß Egbert



  • Hallo

    soetwas geht im Builder leider nicht.
    Es gibt da die << und >> Operatoren, die den Wert als Bitfeld in Strinformat an einen Stream weitergeben.
    Oder du schreibst dir eben selber die Konvertierroutine in eine Integer-Zahl. Dazu gehst eben alle möglichen Werte von TFontStyle durch und überprüfst per Contains(), ob die in dem TFontStyles vorhanden sind, wenn ja, führst du eine XOR-Operation zwischen (2 hoch Wert) und dem Rückgabewert durch, um das Bit zu setzen.

    bis bald
    akari



  • Hallo, jedenfalls vielen Dank für deine Hilfe und Hinweise. Dachte nicht, daß das Speichern von Style in BCB so schwierig ist. OK, werde mir deinen Vorschlag durch den Kopf gehen lassen. Irgendwie versuche ich es jedenfalls hinzubekommen. Wenn erforderlich, werde ich mich nochmal melden.
    Gruß Egbert...



  • Hallo

    da mich das auch interessiert, habe ich das mal umgesetzt :

    #include <math.h>
    
    // Umwandlung beliebiges Set in Integer
    // Eingabewerte :
    //   SetType Set - das umzuwandelnde Set
    //   EnumType MaxValue - der höchste Wert des Enums, auf dem das Set aufbaut
    template <typename SetType, typename EnumType>
    int SetToInt(SetType Set, EnumType MaxValue)
    {
      int Result = 0;                         // Rückgabewert
    
      // Jede einzelne Option abfragen und wenn vorhanden, in Ergebnis eintragen
      for (int Lv = 0; Lv <= MaxValue; Lv++)
      {
        if (Set.Contains(EnumType(Lv))) Result = Result ^ int(pow(2,Lv));
        }
      return(Result);
      }
    
    // Umwandlung Integer in beliebiges Set
    template <typename SetType, typename EnumType>
    SetType IntToSet(int Integer, EnumType MaxValue)
    {
      SetType Result = SetType();             // Rückgabewert
      int Buffer;                             // Zwischenspeicher
    
      // Jede 2-Potenz vom höchsten Wert angefangen bis 0 abfragen und
      // wenn vorhanden, in Ergebnis aktivieren
      for (int Lv = MaxValue; Lv >= 0; Lv--)
      {
        Buffer = int(pow(2,Lv));
        if (Integer >= Buffer)
        {
          Integer -= Buffer;
          Result << EnumType(Lv);
          }
        }
      return(Result);
      }
    

    Jetzt kannst du die Templates so verwenden :

    TFontStyles FontStyles;
      int Value;
    
      FontStyles << fsBold << fsUnderline;
      Value = SetToInt(FontStyles, fsStrikeOut);
      FontStyles.Clear();
      FontStyles = IntToSet<TFontStyles, TFontStyle>(Value, fsStrikeOut);
    

    bis bald
    akari



  • Hallo akari,
    das finde ich ja super, dass du dich meine Probleme annimmst. Versuche zunächst, deinen Source genau zu verstehen. Wie kann ich jetzt Style meiner StringGrid->Canvas->Font ausgeben lassen. Etwa so?

    FontStyles << StringGrid->Canvas->Font->Style;
    Value = SetToInt(FontStyles, fsStrikeOut);

    Möchte StringGrid1->Canvas->Font folgendermaßen speichern.

    [cpp][code]
    void __fastcall TForm1::SpaltenSchrift1Click(TObject *Sender)
    {
    int ACol=StringGrid1->Col;
    if (FontDialog1->Execute())
    {
    String S = "<0>"+FontDialog1->Font->Name;
    S += "<1>"+IntToStr(FontDialog1->Font->Size);
    S += "<2>"+IntToStr(FontDialog1->Font->Color);
    S += "<3>“+... hier soll Style gespeichert werden ...+”<4>";
    StringGrid1->Cells[ACol][2]=S; // speichern im Haeder der betreffenden Spalte
    StringGrid1->Refresh();
    }
    }
    //---------------------------------------------------------------------------

    Was meinst du dazu?

    Gruß Egbert

    PS
    Irgendwie kriege ich das mit der Code-Eingabe hier nicht hin. Was mache ich falsch?



  • Hallo

    Um die Funktionen zu verstehen, mußt du dich mit Templates beschäftigen (Set ist übrigens auch ein Template).
    Im Grunde geht es darum, gleiche Methoden für ähnliche Typen zu schreiben, ohne für jeden Typ eine eigene Funktion schreiben zu müßen.

    S += "<3>"+IntToStr(SetToInt(FontDialog1->Font->FontStyle))+"<4>";
    

    Wenn du dann das wieder einlesen willst, schreibst du

    TFont *Font;
    int Value;
    ...
    // Integer-Wert zwischen <3> und <4> auslesen und in Value schreiben
    // danach Integer in TFontStyles umwandeln
    Font->Styles = IntToSet<TFontStyles,TFontStyle>(Value,fsStrikeOut);
    

    bis bald
    akari



  • Hallo akari,
    jetzt komme ich allmählich dahinter. Nimm es mir aber bitte nicht übel, wenn ich dich mit meiner Unerfahrenheit belästige. Nur so kann ich es ja lernen!!!.
    Werde deine Routinen einbinden und letzteres nachvollziehen. Ebenfalls werde ich mich mit Templates beschäftigen, um das Ganze einfach besser zu verstehen. Jetzt mache ich aber erst mal Schluss hier und lege den Hebel um.
    Hab vielen Dank. Ohne deine Hilfe hätte ich es jedenfalls nicht hinbekommen.
    Gruß Egbert





  • Hallo

    Für TFontStyles ist das ja eine Lösung. Aber leider kann man das nicht in ein Template bringen, was an der globalen Variable liegt. Wo liegt denn der Unterschied zwischen dem

    // Konvertierung funktioniert, ist aber durch globale Variable sinnlos, denn
    // nur für TFontStyles nutzbar
    TFontStyles style_dummy;
    template <typename SetType>
    int SetToInt(SetType Set)
    {
      style_dummy = Set;
      long &ref = (long &) style_dummy;
      return(ref);
      }
    

    und dem

    // Konvertierung funktioniert nicht, Rückgabewert ist ein wilder Wert // (Speicheradresse?)
    template <typename SetType>
    int SetToInt(SetType Set)
    {
      SetType dummy = Set;
      long &ref = (long &) dummy;
      return(ref);
      }
    

    Meine Lösung ist zwar umständlich (muß noch optimiert werden) aber zumindestens
    ist sie für alle Sets anwendbar.

    /Edit : was ist das long &ref eigentlich? soetwas habe ich noch nie gesehen. (In so einen Zusammenhang. Ansonsten ist es ja eine Referenz.)

    bis bald
    akari



  • Hallo akari,
    komme nochmal auf mein Problem zurück. Habe deine Routinen eingebaut. Außer fsBold, wird kein Wert zurückgegeben.
    Beim compilieren der Unit wird die Warnung:
    W8006 const TFontStyle wird mit int initialisiert
    ausgegeben. Kann eigentlich nicht verstehen, dass es so schwierig ist, die Werte für Style zu bekommen.
    Inzwischen habe ich mir folgende, umständliche Möglichkeit ausgedacht, die einwandfrei funktioniert.

    Byte StyleToByte(TFont *FST)
    {
      Byte re=255;
    
      if (FST->Style == (TFontStyles() << fsBold << fsItalic << fsUnderline)) re=9; else
      if (FST->Style == (TFontStyles() << fsBold << fsItalic << fsStrikeOut)) re=10; else
    
      if (FST->Style == (TFontStyles() << fsBold << fsItalic)) re=4; else
      if (FST->Style == (TFontStyles() << fsBold << fsUnderline)) re=5; else
      if (FST->Style == (TFontStyles() << fsBold << fsStrikeOut)) re=6; else
    
      if (FST->Style == (TFontStyles() << fsItalic << fsUnderline)) re=7; else
      if (FST->Style == (TFontStyles() << fsItalic << fsStrikeOut)) re=8; else
    
      if (FST->Style == (TFontStyles() << fsBold)) re=0; else
      if (FST->Style == (TFontStyles() << fsItalic)) re=1; else
      if (FST->Style == (TFontStyles() << fsUnderline)) re=2; else
      if (FST->Style == (TFontStyles() << fsStrikeOut)) re=3;
      return re;
    }
    
    TFontStyles ByteToStyle(Byte FST)
    {
      if (FST == 0) return (TFontStyles() << fsBold); else
      if (FST == 1) return (TFontStyles() << fsItalic); else
      if (FST == 2) return (TFontStyles() << fsUnderline); else
      if (FST == 3) return (TFontStyles() << fsStrikeOut); else
      if (FST == 4) return (TFontStyles() << fsBold << fsItalic); else
      if (FST == 5) return (TFontStyles() << fsBold << fsUnderline); else
      if (FST == 6) return (TFontStyles() << fsBold << fsStrikeOut); else
      if (FST == 7) return (TFontStyles() << fsItalic << fsUnderline); else
      if (FST == 8) return (TFontStyles() << fsItalic << fsStrikeOut); else
      if (FST == 9) return (TFontStyles()  << fsBold << fsItalic << fsUnderline); else
      if (FST == 10) return (TFontStyles() << fsBold << fsItalic << fsStrikeOut); else
      TFontStyles();
      return TFontStyles();
    }
    

    Gruß Egbert



  • Hallo

    Habe deine Routinen eingebaut. Außer fsBold, wird kein Wert zurückgegeben.
    Beim compilieren der Unit wird die Warnung:
    W8006 const TFontStyle wird mit int initialisiert
    ausgegeben.

    Dieser Fehler kommt bei mir nur, wenn ich bei

    Value = SetToInt(FontStyles, fsStrikeOut);
    

    statt dem fsStrikeOut eine Zahl wie 4 übergebe

    Kann eigentlich nicht verstehen, dass es so schwierig ist, die Werte für Style zu bekommen.
    Inzwischen habe ich mir folgende, umständliche Möglichkeit ausgedacht, die einwandfrei funktioniert.

    Schau dir noch mal den Link von Jansen an, da werden für TFontStyles bereits vorgefertigte Funktionen dargestellt (Den Link zu den Newsgroups folgen).
    Das ist auf jeden Fall besser als deine Variante (Zumal die nicht vollständig ist).

    bis bald
    akari



  • Hallo,
    ja ok, das ist ja auch nur aus Verzweifelung entstanden.
    Auf dem Link von Jansen war ich schon, habe aber nichts Konkretes gefunden. Werde da trotzdem noch mal nachschauen.
    Gruß Egbert…



  • Hallo

    Bin auf dem Link pfundig geworden und jetzt klappt alles, wie gewünscht. Manchmal sieht man den Wald vor lauter Bäumen nicht.
    Hier nun, wie ich es gemacht habe.

    TFontStyles style_dummy;
    
      ... 
        try
        {
          long &style_ref = (long &)style_dummy;
          style_ref = 0;
    
          p4=S.Pos("<4>");
          style_ref = S.SubString(p3+3,p4-p3-3).ToInt();
          StringGrid1->Canvas->Font->Style=style_dummy;
        }
        catch(...)
        {
          StringGrid1->Canvas->Font->Style=TFontStyles();
        }
      ...
    

    Möchte mich auf diesem Wege noch mal für die Hilfe und Hinweise herzlich bedanken.
    Gruß Egbert…



  • Hallo

    hab nochmal meine Templates überarbeitet

    // Umwandlung beliebiges Set in Integer
    // Eingabewerte :
    //   SetType Source - das umzuwandelnde Set
    template <class Enum, unsigned char MinElem, unsigned char MaxElem>
    int SetToInt(const Set<Enum, MinElem, MaxElem> & Source)
    {
      int Result = 0;                         // Rückgabewert
      int CurrPower = int(pow(2, MinElem));
    
      // Jede einzelne Option abfragen und wenn vorhanden, in Ergebnis eintragen
      for (int Lv = MinElem; Lv <= MaxElem; Lv++)
      {
        if (Source.Contains(Enum(Lv))) Result = Result ^ CurrPower;
        CurrPower *=2;
        }
      return(Result);
      }
    
    // Umwandlung Integer in beliebiges Set
    // Eingabewerte :
    //   int Integer - die umzuwandelnde Zahl
    //   SetType Dest - Set, das vom selbem Typ ist wie das Ziel-Set (wird nicht verändert)
    template <class Enum, unsigned char MinElem, unsigned char MaxElem>
    Set<Enum, MinElem, MaxElem> IntToSet(int Integer, const Set<Enum, MinElem, MaxElem> & Dest)
    {
      Set<Enum, MinElem, MaxElem> Result = Set<Enum, MinElem, MaxElem>(); // Rückgabewert
      int Buffer = int(pow(2,MaxElem));       // Zwischenspeicher
    
      // Jede 2-Potenz vom höchsten Wert angefangen bis 0 abfragen und
      // wenn vorhanden, in Ergebnis aktivieren
      for (int Lv = MaxElem; Lv >= MinElem; Lv--)
      {
        if (Integer >= Buffer)
        {
          Integer -= Buffer;
          Result << Enum(Lv);
          }
        Buffer /= 2;
        }
      return(Result);
      }
    

    Verwendung mit (hier mit TFontStyles, funktioniert aber auch mit allen anderen Sets)

    TFontStyles FontStyles;
      int Value;
    
      FontStyles << fsBold << fsUnderline;
      Value = SetToInt(FontStyles);
      FontStyles.Clear();
      FontStyles = IntToSet(Value, FontStyles); // Das FontStyles als Parameter wird nicht veränder!
    

    bis bald
    akari



  • Hallo

    ja, jetzt laufen deine Templates ufb !!!

    Gruß Egbert


Anmelden zum Antworten