|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
#1
|
|||
|
|||
Создание точки восстановления программы написанной на Delphi
Вопрос знатокам. Возможно ли создать точку восстановления программы написанной на Delphi.
Т.е. записать в файл полное состояние программы с целью при повторном запуске приложения продолжить работу так, как будто вы не выгружались. В своём Sapr автоматизированного раскроя я сохраняю в бинаный файл те классы, которые отвечают за раскладку деталей на листе раскроя. Но есть ньюансы при чтении данных из этого бинарного файла после загрузки приложения. Раскрой воспроизводится и можно продолжить дальнейшую раскладку деталей с возможностью изменения положения ранее разложенных деталей. Но нет возможности делать откат назад и возврат, хотя он работает при самом проектировании. Возможно ли сохранить состояние программы каким то другим способом. Исходные коды Sapr мои . |
#2
|
|||
|
|||
Ну так сохраняй в бинарник историю тоже.
Теоретически, можно сохранить весь дамп памяти приложения. Вот только потом будут проблемы с восстановлением, бо как физ адреса съедут. Т.е. в твоем случае заморачиваться смысла нет, просто пиши в бинарник историю, если это действительно нужно при "восстановлении". |
#3
|
|||
|
|||
Цитата:
Торопился и не совсем правильно выразился. "я сохраняю в бинаный файл те классы, которые отвечают за раскладку деталей " имею ввиду конечно не сами классы, а записи, ссылки на которые сохраняю в этих классах ( классы 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; Код:
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; Код:
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
|
|||
|
|||
Значит что-то не пишешь или не читаешь. Кстати, что такое TPointM? Указатель на структуру? Если да, то вот тут и есть ошибка, бо, как видимо, там сохраняется адрес, а не содержимое полей. Кстати, там вообще можно тогда на Access Violation налететь только так.
Вообще, это у тебя кошмар какой-то. Нет что бы сделать нормальную иерархию классов. В каждом классе есть метод его записи и чтения (например, в поток, так лучше, чем использовать нетипизированный файл). И, соответсвенно, просто вызывается соотв. метод. Посмотри, я вот тут: https://delphisources.ru/forum/showt...029#post158029 постил пример модели. Там всего 2 уровня, но идея должна быть понятна. Да, кода придется написать чуточку больше, но зато будет красиво и читабельно. Ну и вообще, поправишь модель. А то есть у меня подозрение, что у тебя там что-то лишнее есть... |
#5
|
|||
|
|||
Цитата:
Код:
PPointM=^TPointM; TPointM=record X,Y:real; Последний раз редактировалось lmikle, 27.09.2022 в 04:54. |
#6
|
|||
|
|||
Да нет, судя по описанию записи должно быть нормально.
Но, как я уже сказал, код у тебя получается очень путанный, неудобно отлаживать. Вообще, наверное лучше переписать сохранение на алгоритм "честной" сереализации. А еще лучше, как я говорил, переделай на иерархию классов. Там код будет очень простой и прозрачный, вероятность ошибки будет минимальная. Если не знаешь как - пиши, подскажу. |