{Save/load options} const opt_group = 'Group'; opt_actions = 'Action'; opt_numacts = 'numactions'; opt_nummacro = 'numgroups'; opt_descr = 'descr'; opt_id = 'id'; opt_uid = 'uid'; opt_flags = 'flags'; //----- Save settings ----- procedure SaveActions(Macro:pMacroRecord;section:pAnsiChar); var p,p1:PAnsiChar; i:integer; begin p:=StrEnd(section); StrCopy(p,opt_numacts); DBWriteWord(0,DBBranch,section,Macro^.ActionCount); // in: section = "Group#/" p1:=StrCopyE(p,opt_actions); // "Group#/Action" DBDeleteGroup(0,DBBranch,section); for i:=0 to Macro^.ActionCount-1 do begin p:=StrEnd(IntToStr(p1,i)); p^:='/'; inc(p); // "Group#/Action#/" //?? StrCopy(p,opt_uid); DBWriteDWord(0,DBBranch,section,Macro^.ActionList[i].uid); p^:=#0; Macro^.ActionList[i].Save(section,0); end; end; procedure SaveMacros; var Macro:pMacroRecord; NumMacro:integer; i:integer; section:array [0..127] of AnsiChar; p,p1:PAnsiChar; begin // even if crap in settings, skip on read // DBDeleteGroup(0,DBBranch,opt_group); Macro:=MacroList[0]; i:=MacroList.Count; NumMacro:=0; p1:=StrCopyE(section,opt_group); while i>0 do begin with Macro^ do begin if (flags and (ACF_ASSIGNED or ACF_VOLATILE))=ACF_ASSIGNED then begin p:=StrEnd(IntToStr(p1,NumMacro)); p^:='/'; inc(p); StrCopy(p,opt_id ); DBWriteDWord(0,DBBranch,section,id); StrCopy(p,opt_flags); DBWriteDWord(0,DBBranch,section,flags); StrCopy(p,opt_descr); DBWriteUnicode (0,DBBranch,section,descr); p^:=#0; SaveActions(Macro,section); inc(NumMacro); end; end; inc(Macro); dec(i); end; DBWriteWord(0,DBBranch,opt_nummacro,NumMacro); end; //----- Load settings ----- function LoadActions(Macro:pMacroRecord;section:pAnsiChar):integer; var p,p1:PAnsiChar; i,num:integer; actm:pActModule; action:tBaseAction; uid:dword; tmp:pActionList; begin result:=0; p:=StrEnd(section); StrCopy(p,opt_numacts); Macro^.ActionCount:=DBReadWord(0,DBBranch,section); if Macro^.ActionCount>0 then begin GetMem(Macro^.ActionList,SizeOf(tBaseAction)*Macro^.ActionCount); p1:=StrCopyE(p,opt_actions); // "Group#/Action" num:=0; for i:=0 to Macro^.ActionCount-1 do begin p:=StrEnd(IntToStr(p1,i)); p^:='/'; inc(p); // "Group#/Action#/" // get uid StrCopy(p,opt_uid); uid:=DBReadDWord(0,DBBranch,section,0); if uid<>0 then begin p^:=#0; // call proper constructor actm:=GetLink(uid); if actm=nil then continue; action:=actm.Create; // call proper loader action.Load(section,0); Macro^.ActionList^[num]:=action; inc(num); end; end; if Macro^.ActionCount<>num then begin GetMem(tmp,SizeOf(tBaseAction)*num); move(Macro^.ActionList^,tmp^,SizeOf(tBaseAction)*num); Macro^.ActionCount:=num; FreeMem(Macro^.ActionList); Macro^.ActionList:=tmp; end; end; end; procedure LoadMacros; var Macro:pMacroRecord; i:cardinal; p,p1:PAnsiChar; section:array [0..127] of AnsiChar; NumMacros:cardinal; tmp:pWideChar; begin // Allocate macro list NumMacros :=DBReadWord(0,DBBranch,opt_nummacro,0); MacroList:=tMacroList.Create(NumMacros); // read macro list settings if NumMacros>0 then //?? really, not so necessary begin Macro:=MacroList[0]; i:=0; p1:=StrCopyE(section,opt_group); while i0 then //?? not needed in normal cases begin StrCopy(p,opt_id ); id :=DBReadDWord (0,DBBranch,section); StrCopy(p,opt_descr); tmp:=DBReadUnicode(0,DBBranch,section,NoDescription); StrCopyW(descr,tmp,MacroNameLen-1); mFreeMem(tmp); p^:=#0; LoadActions(Macro,section); end; end; inc(Macro); inc(i); end; end; end;