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
-
Suchfunktion benutzen! Z.B.
http://www.c-plusplus.net/forum/viewtopic.php?t=78972&highlight=font+style+speichern
-
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