Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Проблема с сохранением объектов, в файл и наоборот 
:(
    Опции темы
Teran
  Дата 19.9.2006, 16:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 590
Регистрация: 9.9.2005
Где: Украина, Запорожь е

Репутация: нет
Всего: 3



Есть класс который в последствии должен сохранятся в файл
Код

class TClassTmp : public TPersistent
   {
   private:
      int FProp;
      TList *ListOb;
      TBitBtn *Buto;

   public:
      __fastcall TClassTmp();
      __fastcall ~TClassTmp();

   __published:

      __property int Prop = {read = FProp, write = FProp};
      __property TList *List = {read = ListOb, write = ListOb};
      __property TBitBtn *Buton = {read = Buto, write = Buto};
   };

вот код создания ну и сохранения и загрузки этого класса
Код

TfrmMain *frmMain;
TClassTmp *ClassTmp;
//---------------------------------------------------------------------------
__fastcall TClassTmp::TClassTmp()
{
 List=new TList;
 Buton=new TBitBtn(this);
}
__fastcall TClassTmp::~TClassTmp()
{
 delete List;
 delete Buton;
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::Button1Click(TObject *Sender)  //Сохранение в файл
{ ClassTmp=new TClassTmp();
  ClassTmp->Buton->Caption="Boxa";
  ClassTmp->List->Add(ClassTmp->Buton);
  ClassTmp->Prop=5;
  SaveObjToFile(ClassTmp,"c:\\1.txt");
  ShowMessage(IntToStr(ClassTmp->Prop)+"  "+IntToStr(ClassTmp->List->Count)+"  "+((TBitBtn*)ClassTmp->List->Items[0])->Caption);
  delete ClassTmp;
}
void __fastcall TfrmMain::Button2Click(TObject *Sender)  //Загрузка из файл
{ ClassTmp=new TClassTmp();
  LoadObjFromFile(ClassTmp,"c:\\1.txt");
  ShowMessage(IntToStr(ClassTmp->Prop)+"  "+IntToStr(ClassTmp->List->Count)+"  "+((TBitBtn*)ClassTmp->List->Items[0])->Caption);
  delete ClassTmp;
}

Здесь функции SaveObjToFile(ClassTmp,"c:\\1.txt"); и LoadObjFromFile(ClassTmp,"c:\\1.txt"); взяти из статьи Snowy Тут
вот кусок его кода относящийся к моей проге
Код

unit Saver;

interface

uses SysUtils, Classes;

procedure WriteObj(obj: TPersistent; st: TStream);
procedure ReadObj(obj: TPersistent; st: TStream);

procedure SaveObjToFile(obj: TPersistent; FileName: string);
procedure LoadObjFromFile(obj: TPersistent; FileName: string);

implementation

type
  TObjWriter = class(TWriter)
  end;
  TObjReader = class(TReader)
  end;

procedure WriteObj(obj: TPersistent; st: TStream);
begin
  with TObjWriter.Create(st, 10240) do
  begin
    WriteProperties(obj);
    FlushBuffer; Free;
  end;
end;

procedure ReadObj(obj: TPersistent; st: TStream);
begin
  with TObjReader.Create(st, 1) do
  begin
    while st.Position < st.Size do
    try ReadProperty(obj); except Continue; end;
    Free;
  end;
end;

procedure SaveObjToFile(obj: TPersistent; FileName: string);
var fs: TFileStream;
begin
  try
    fs := TFileStream.Create(FileName, fmCreate or fmShareDenyWrite);
    try
      WriteObj(obj, fs);
    finally
      fs.Free;
    end;
  except end;
end;

procedure LoadObjFromFile(obj: TPersistent; FileName: string);
var fs: TFileStream;
begin
  if FileExists(FileName) then try
    fs := TFileStream.Create(FileName, fmShareDenyWrite);
    try
      ReadObj(obj, fs);
    finally
      fs.Free;
    end;
  except end;
end;

end.

новот почемуто программа не сохраняет в файл обьект, точнее сохраняет но не вес а только вот это значение "ClassTmp->Prop" ну а кудаже подевался  ClassTmp->Buton и ClassTmp->List неизвестно
подскажите что тут не так сделано?


--------------------
Ни цего не понимаю
PM MAIL ICQ   Вверх
stmamont
Дата 20.9.2006, 10:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 343
Регистрация: 13.3.2004
Где: влг

Репутация: 3
Всего: 3



А разве указатели сохраняются?
Наверное нужно сделать их НЕ указателями.


--------------------
user posted image
PM MAIL ICQ   Вверх
Teran
Дата 20.9.2006, 10:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 590
Регистрация: 9.9.2005
Где: Украина, Запорожь е

Репутация: нет
Всего: 3



Цитата(stmamont @  20.9.2006,  10:35 Найти цитируемый пост)
Наверное нужно сделать их НЕ указателями

а разве это можно? как?


--------------------
Ни цего не понимаю
PM MAIL ICQ   Вверх
Sartorius
Дата 20.9.2006, 11:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1568
Регистрация: 18.7.2006
Где: Ivory tower

Репутация: нет
Всего: 37



 Так как у тебя есть поля-указатели, тебе придется отдельно написать сохраниние и восстановление той области памяти, на которую они ссылаются... 
PM MAIL ICQ   Вверх
Teran
Дата 20.9.2006, 11:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 590
Регистрация: 9.9.2005
Где: Украина, Запорожь е

Репутация: нет
Всего: 3



т.е. в конечном итоге можно реализовать сохранение только стандартных типов (int,AnsiString,bool,...), а уже сохранение полей указателей нужно отдельно писать самому основываясь на сохранение стандартных типов

Добавлено @ 11:16 
тогда ткаое сохранение ничем неотличается от обычного сохранения в ini файле


--------------------
Ни цего не понимаю
PM MAIL ICQ   Вверх
Vyacheslav
Дата 20.9.2006, 11:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 47
Всего: 59



Не совсем так. Сохранять можно все, например ту же форму целиком. Что кстати делает успешно и IDE и ряд программ и библиотек(RXLIB). Только такой подход в лоб не совсем проходит.
Вот например  хидеры моей формы, которая  могла сохранять свое состояние (размеры, координаты, сттатус) + состояние тех компонентов на форме, которые я в дизайне мог доавить по выбору  в свойсвто(колеекцию) StoredItems - 
Код

typedef  void __fastcall (__closure *TStoredValueEvent)(System::TObject* Sender,
                                                        const AnsiString& Name,
                                                        Variant& Data);
typedef  void __fastcall (__closure *TStoredComponentEvent)(System::TObject* Sender,
                                                        const AnsiString& Name,
                                                        TComponent* Component,
                                                        TStream* Stream);
typedef void __fastcall  (__closure *TMDIModalFormClose)(System::TObject* Sender,
                                                         TModuleForm* Form);
//---------------------------------------------------------------------------
class PACKAGE TStoredItem : public TCollectionItem
{
    typedef TCollectionItem inherited;
private:
    Variant m_Value;
    AnsiString m_Name;
    bool m_Stored;
    std::auto_ptr<TMemoryStream> m_Stream;
    TComponent* m_Component;
    TStoredComponentEvent   m_OnSaveItemComponent;
    TStoredComponentEvent   m_OnRestoreItemComponent;
    TStoredValueEvent       m_OnSaveItemValue;
    TStoredValueEvent       m_OnRestoreItemValue;
                              
private:
    void __fastcall SetDisplayName(const AnsiString );
    AnsiString __fastcall GetDisplayName();
    bool __fastcall TestName(const AnsiString&);
    void __fastcall SaveComponent(TComponent*, TStream*);
    void __fastcall RestoreComponent(TComponent**, TStream*);
protected:

    void __fastcall DefineProperties(TFiler* Filer);
    void __fastcall ReadStream(TStream* AStream);
    void __fastcall WriteStream(TStream* AStream);

public:
    virtual __fastcall TStoredItem(TCollection* a_Collection);
    __fastcall ~TStoredItem(void){}
    void __fastcall Assign(TPersistent* );
__published:
   __property TComponent* Component  = { read=m_Component, write=m_Component, stored = m_Stored };
   __property Variant Value  = { read=m_Value, write=m_Value};
   __property TStoredComponentEvent OnSaveComponent  = { read=m_OnSaveItemComponent, write=m_OnSaveItemComponent, stored = m_Stored };
   __property TStoredComponentEvent OnRestoreComponent  = { read=m_OnRestoreItemComponent, write=m_OnRestoreItemComponent, stored = m_Stored };
   __property TStoredValueEvent OnBeforeSaveValue  = { read=m_OnSaveItemValue, write=m_OnSaveItemValue, stored = m_Stored };
   __property TStoredValueEvent OnAfterRestoreValue  = { read=m_OnRestoreItemValue, write=m_OnRestoreItemValue, stored = m_Stored };
   __property AnsiString Name  = { read=GetDisplayName, write=SetDisplayName };

};
//---------------------------------------------------------------------------
class PACKAGE  TStoredItems : public TOwnedCollection
{
     typedef TOwnedCollection inherited;
private:
public:
    virtual __fastcall TStoredItems(TComponent* a_Owner):
                       TOwnedCollection( a_Owner, __classid(TStoredItem)){}
    __fastcall ~TStoredItems(void){}
    TStoredItem* __fastcall FindByName(const AnsiString&);
    int __fastcall IndexOf(const AnsiString&);
__published:

};
//---------------------------------------------------------------------------
// Класс:       TDataWrapper
// Описание:    Служебный компонент-обертка, содержащий сохраняемые данные  -
// Назначение:  Предназначен для сохранения-загрузки данных в поток,
//              с использованием встроенных средств сохранения загрузки
//              компонента
// Комментарий: Предназначен для работы только внутри класса TModuleForm
//              С этой целью конструктор класса сделан protected.
//              В конструкторе параметр Owner должен быть экземпляром
//              класса TModuleForm
//---------------------------------------------------------------------------
class PACKAGE TDataWrapper: public Classes::TComponent
{
        typedef Classes::TComponent  inherited;
private:
        TStoredItems*   m_StoredItems;
        void __fastcall ReadTop(TReader*);
        void __fastcall WriteTop(TWriter*);
        void __fastcall ReadLeft(TReader*);
        void __fastcall WriteLeft(TWriter*);
        void __fastcall ReadWidth(TReader*);
        void __fastcall WriteWidth(TWriter*);
        void __fastcall ReadHeight(TReader*);
        void __fastcall WriteHeight(TWriter*);
        void __fastcall ReadFormState(TReader*);
        void __fastcall WriteFormState(TWriter*);
protected:
        __fastcall TDataWrapper(TComponent*);
        void __fastcall DefineProperties(TFiler*);
public:
        __fastcall ~TDataWrapper();

__published:
       __property TStoredItems* StoredItems  = { read=m_StoredItems, write=m_StoredItems };

friend class TModuleForm;
};

//---------------------------------------------------------------------------
typedef void __fastcall (__closure *TExitProc)(void);

enum TStoredParam {spTop, spLeft, spWidth, spHeight, spState, spAutoSave, spAutoRestore};
typedef Set<TStoredParam, spTop, spAutoRestore> TStoredParams;

class PACKAGE TModuleForm : public TForm
{
    typedef TForm  inherited;
private:

    TPluginModule* m_Module;
    TExitProc m_ExitProc;
    TModuleForm* m_ParentForm;
    TModuleForm* m_ChildForm;
    //TStoredParams* m_StoredParams;
    TStoredItems* m_StoredItems;
    char m_StoredParams;
    TFunction* m_Function;
    AnsiString  m_ID;
    TNotifyEvent m_OnPrint;
    TNotifyEvent m_OnPrintDlgBeforeExecute;
    bool m_DestroyModule;
    bool m_MDIModalForm;
    TMDIModalFormClose m_OnMDIModalFormClose;
    void __fastcall SetStoredItems(TStoredItems* value);
    TStoredItems* __fastcall GetStoredItems();
    void __fastcall SetOnPrint(TNotifyEvent value);
    TNotifyEvent __fastcall GetOnPrint();
    void __fastcall SetOnPrintDlgBeforeExecute(TNotifyEvent value);
    TNotifyEvent __fastcall GetOnPrintDlgBeforeExecute();
    void __fastcall SetMDIModalForm(bool value);
    bool __fastcall GetMDIModalForm();
    void __fastcall SetFormStyle(TFormStyle value);
    TFormStyle __fastcall GetFormStyle();


protected:
    DYNAMIC void __fastcall Activate(void);
    DYNAMIC void __fastcall DoClose(TCloseAction &Action);
    void __fastcall Save(TStream*);
    void __fastcall Restore(TStoredItems*, TStoredItems*);
    void __fastcall Restore(TStream*);
    void __fastcall SetStoredParams(TStoredParams value);
    TStoredParams __fastcall GetStoredParams();
    void __fastcall Redirect(TComponent * Root, TDataModule * DataModule);

public:
    virtual __fastcall TModuleForm(TPluginModule*, TFunction*);
    __fastcall ~TModuleForm(void);
    virtual void __fastcall DoPrint(TObject*);
    void __fastcall DoPrintDlgBeforeExecute(TObject*);
    virtual void __fastcall Restore(void);
    virtual void __fastcall Save(void);
    __property TFunction* Function  = { read=m_Function };
    __property TPluginModule* Module = { read=m_Module };
__published:
   
    __property TStoredItems* StoredItems  = { read=GetStoredItems, write=SetStoredItems };
    __property TStoredParams StoredParams  = { read=GetStoredParams, write=SetStoredParams };
    __property TNotifyEvent OnPrint  = { read=GetOnPrint, write=SetOnPrint };
    __property TNotifyEvent OnPrintDlgBeforeExecute  = { read=GetOnPrintDlgBeforeExecute, write=SetOnPrintDlgBeforeExecute };
    __property bool DestroyModule  = { read=m_DestroyModule, write=m_DestroyModule };
    __property bool MDIModalForm  = { read=GetMDIModalForm, write=SetMDIModalForm };
    __property TFormStyle FormStyle  = { read=GetFormStyle, write=SetFormStyle };
    __property TMDIModalFormClose OnMDIModalFormClose  = { read=m_OnMDIModalFormClose, write=m_OnMDIModalFormClose };

friend class TFunction;
friend class TDataWrapper;
};

 

Эта форма - моя со  своими дополнительными проперятим и ее(форму) я использовал вместо стандартной. Возможно это тебя наведет на определенные мысли. Обратите внимание, на TStoredItem.
Этот член коллекции может сохранить, либо компонент(свойство Component  ) либо любой простой тип (свойство Value), либо то и другое вместе. Подход достаточно универсален и универсальность в том, что нет необходимости заренее определять, что будет храниться. От использования ini, это отличается тем, что загружая Component, я не знаю, что в данный момент я гружу. Это может быть Button, а может быть Label.
Что касается самой идеи, то могу предолжить следующее решение.
Создай свой компонент( в данном примере я обошелся без компонента, встроив коллекцию непосредсвенно в форму), который  будет содержать коллекцию. Этот компонент должен сохранять коллекцию, которая содержить указатели на те компонент, которые нужно сохранить


--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
Teran
Дата 20.9.2006, 18:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 590
Регистрация: 9.9.2005
Где: Украина, Запорожь е

Репутация: нет
Всего: 3



мда....   Vyacheslav загрузил ты меня пополной.
такой код я наверное 3 месяца пережовывать буду


--------------------
Ни цего не понимаю
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по С++ Builder обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Настоятельно рекомендуем заглянуть в DRKB (Delphi Russian Knowledge Base) - крупнейший в рунете сборник материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C++ Builder | Следующая тема »


 




[ Время генерации скрипта: 0.0499 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.