Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Разное
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 23.09.2022, 21:55
basilcat basilcat вне форума
Прохожий
 
Регистрация: 27.04.2017
Сообщения: 16
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию Создание точки восстановления программы написанной на Delphi

Вопрос знатокам. Возможно ли создать точку восстановления программы написанной на Delphi.
Т.е. записать в файл полное состояние программы с целью при повторном запуске приложения продолжить работу так, как будто вы не выгружались.
В своём Sapr автоматизированного раскроя я сохраняю в бинаный файл те классы, которые отвечают за раскладку деталей на листе раскроя. Но есть ньюансы при чтении данных из этого бинарного файла после загрузки приложения. Раскрой воспроизводится и можно продолжить дальнейшую раскладку деталей с возможностью изменения положения ранее разложенных деталей. Но нет возможности делать откат назад и возврат, хотя он работает при самом проектировании. Возможно ли сохранить состояние программы каким то другим способом. Исходные коды Sapr мои .
Ответить с цитированием
  #2  
Старый 23.09.2022, 23:03
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,003
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Ну так сохраняй в бинарник историю тоже.

Теоретически, можно сохранить весь дамп памяти приложения. Вот только потом будут проблемы с восстановлением, бо как физ адреса съедут. Т.е. в твоем случае заморачиваться смысла нет, просто пиши в бинарник историю, если это действительно нужно при "восстановлении".
Ответить с цитированием
  #3  
Старый 24.09.2022, 11:55
basilcat basilcat вне форума
Прохожий
 
Регистрация: 27.04.2017
Сообщения: 16
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от lmikle
Ну так сохраняй в бинарник историю тоже.

Теоретически, можно сохранить весь дамп памяти приложения. Вот только потом будут проблемы с восстановлением, бо как физ адреса съедут. Т.е. в твоем случае заморачиваться смысла нет, просто пиши в бинарник историю, если это действительно нужно при "восстановлении".

Торопился и не совсем правильно выразился.
"я сохраняю в бинаный файл те классы, которые отвечают за раскладку деталей " имею ввиду конечно не сами классы, а записи, ссылки на которые сохраняю в этих классах ( классы TList).

Код:
type
 	PNewElement=^TNewElement;
	TNewElement=record
           NumberFigures:integer; // порядковый номер фигуры раскроя 1,2,3...
           Begin_Figures:integer; // начальный индекс фигуры в списке  List
           End_Figures:integer;   // конечный индекс фигуры в списке  List
           Nach_Point:TPointM;
           End_Point:TPointM;
           Angle_Rotate    :double;
           MRect:TMainRect;
           STR_Coment:string[80];
	case Element  :TMElement of
            elLine 	:(Pln,Plk:TPointM);
            elCircle    :(Pn,Pk,Pc:TPointM;Direct:TPrisnak);
            elBKL       :(BKL:integer);
            elBIKL      :(BIKL:integer);
            elKORLeft   :(KORLeft:integer);
            elKORRight  :(KORRight:integer);
            elKORKK     :(KORKK	:integer);
            elHP        :(HP:boolean);
            elKP        :(KP:integer);
            elBX	:(BX:integer);
            elBBX	:(BBX:integer);
            elHPP       :(HPP:integer); // 1001,1002
            elKPP       :(KPP:integer);
            elBPP       :(BPP,BPPN:integer;BPPAngle:real);
            elSpeed     :(Speed	:boolean);
            elNul	:(NUL:boolean);
            elABC	:(ABC:boolean);
            elPrisnak   :(Prisn:TPrisnak);
            elName      :(Name:string[80]);
            elComent    :(Comment:boolean);
       	end;

 	PChetchik=^TChetchik_;
	TChetchik_=record
       NumberFigures:integer; // порядковый номер детали в StringList -  1,4,2,2,3,3,5.
       end;
...


var
FiguresElem:PNewElement;
FigureList_Elem_:TList; // список который заполняется адресами элементов детали
Chetchik:PChetchik;
FLE_Chetchik:TList;

...
procedure TFormSapr.SaveFigure_NEW;   // ïèñàòü
var
   i,j:integer;
   f:file;
   filename: string;
   FigureIndex_:integer;
begin
      if FigureList_Elem_.Count<>0 then   // ñàìè ôèãóðû
      begin
       FigureIndex:=FigureList_Elem_.Count-1;
       filename:=ExtractFilePath(ParamStr(0))+'RaskFigMem\FigureList_Elem.figN';
       system.assign(f,filename);
       system.rewrite(f,1);
       system.blockWrite(f,FigureIndex,sizeof(FigureIndex));

       for i:=0 to FigureList_Elem_.Count-1 do
       begin
            FiguresElem:=FigureList_Elem_.Items[i];
            system.blockWrite(f,FiguresElem^,SizeOf(FiguresElem^));
       end;

            system.blockWrite(f,FiguresElem^.Nach_Point.X,SizeOf(FiguresElem^.Nach_Point.X));
            system.blockWrite(f,FiguresElem^.Nach_Point.Y,SizeOf(FiguresElem^.Nach_Point.Y));

            system.blockWrite(f,FiguresElem^.End_Point.X,SizeOf(FiguresElem^.End_Point.X));
            system.blockWrite(f,FiguresElem^.End_Point.Y,SizeOf(FiguresElem^.End_Point.Y));


            system.blockWrite(f,FiguresElem^.MRect.MinX,SizeOf(FiguresElem^.MRect.MinX));
            system.blockWrite(f,FiguresElem^.MRect.MaxX,SizeOf(FiguresElem^.MRect.MaxX));

            system.blockWrite(f,FiguresElem^.MRect.MinY,SizeOf(FiguresElem^.MRect.MinY));
            system.blockWrite(f,FiguresElem^.MRect.MaxY,SizeOf(FiguresElem^.MRect.MaxY));

        system.close(f);
      end; // if FigureList_Elem_.Count<>0 then



      if FLE_Chetchik.Count<>0 then   // ïîðÿäêîâûé íîìåð ôèãóðû ðàñêðîÿ 1,4,2,2,3,3,5... èç StringGrid1
      begin
       FigureIndex_:=FLE_Chetchik.Count-1;
       filename:=ExtractFilePath(ParamStr(0))+'RaskFigMem\FLE_Chetchik.figN';
       system.assign(f,filename);
       system.rewrite(f,1);
       system.blockWrite(f,FigureIndex_,sizeof(FigureIndex_));

       for i:=0 to FLE_Chetchik.Count-1 do
       begin
            Chetchik:=FLE_Chetchik.Items[i];
            system.blockWrite(f,Chetchik^,SizeOf(Chetchik^));
       end;
        system.close(f);

      end;



end;

procedure TFormSapr.LoadRaskroj_NEW; // ÷èòàòü
var
   i,j,nomread:integer;
   f:file;
   S,S1:string;
   k:integer;
   fileName:string;
   FigureIndex_:integer;

begin
       if FigureList_Elem_.Count=0 then
       begin
             filename:=ChangeFileExt(ExtractFilePath(ParamStr(0))+'RaskFigMem\FigureList_Elem.figN','.figN');
             if not FileExists(filename) then
                Exit;
             LMDLabel7.Caption:='ÑÈÑÒÅÌÀ SAPR ×ÏÓ. ÐÀÑÊÐÎÉ :  '+ExtractShortPathName(filename);

             system.assign(f,Filename);
             system.Reset(f,1);
             system.blockRead(f,FigureIndex,sizeof(FigureIndex),nomread);

             for i:=0 to FigureIndex do // èçì
             begin
                  new(FiguresElem);
                  system.blockRead(f,FiguresElem^,SizeOf(FiguresElem^),nomread);
                  if (i=FigureIndex) then
                      Index_Figure:=FiguresElem.NumberFigures;
                  FigureList_Elem_.Add(FiguresElem);
             end;

Nach_Point_X := FiguresElem^.Nach_Point.X;
Nach_Point_Y := FiguresElem^.Nach_Point.Y;
End_Point_X  := FiguresElem^.End_Point.X;
End_Point_Y  := FiguresElem^.End_Point.Y;

MRect_MinX   := FiguresElem^.MRect.MinX;
MRect_MaxX   := FiguresElem^.MRect.MaxX;
MRect_MinY   := FiguresElem^.MRect.MinY;
MRect_MaxY   := FiguresElem^.MRect.MaxY;


             Inc(Index_Figure);
             system.close(f);
       end;


       if FLE_Chetchik.Count=0 then
       begin
             filename:=ChangeFileExt(ExtractFilePath(ParamStr(0))+'RaskFigMem\FLE_Chetchik.figN','.figN');
             if not FileExists(filename) then
                Exit;

             system.assign(f,Filename);
             system.Reset(f,1);
             system.blockRead(f,FigureIndex_,sizeof(FigureIndex_),nomread);

             for i:=0 to FigureIndex_ do
             begin
                  new(Chetchik);
                  system.blockRead(f,Chetchik^,SizeOf(Chetchik^),nomread);
                  FigureList_Elem_.Add(Chetchik);
             end;
             system.close(f);

       end;

    if FormSapr.Panel_Visual_Raskroj1<>nil then
      Panel_Visual_Raskroj1.WMPaint(Msg1)
    else
      Panel_Visual_Raskroj2.WMPaint(Msg1);


end;
В чём состоит проблема. Читается всё правильно, но в FigureList_Elem_ в последнем элементе впоследствии, когда начинаю выводить следующую деталь значения в FiguresElem^ ответственные за привязку следующей детали к предыдущей обнуляются, хотя при прочтении были верные. Пришлось пойти на хитрость и сразу после прочтения файла записать теряемые значения в
Код:
Nach_Point_X := FiguresElem^.Nach_Point.X;
Nach_Point_Y := FiguresElem^.Nach_Point.Y;
End_Point_X  := FiguresElem^.End_Point.X;
End_Point_Y  := FiguresElem^.End_Point.Y;

MRect_MinX   := FiguresElem^.MRect.MinX;
MRect_MaxX   := FiguresElem^.MRect.MaxX;
MRect_MinY   := FiguresElem^.MRect.MinY;
MRect_MaxY   := FiguresElem^.MRect.MaxY;
И потом в том месте где они нужны заменять все FiguresElem^.End_Point.X и т.д. на End_Point_X и т.д.:
Код:
           if (Index_Figure>1) and (i=1) then
           begin

{Line}          new(FiguresElem);
                FiguresElem^.Element:=elLine;
if Flag_Vosstanovlen then
begin
                FiguresElem^.Pln.X:=End_Point_X;
                FiguresElem^.Pln.Y:=End_Point_Y;

                FiguresElem^.Plk.X:=MRect_MinX;
                FiguresElem^.Plk.Y:=MRect_MaxY+5;
                Flag_Vosstanovlen:=false;
end
else
begin
                FiguresElem^.Pln:=PNewElement(FigureList_Elem_.Items[BeginFig-1]).End_Point;
                FiguresElem^.Plk.X:=PNewElement(FigureList_Elem_.Items[BeginFig-1]).MRect.MinX;
                FiguresElem^.Plk.Y:=PNewElement(FigureList_Elem_.Items[BeginFig-1]).MRect.MaxY+5;

end;




//                FiguresElem^.Pln:=PNewElement(FigureList_Elem_.Items[BeginFig-1]).End_Point;
//                FiguresElem^.Plk.X:=PNewElement(FigureList_Elem_.Items[BeginFig-1]).MRect.MinX;
//                FiguresElem^.Plk.Y:=PNewElement(FigureList_Elem_.Items[BeginFig-1]).MRect.MaxY+5;
                FiguresElem^.Begin_Figures:=BeginFig;
                FiguresElem^.End_Figures:=BeginFig+FigureIndex+1;
                FiguresElem^.NumberFigures:=Index_Figure;
                Nach_Point_:=FiguresElem^.Plk;

                Xmin_:=FiguresElem^.Pln.X;
                Xmax_:=FiguresElem^.Pln.Y;
                Ymin_:=FiguresElem^.Pln.X;
                Ymax_:=FiguresElem^.Pln.Y;

                FiguresElem^.MRect.MinX:=Xmin_;
                FiguresElem^.MRect.MaxX:=Xmax_;
                FiguresElem^.MRect.MinY:=Ymin_;
                FiguresElem^.MRect.MaxY:=Ymax_;

                FigureList_Elem_.Add(FiguresElem);

           end
Чего хотелось не делать. Т.к. при выводе новой фигуры и попытке её перемещать вылетает трудно обнаруживаемая ошибка. Видимо какие то переменные не пишу и потом не читаю. Буду искать, но пока что ...
Потому что приходится стирать всё и читать второй раз, тогда всё работает нормально.[/code]

Последний раз редактировалось lmikle, 26.09.2022 в 04:23.
Ответить с цитированием
  #4  
Старый 26.09.2022, 04:30
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,003
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Значит что-то не пишешь или не читаешь. Кстати, что такое TPointM? Указатель на структуру? Если да, то вот тут и есть ошибка, бо, как видимо, там сохраняется адрес, а не содержимое полей. Кстати, там вообще можно тогда на Access Violation налететь только так.

Вообще, это у тебя кошмар какой-то.
Нет что бы сделать нормальную иерархию классов. В каждом классе есть метод его записи и чтения (например, в поток, так лучше, чем использовать нетипизированный файл). И, соответсвенно, просто вызывается соотв. метод.
Посмотри, я вот тут:
https://delphisources.ru/forum/showt...029#post158029
постил пример модели. Там всего 2 уровня, но идея должна быть понятна. Да, кода придется написать чуточку больше, но зато будет красиво и читабельно.
Ну и вообще, поправишь модель. А то есть у меня подозрение, что у тебя там что-то лишнее есть...
Ответить с цитированием
  #5  
Старый 27.09.2022, 04:38
basilcat basilcat вне форума
Прохожий
 
Регистрация: 27.04.2017
Сообщения: 16
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от lmikle
Значит что-то не пишешь или не читаешь. Кстати, что такое TPointM? Указатель на структуру? Если да, то вот тут и есть ошибка, бо, как видимо, там сохраняется адрес, а не содержимое полей. Кстати, там вообще можно тогда на Access Violation налететь только так.

Вообще, это у тебя кошмар какой-то.
Нет что бы сделать нормальную иерархию классов. В каждом классе есть метод его записи и чтения (например, в поток, так лучше, чем использовать нетипизированный файл). И, соответсвенно, просто вызывается соотв. метод.
Посмотри, я вот тут:
https://delphisources.ru/forum/showt...029#post158029
постил пример модели. Там всего 2 уровня, но идея должна быть понятна. Да, кода придется написать чуточку больше, но зато будет красиво и читабельно.
Ну и вообще, поправишь модель. А то есть у меня подозрение, что у тебя там что-то лишнее есть...

Код:
PPointM=^TPointM;
	TPointM=record
		X,Y:real;
Спасибо за ответ. Посмотрю обязательно.

Последний раз редактировалось lmikle, 27.09.2022 в 04:54.
Ответить с цитированием
  #6  
Старый 27.09.2022, 04:57
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,003
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Да нет, судя по описанию записи должно быть нормально.
Но, как я уже сказал, код у тебя получается очень путанный, неудобно отлаживать. Вообще, наверное лучше переписать сохранение на алгоритм "честной" сереализации. А еще лучше, как я говорил, переделай на иерархию классов. Там код будет очень простой и прозрачный, вероятность ошибки будет минимальная.
Если не знаешь как - пиши, подскажу.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра
Комбинированный вид Комбинированный вид

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 13:27.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter