Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.10.22;
Скачать: CL | DM;

Вниз

сохранить шрифт memo в ini файле   Найти похожие ветки 

 
anton773 ©   (2006-09-30 21:14) [0]

здравствуйте как сохранить параметры шрифта memo в ini файле


 
Anatoly Podgoretsky ©   (2006-09-30 21:25) [1]

Какие именно?


 
Джо ©   (2006-09-30 21:26) [2]

> здравствуйте как сохранить параметры шрифта memo в ini файле

Да, в общем, так же, как и параметры чего-нибудь другого.


 
anton773 ©   (2006-09-30 21:41) [3]


> Какие именно?

все
> Да, в общем, так же, как и параметры чего-нибудь другого

как сохранить строковое свойство понятно: Ini.writeString() числовое значение:Ini.writeinteger() , а вот запись типа Ini.writeFont не прокатит...


 
Джо ©   (2006-09-30 21:43) [4]

> [3] anton773 ©   (30.09.06 21:41)

К каким именно свойством затруднение?


 
Desdechado ©   (2006-09-30 21:43) [5]

Сохраняй нужные тебе свойства фонта (имя, размеры, зачеркивания/курсив/подчеркивания, цвет)


 
Kolan ©   (2006-09-30 21:44) [6]


> anton773 ©   (30.09.06 21:41) [3]
>
>

Так не выйдет. Придется сохронять отдельно все параметры шрифта.

Хотя может можно используя Fake свойства и сериализацию...

http://www.rsdn.ru/article/delphi/serialization.xml


 
anton773 ©   (2006-09-30 22:02) [7]


> К каким именно свойством затруднение?

чесно говоря лень сохранять каждое свойство по отдельности ;-) хочется все сразу. В ин-нете нашел способ : затолкать все свойства в строку ,а потом сохранить её методом WriteString , затем при чтении INI файла разобрать ее на запчасти. Нудно все это :-)


 
Desdechado ©   (2006-09-30 22:05) [8]

> затолкать все свойства в строку
это имхо перректально, для особенных извращенцев


 
anton773 ©   (2006-09-30 22:10) [9]


> это имхо перректально, для особенных извращенцев

Согласен. Поэтому я и обратился на форум для более изящных решений


 
Anatoly Podgoretsky ©   (2006-09-30 22:16) [10]

Все, зачем сохранять - Handle, PixelsPerInch
Не могу понять.


 
Kolan ©   (2006-09-30 22:18) [11]


> Все, зачем сохранять - Handle, PixelsPerInch
> Не могу понять.


Автору: Ну сохрани нужные их там штук 5...


 
anton773 ©   (2006-09-30 22:21) [12]


> Автору: Ну сохрани нужные их там штук 5...

если других вариантов нет - так и поступлю


 
Kolan ©   (2006-09-30 22:25) [13]

Да за это время ужо бы написал процедурку. Вот те интерфейс:
procedure SaveFontToIniFile(FileName: string; Font: TFont);
или
procedure SaveFontToIniFile(IniFile: TIniFile; Font: TFont);
но видимо первое поудобнее :)


 
Loginov Dmitry ©   (2006-09-30 22:43) [14]

anton773 ©   (30.09.06 21:14)
как сохранить параметры шрифта memo в ini файле


Например так:

function FontToString(AFont: TFont): string;
begin
 Result := Format("%s,%d,%d,%d", [AFont.Name, AFont.Size,
   Byte(AFont.Style), AFont.Color]);
end;


 
Loginov Dmitry ©   (2006-09-30 22:44) [15]

и не забыть SaveFontToIniFile

:)


 
Джо ©   (2006-09-30 22:52) [16]

> [9] anton773 ©   (30.09.06 22:10)
>
> > это имхо перректально, для особенных извращенцев
>
> Согласен. Поэтому я и обратился на форум для более изящных
> решений

Вот изящно :)


uses TypInfo;

type
 TPropInfo = record
   Name: string;
   Kind: TTypeKind;
 end;

 TPropInfoArray = array of TPropInfo;

function GetPropertyNames (AClass: TClass): TPropInfoArray;
var
 I,Cnt: Integer;
 Pti: PTypeInfo;
 PPropLst: PPropList;
begin
 Pti := PTypeInfo(AClass.ClassInfo);

 GetMem (PPropLst,High(TPropList));
 try
   Cnt := GetPropList(
     Pti,
     [tkInteger, tkChar, tkEnumeration, tkFloat,
     tkString, tkSet, tkClass, tkMethod, tkWChar, tkLString, tkWString,
     tkVariant, tkArray, tkRecord, tkInterface, tkInt64, tkDynArray],
     PPropLst
   );

   SetLength(Result,Cnt);

   for I := 0 to Cnt-1 do
   begin
     Result[I].Name := PPropLst^[I].Name;
     Result[I].Kind := PPropLst^[I].PropType^.Kind;
   end;

 finally
   FreeMem (PPropLst);
 end;
end;

procedure SavePublishedProperties (Obj: TObject; FileName, Section: string);
var
 I: Integer;
 Ini: TIniFile;
 Props: TPropInfoArray;
begin
 Props := GetPropertyNames(Obj.ClassType);

 Ini := TIniFile.Create(FileName);
 try
   for I := 0 to High(Props) do
   begin
     case Props[I].Kind of
       tkInteger:
         begin
           Ini.WriteInteger(Section,Props[I].Name,GetOrdProp(Obj,Props[I].Name));
         end;
       tkString,tkLString:
         begin
           Ini.WriteString(Section,Props[I].Name,GetStrProp(Obj,Props[I].Name));
         end;
       else
         begin
           //raise Exception.Create("Unsupported property type");
         end;
     end;
   end;
 finally
   Ini.Free;
 end;
end;



Пример использования:


procedure TForm1.Button1Click(Sender: TObject);
var
 Fnt: TFont;
begin
 Fnt := TFont.Create;
 try
   SavePublishedProperties(Fnt,"d:\font.ini","Font");
 finally
   Fnt.Free;
 end;
end;


Код, возможно, местами некорректен и, во всяком случае, неполон. Запись остальных типов свойств предоставляю в качестве ДЗ. Равно как и имплементацию SavePublishedProperties.
:)


 
Джо ©   (2006-09-30 22:54) [17]

> [16]

Подходит, естественно, не только для TFont.


 
Джо ©   (2006-09-30 22:55) [18]

> Равно как и имплементацию SavePublishedProperties.

Что ж за день такой?! Имел в виду: LoadPublishedProperties.


 
RASkov   (2006-10-01 01:05) [19]

> anton773


Чуть и я добавлю....

uses ..., IniFiles;
.....
const
  FONTB: set of Byte=[2, 6, 10, 14];
  FONTI: set of Byte=[4, 6, 12, 14];
  FONTU: set of Byte=[8, 10, 12, 14];
......

implementation

{$R *.dfm}

function GetFontStyle(const N: Integer): TFontStyles;
begin
 Result:=[];
 if N in FONTB then Result:=Result+[fsBold];
 if N in FONTI then Result:=Result+[fsItalic];
 if N in FONTU then Result:=Result+[fsUnderline];
end;

function FontStyleToInt(const Fn: TFontStyles): Integer;
begin
 Result:=0;
 if fsBold in Fn then Result:=Result+2;
 if fsItalic in Fn then Result:=Result+4;
 if fsUnderLine in Fn then Result:=Result+8;
end;

procedure GetFontFromIni(const FlIni: String; Fnt: TFont);
var FIni: TIniFile;
begin
 FIni:= TIniFile.Create(FlIni);
 Fnt.Name :=FIni.ReadString("FONTDATA", "FName", "Courier New Cyr");
 Fnt.Color:=TColor(FIni.ReadInteger("FONTDATA", "FColor", clBlack));
 Fnt.Pitch:=TFontPitch(FIni.ReadInteger("FONTDATA", "FPitch", 0));
 Fnt.Size :=FIni.ReadInteger("FONTDATA", "FSize", 8);
 Fnt.Style:=GetFontStyle(FIni.ReadInteger("FONTDATA", "FStyle", 0));
 FIni.Free;
end;

procedure SetFontToIni(const FlIni: String; Fnt: TFont);
var FIni: TIniFile;
begin
 FIni:= TIniFile.Create(FlIni);
 FIni.WriteString ("FONTDATA", "FName", Fnt.Name);
 FIni.WriteInteger("FONTDATA", "FColor", Fnt.Color);
 FIni.WriteInteger("FONTDATA", "FPitch", ORD(Fnt.Pitch));
 FIni.WriteInteger("FONTDATA", "FSize", Fnt.Size);
 FIni.WriteInteger("FONTDATA", "FStyle", FontStyleToInt(Fnt.Style));
 FIni.Free;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 GetFontFromIni(ExtractFilePath(ParamStr(0))+"memo.ini", Memo1.Font);
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
 SetFontToIni(ExtractFilePath(ParamStr(0))+"memo.ini", Memo1.Font);
end;


 
Джо ©   (2006-10-01 01:14) [20]

> [19] RASkov   (01.10.06 01:05)

Простите, но это ужас! :)
Вот, например — зачем нужна функция FontStyleToInt? Всю ее можно свести к одной простой строке: N := Byte(Font.Style).


 
RASkov   (2006-10-01 01:22) [21]

> [20] Джо ©   (01.10.06 01:14)

Блин, точно

> Что ж за день такой?!


 
RASkov   (2006-10-01 01:41) [22]

В процедуре SetFontToIni
procedure SetFontToIni(const FlIni: String; Fnt: TFont);
...
//исправить на
FIni.WriteInteger("FONTDATA", "FStyle", Byte(Fnt.Style));
...
end;


ну и выделить всю FontStyleToInt и нажать Del :)
затем переписать константы :)

> [21] RASkov   (01.10.06 01:22)

Да... но только теперь нужно константы переделать и...
(забыл в первый раз:) добавить FONTS (зачеркнутый)

> [20] Джо ©   (01.10.06 01:14)

А нельзя ли как-то и от GetFontStyle избавится? ну или тоже к одной строчке привести...?


 
Джо ©   (2006-10-01 01:44) [23]

> [22] RASkov   (01.10.06 01:41)
> А нельзя ли как-то и от GetFontStyle избавится? ну или тоже
> к одной строчке привести...?

var
 N: Byte;
begin
 Font.Style := TFontStyles(N);
end;


 
Джо ©   (2006-10-01 01:46) [24]

Но я бы все-равно рекоммендовал [16], как пример гораздо более универсального подхода :)


 
RASkov   (2006-10-01 01:51) [25]

> [24] Джо ©   (01.10.06 01:46)

Согласен на 150%


> [23] Джо ©   (01.10.06 01:44)

[Error] Unit1.pas(96): Invalid typecast


 
RASkov   (2006-10-01 01:59) [26]

> [23] Джо ©   (01.10.06 01:44)

Извеняюсь за

> [Error] Unit1.pas(96): Invalid typecast

У меня Integer был :)
Джо, Спасибо.


 
RASkov   (2006-10-01 02:12) [27]

С помощью Джо вот что осталось:

uses ..., IniFiles;
.....
procedure GetFontFromIni(const FlIni: String; Fnt: TFont);
var FIni: TIniFile;
begin
 FIni:= TIniFile.Create(FlIni);
 Fnt.Name:=FIni.ReadString("FONTDATA", "FName", "Courier New Cyr");
 Fnt.Color:=TColor(FIni.ReadInteger("FONTDATA", "FColor", clBlack));
 Fnt.Pitch:=TFontPitch(FIni.ReadInteger("FONTDATA", "FPitch", 0));
 Fnt.Size:=FIni.ReadInteger("FONTDATA", "FSize", 8);
 Fnt.Style:=TFontStyles(Byte(FIni.ReadInteger("FONTDATA", "FStyle", 0)));
 FIni.Free;
end;

procedure SetFontToIni(const FlIni: String; Fnt: TFont);
var FIni: TIniFile;
begin
 FIni:= TIniFile.Create(FlIni);
 FIni.WriteString("FONTDATA", "FName", Fnt.Name);
 FIni.WriteInteger("FONTDATA", "FColor", Fnt.Color);
 FIni.WriteInteger("FONTDATA", "FPitch", ORD(Fnt.Pitch));
 FIni.WriteInteger("FONTDATA", "FSize", Fnt.Size);
 FIni.WriteInteger("FONTDATA", "FStyle", Byte(Fnt.Style));
 FIni.Free;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 GetFontFromIni(ExtractFileDir(ParamStr(0))+"\memo.ini", Memo1.Font);
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
 SetFontToIni(ExtractFileDir(ParamStr(0))+"\memo.ini", Memo1.Font);
end;


[19] - было тренировкой:)
ЗЫ я не настаиваю на своём решении, просто испровляю ошибки...
ЗЫЫ > anton773 технология [16] усе равно гибче, тем самым лучше. ИМХО.


 
RASkov   (2006-10-01 02:15) [28]

надоже написать "просто испровляю ошибки" - и тут же с ошибкой;)
Вот правильно:
"я не настаиваю на своём решении, просто исправляю ошибки"
Усё... пора спать.


 
Юрий Зотов ©   (2006-10-01 02:35) [29]

ObjectBinaryToText
ObjectTextToBinary

И всех дел.
:o)


 
Джо ©   (2006-10-01 02:40) [30]

> [29] Юрий Зотов ©   (01.10.06 02:35)
> ObjectBinaryToText
> ObjectTextToBinary
>
> И всех дел.

У TFont нету WriteToStream, равно как и не выйдет TStream.WriteComponent, по очевидным причинам.


 
Джо ©   (2006-10-01 03:39) [31]

Не корысти ради, а во благо, выкладываю плод бессоницы :о)


uses ..., IniFiles;

type
 TExtendedIniFile = class (TIniFile)
 public
   procedure WriteObject (AObject: TObject; const Section: string);
   procedure ReadObject (AObject: TObject; const Section: string);
 end;

implementation

uses ..., TypInfo;

type
 TPropInfo = record
   Name: string;
   Kind: TTypeKind;
 end;

 TPropInfoArray = array of TPropInfo;

function GetPropertyNames (AClass: TClass): TPropInfoArray;
var
 I,Cnt: Integer;
 Pti: PTypeInfo;
 PPropLst: PPropList;
begin
 Pti := PTypeInfo(AClass.ClassInfo);

 GetMem (PPropLst,High(TPropList));
 try
   Cnt := GetPropList(
     Pti,
     [tkInteger, tkChar, tkEnumeration, tkFloat, tkString,
     tkSet, tkWChar, tkLString, tkWString,tkInt64],
     PPropLst
   );

   SetLength(Result,Cnt);

   for I := 0 to Cnt-1 do
   begin
     Result[I].Name := PPropLst^[I].Name;
     Result[I].Kind := PPropLst^[I].PropType^.Kind;
   end;

 finally
   FreeMem (PPropLst);
 end;

end;

{ TExtendedIniFile }

procedure TExtendedIniFile.ReadObject(AObject: TObject; const Section: string);
var
 I: Integer;
 Props: TPropInfoArray;
 V: Variant;
begin
 Props := GetPropertyNames(AObject.ClassType);
 for I := 0 to High(Props) do
 begin
   case Props[I].Kind of
     tkInteger,tkInt64:
       SetOrdProp(AObject,Props[I].Name,ReadInteger(Section,Props[I].Name,0));

     tkString,tkLString,tkWString,tkChar,tkWChar:
       SetStrProp(AObject,Props[I].Name,ReadString(Section,Props[I].Name,""));

     tkFloat:
       SetFloatProp(AObject,Props[I].Name,ReadFloat(Section,Props[I].Name,0));

     tkEnumeration:
       SetEnumProp(AObject,Props[I].Name,ReadString(Section,Props[I].Name,""));

     tkSet:
       SetSetProp(
         AObject,
         Props[I].Name,
         ReadString (Section,Props[I].Name,"")
       );
   end;
 end;
end;

procedure TExtendedIniFile.WriteObject(AObject: TObject; const Section: string);
var
 I: Integer;
 Props: TPropInfoArray;
 V: Variant;
begin
 Props := GetPropertyNames(AObject.ClassType);

 for I := 0 to High(Props) do
 begin
   V := GetPropValue(AObject,Props[I].Name);

   case Props[I].Kind of
     tkInteger,tkInt64:
       WriteInteger (Section,Props[I].Name,V);

     tkString,tkLString,tkWString,tkChar,tkWChar:
       WriteString (Section,Props[I].Name,V);

     tkFloat:
       WriteFloat (Section,Props[I].Name,V);

     tkEnumeration:
         WriteString (Section,Props[I].Name,
           GetEnumProp(AObject,Props[I].Name));
     tkSet:
       begin
         WriteString(
           Section,
           Props[I].Name,
           GetSetProp(AObject,Props[I].Name,True)
         );
       end;
     else
       begin
         // Этого не должно случиться
         // ибо в GetPropertyNames мы фильтруем
         // только нужные нам типы свойств
         Assert (False,"Unsupported property type");
       end;
   end;

 end;
end;

end.


Пример:


procedure TForm1.Button1Click(Sender: TObject);
var
 Ini: TExtendedIniFile;
begin
 Ini := TExtendedIniFile.Create("d:\form.ini");
 try
   // Сохраняем, что угодно
   Ini.WriteObject(Self,"Form");
   Ini.WriteObject(Font,"Font");

   // Читаем, что угодно
   Ini.ReadObject(Font,"Font");
   Ini.ReadObject(Self,"Form");
 finally
   Ini.Free;
 end;
end;


---
ToDo:
1. Сделать рекурсивные чтение/запись "вложенных" классов, т.е., включить в "фильтр" в функции GetPropertyNames тип tkClass и обрабатывать его в соответствующих методах записи/чтения рекурсивно.
2. Устранить (возможную) утечку памяти в GetPropertyNames — чую, что она там должна быть, но уже лень проверять :0)


 
anton773 ©   (2006-10-01 04:13) [32]

всем спасибо. разобрался!


 
Карелин Артем ©   (2006-10-02 09:18) [33]

По-моему приведение шрифта без стиля к байту и обратное преобразование байта 0 в стиль даст [fsBold]. Попраьте меня если что, ибо год уже не пишу на дельфи.


 
Loginov Dmitry ©   (2006-10-02 10:04) [34]

> Карелин Артем ©   (02.10.06 09:18)


А вот и нет! Стилю fsBold соответстует установленный младший бит.



Страницы: 1 вся ветка

Текущий архив: 2006.10.22;
Скачать: CL | DM;

Наверх




Память: 0.56 MB
Время: 0.03 c
2-1159981434
Merry
2006-10-04 21:03
2006.10.22
Invalid pointer operation.


1-1158177480
RagapuK
2006-09-13 23:58
2006.10.22
Как подсоединиться и интернету с помощью Delphi&


2-1159765679
Officeman
2006-10-02 09:07
2006.10.22
требуется програмно закрыть окно, имя окна хранится в переменной


15-1159615411
Furyz
2006-09-30 15:23
2006.10.22
Windows Script


2-1159945999
Roma L
2006-10-04 11:13
2006.10.22
TreeView