antarey Опубликовано 14 октября, 2014 Поделиться Опубликовано 14 октября, 2014 Пытаюсь переделать под билдер Automate Save State Feature in Firemonkey Как говорят вроде все просто, но толи лижи не едут ну и т.д. делфи код unit SaveStateHelper; interface uses FMX.Forms; type TSaveStateHelper = class helper for TCustomForm public const DATA_FIELD = 'data'; procedure SaveFormState; procedure LoadFormState; end; implementation uses System.JSON, FMX.Types, System.Classes, System.SysUtils; { TSaveStateHelper } procedure TSaveStateHelper.LoadFormState; var R: TBinaryReader; FormJSONObject: TJSONObject; I: Integer; FMXObj: TFmxObject; FMXJObj: TJSONObject; begin try if not(SaveState.Stream.Size > 0) then exit; // Recover previously typed values in all control. R := TBinaryReader.Create(SaveState.Stream); try FormJSONObject := TJSONObject.ParseJSONValue(R.ReadString) as TJSONObject; try for I := 0 to Self.ComponentCount - 1 do begin if not(Self.Components[I] is TFmxObject) then continue; FMXObj := Self.Components[I] as TFmxObject; FMXJObj := FormJSONObject.Values[FMXObj.Name] as TJSONObject; case FMXObj.Data.Kind of tkUnknown: ; tkInteger: FMXObj.Data := (FMXJObj.GetValue(DATA_FIELD) as TJSONNumber).AsInt; tkChar: ; tkEnumeration: if FMXJObj.GetValue(DATA_FIELD) is TJSONTrue then FMXObj.Data := true else FMXObj.Data := false; tkFloat: FMXObj.Data := (FMXJObj.GetValue(DATA_FIELD) as TJSONNumber).AsDouble; tkString, tkUString, tkLString, tkWString: FMXObj.Data := (FMXJObj.GetValue(DATA_FIELD) as TJSONString).Value; tkSet: ; tkClass: ; tkMethod: ; tkWChar: ; tkVariant: ; tkArray: ; tkRecord: ; tkInterface: ; tkInt64: FMXObj.Data := (FMXJObj.GetValue(DATA_FIELD) as TJSONNumber).AsInt64; tkDynArray: ; tkClassRef: ; tkPointer: ; tkProcedure: ; end; end; finally FormJSONObject.Free; end; finally R.Free; end; except on e: Exception do Log.d('SaveStateHelper', Self, e.Message); end; end; procedure TSaveStateHelper.SaveFormState; var FormJSONObject: TJSONObject; I: Integer; FMXObj: TFmxObject; FMXJObj: TJSONObject; W: TBinaryWriter; begin try FormJSONObject := TJSONObject.Create; try for I := 0 to Self.ComponentCount - 1 do begin if not(Self.Components[I] is TFmxObject) then continue; FMXObj := Self.Components[I] as TFmxObject; FMXJObj := TJSONObject.Create; case FMXObj.Data.Kind of tkUnknown: ; tkInteger: FMXJObj.AddPair(DATA_FIELD, TJSONNumber.Create(FMXObj.Data.AsInteger)); tkChar: ; tkEnumeration: if FMXObj.Data.AsBoolean then FMXJObj.AddPair(DATA_FIELD, TJSONTrue.Create) else FMXJObj.AddPair(DATA_FIELD, TJSONFalse.Create); tkFloat: FMXJObj.AddPair(DATA_FIELD, TJSONNumber.Create(FMXObj.Data.AsExtended)); tkString, tkUString, tkLString, tkWString: FMXJObj.AddPair(DATA_FIELD, FMXObj.Data.AsString); tkSet: ; tkClass: ; tkMethod: ; tkWChar: ; tkVariant: ; tkArray: ; tkRecord: ; tkInterface: ; tkInt64: FMXJObj.AddPair(DATA_FIELD, TJSONNumber.Create(FMXObj.Data.AsInt64)); tkDynArray: ; tkClassRef: ; tkPointer: ; tkProcedure: ; end; FormJSONObject.AddPair(FMXObj.Name, FMXJObj) end; SaveState.Stream.Clear; W := TBinaryWriter.Create(SaveState.Stream); try W.Write(FormJSONObject.ToJSON); finally W.Free; end; finally FormJSONObject.Free; end; except on e: Exception do Log.d('SaveStateHelper', Self, e.Message); end; end; end. Что наваял: SaveStateHelper.h #ifndef SaveStateHelperH #define SaveStateHelperH //--------------------------------------------------------------------------- #include <FMX.Forms.hpp> #include <System.Classes.hpp> #include <System.SysUtils.hpp> #include <FMX.Types.hpp> #include <System.JSON.hpp> //--------------------------------------------------------------------------- class TSaveStateHelper : public TCustomForm { __published: private: // User declarations public: // User declarations void SaveFormState(); void LoadFormState(); void Init(); }; #endif SaveStateHelper.cpp //--------------------------------------------------------------------------- #pragma hdrstop #include "SaveStateHelper.h" #include <System.IOUtils.hpp> //--------------------------------------------------------------------------- #pragma package(smart_init) //--------------------------------------------------------------------------- void TSaveStateHelper::Init() { SaveState->Name=System::Ioutils::TPath::GetFileNameWithoutExtension(ParamStr(0)); SaveState->StoragePath = System::Ioutils::TPath::GetHomePath(); } //--------------------------------------------------------------------------- void TSaveStateHelper::LoadFormState() { TBinaryReader *R; TJSONObject *FormJSONObject; TFmxObject *FMXObj; TJSONObject *FMXJObj; if (SaveState->Stream->Size >0) { } } //--------------------------------------------------------------------------- и при вызове LoadFormState получаю access violation Что не так Цитата Ссылка на комментарий
0 antarey Опубликовано 14 октября, 2014 Автор Поделиться Опубликовано 14 октября, 2014 ну почему access violation - разобрался - вызов SaveState производится без объекта если frmMain->SaveState -то все нормально. Но связать вызывающую форму с кодом не привязываясь к конкретному имени формы? Цитата Ссылка на комментарий
0 antarey Опубликовано 17 октября, 2014 Автор Поделиться Опубликовано 17 октября, 2014 Один нюанс- в делфи FormJSONObject.AddPair(FMXObj.Name, FMXJObj) в файле ‘{"Edit1":{"data":"qwerty"},"Edit2":{"data":"adfsdaf"},"GroupBox1":{"data":"Your Preferred OS"},"RadioButton1":{"data":false},"RadioButton2":{"data":true},"RadioButton3":{"data":false},"RadioButton4":{"data":false},"Label1":{"data":"Firstname"},"Label2":{"data":"Lastname"}} В билдере FormJSONObject.AddPair(FMXObj.Name, FMXJObj) выдает ошибку неверный указатель если FormJSONObject->AddPair(FMXObj->Name, FMXJObj->ToJSON()); то записывается как Б{"Switch1":"{\"data\":\"Switch1\"}","Edit1":"{\"data\":\"ADS\"}","Memo1":"{\"data\":\"Switch1\\r\\nADS\\r\\nSwitch1\\r\\nADS\\r\\nComboBox1\\r\\n{\\\"Switch1\\\":\\\"{\\\\\\\"data\\\\\\\":\\\\\\\"Switch1\\\\\\\"}\\\",\\\"Edit1\\\":\\\"{\\\\\\\"data\\\\\\\":\\\\\\\"ADS\\\\\\\"}\\\",\\\"Memo1\\\":\\\"{\\\\\\\"data\\\\\\\":\\\\\\\"Switch1\\\\\\\\r\\\\\\\\nADS\\\\\\\"}\\\",\\\"CheckBox1\\\":\\\"{}\\\",\\\"RadioButton1\\\":\\\"{}\\\",\\\"RadioButton2\\\":\\\"{}\\\",\\\"ComboBox1\\\":\\\"{\\\\\\\"data\\\\\\\":\\\\\\\"ComboBox1\\\\\\\"}\\\",\\\"Button1\\\":\\\"{}\\\"}\\r\\nSwitch1\\r\\nADS\"}","CheckBox1":"{}","RadioButton1":"{}","RadioButton2":"{}","ComboBox1":"{\"data\":\"ComboBox1\"}","Button1":"{}"} тоесть добавляется "\" - как правильно перевести с делфи на с++?? Цитата Ссылка на комментарий
0 antarey Опубликовано 17 октября, 2014 Автор Поделиться Опубликовано 17 октября, 2014 по предыдущему вопросу - билдер так и пишет Народ, помогите победить в C++ BuilderXE7 вот что записано {"Edit1":"{\"data\":\"test\"}"} код для записи void __fastcall TfrmMain::FormSaveState(TObject *Sender) { const System::String DATA_FIELD = "data"; SaveState->Name=System::Ioutils::TPath::GetFileNameWithoutExtension(ParamStr(0)); SaveState->StoragePath = System::Ioutils::TPath::GetHomePath(); TJSONObject *FormJSONObject; TFmxObject *FMXObj; TJSONObject *FMXJObj; TBinaryWriter *W; SaveState->Stream->Clear(); W = new TBinaryWriter(SaveState->Stream, TEncoding::UTF8, false); FormJSONObject = new TJSONObject(); for (int i = 0; i < ComponentCount; i++) { if (dynamic_cast<TFmxObject*>(Components[i])) { FMXObj=dynamic_cast<TFmxObject*>(Components[i]); FMXJObj = new TJSONObject(); switch (FMXObj->Data.Kind) { case tkUnknown: break; case tkInteger: FMXJObj->AddPair(DATA_FIELD, new TJSONNumber(FMXObj->Data.AsInteger()));break; case tkChar: break; case tkEnumeration: if (FMXObj->Data.AsBoolean())FMXJObj->AddPair(DATA_FIELD, new TJSONTrue()); else FMXJObj->AddPair(DATA_FIELD, new TJSONFalse());break; case tkFloat: FMXJObj->AddPair(DATA_FIELD,FMXObj->Data.AsVariant());break; case tkString: FMXJObj->AddPair(DATA_FIELD, FMXObj->Data.AsString());break; case tkUString: FMXJObj->AddPair( DATA_FIELD,FMXObj->Data.AsString());break; case tkLString: FMXJObj->AddPair(DATA_FIELD, FMXObj->Data.AsString());break; case tkWString: FMXJObj->AddPair(DATA_FIELD, FMXObj->Data.AsString());break; case tkSet: break; case tkClass: break; case tkMethod: break; case tkWChar: break; case tkVariant: break; case tkArray: break; case tkRecord: break; case tkInterface: break; case tkInt64: break; case tkDynArray: break; case tkClassRef: break; case tkPointer: break; case tkProcedure: break; } FormJSONObject->AddPair(FMXObj->Name, FMXJObj->ToJSON()); } } try { W->Write(FormJSONObject->ToJSON()); } __finally { W->Free(); FormJSONObject->Free(); FMXJObj->Free(); } } //--------------------------------------------------------------------------- вот так пытаюсь читать void __fastcall TfrmMain::FormCreate(TObject *Sender) { SaveState->Name=System::Ioutils::TPath::GetFileNameWithoutExtension(ParamStr(0)); SaveState->StoragePath = System::Ioutils::TPath::GetHomePath(); TBinaryReader *R = new TBinaryReader(SaveState->Stream, TEncoding::UTF8, false); if (SaveState->Stream->Size >0) { TJSONObject *jObj = static_cast<TJSONObject*>(TJSONObject::ParseJSONValue(R->ReadString())); TJSONObject *jItem = static_cast<TJSONObject*>(jObj->Get("Edit1")->JsonValue); Edit1->Text = jItem->Get("data")->JsonValue->Value(); } R->Free(); } //--------------------------------------------------------------------------- на Edit1->Text = jItem->Get("data")->JsonValue->Value(); выдает access violation уже перепробовал все возможные варианты чтения Edit1->Text = jItem->Values[0]->ToString(); Edit1->Text = jItem->Values["data"]->ToString(); Edit1->Text = jItem->Values["data"]->Value(); Edit1->Text = jItem->GetValue("data")->Value(); хотя Edit1->Text = jItem->Value(); выдает {"data":"test"} - тоесть данные есть - но какого они не читаются Забодался уже, толи лижи не едут, толи я ..., толи ембарседеро что-то нафигачело в билдере Всем заранее спасибо Цитата Ссылка на комментарий
Вопрос
antarey
Пытаюсь переделать под билдер Automate Save State Feature in Firemonkey
Как говорят вроде все просто, но толи лижи не едут ну и т.д.
делфи код
Что наваял:
SaveStateHelper.h
и при вызове LoadFormState получаю access violation
Что не так
Ссылка на комментарий
3 ответа на этот вопрос
Рекомендуемые сообщения
Присоединяйтесь к обсуждению
Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.