{Save/load options} const opt_group = 'Group'; opt_actions = 'Action'; opt_numacts = 'numactions'; opt_numhk = 'numgroups'; opt_firstAction = 'firstaction'; opt_cproto = 'cproto'; opt_cuid = 'cuid'; opt_ischat = 'ischat'; opt_descr = 'descr'; opt_id = 'id'; opt_flags = 'flags'; opt_flags2 = 'flags2'; opt_time = 'time'; opt_show = 'show'; opt_action = 'action'; opt_value = 'value'; opt_file = 'file'; opt_next = 'next'; opt_type = 'type'; opt_contact = 'contact'; opt_text = 'text'; opt_prg = 'program'; opt_args = 'arguments'; opt_service = 'service'; opt_wparam = 'wparam'; opt_wlparam = 'wparamlen'; opt_llparam = 'lparamlen'; opt_lparam = 'lparam'; opt_chain = 'chain'; opt_cond = 'condition'; opt_count = 'count'; opt_module = 'module'; opt_setting = 'setting'; opt_oper = 'operation'; opt_mathval = 'mathval'; opt_operval = 'operval'; opt_varval = 'varval'; opt_msgtitle = 'msgtitle'; opt_msgtext = 'msgtext'; opt_boxopts = 'boxopts'; //----- Save settings ----- procedure SaveNumValue(setting:pAnsiChar;value:uint_ptr;isvar:boolean); begin if isvar then DBWriteUnicode(0,DBBranch,setting,pWideChar(value)) else DBWriteDWord (0,DBBranch,setting,value); end; function SaveActions(section:pAnsiChar;first:integer):integer; var p,p1:PAnsiChar; act:pHKAction; i:integer; begin result:=0; // in: section = "Group#/" p1:=StrCopyE(StrEnd(section),opt_actions); // "Group#/Action" DBDeleteGroup(0,DBBranch,section); i:=1; while first<>0 do begin act:=@ActionList[first]; p:=StrEnd(IntToStr(p1,i)); //!!! p^:='/'; inc(p); // "Group#/Action#/" StrCopy(p,opt_flags ); DBWriteDWord(0,DBBranch,section,act^.flags); StrCopy(p,opt_flags2); DBWriteDWord(0,DBBranch,section,act^.flags2); StrCopy(p,opt_type ); DBWriteByte (0,DBBranch,section,act^.actionType); if act^.descr<>nil then begin StrCopy(p,opt_descr); DBWriteUnicode(0,DBBranch,section,act^.descr); end; case act^.actionType of ACT_CONTACT: begin p^:=#0; SaveContact(act^.contact,DBBranch,section); end; ACT_SERVICE: begin StrCopy(p,opt_service); DBWriteString(0,DBBranch,section,act^.service); if (act^.flags and (ACF_WCURRENT or ACF_WRESULT or ACF_WPARAM))=0 then begin StrCopy(p,opt_wparam); if (act^.flags and ACF_WPARNUM)<>0 then SaveNumValue(section,act^.wparam,(act^.flags2 and ACF2_SRV_WPAR)<>0) // DBWriteDWord(0,DBBranch,section,act^.wparam) else if act^.wparam<>0 then begin if (act^.flags and ACF_WSTRUCT)<>0 then DBWriteUTF8(0,DBBranch,section,pAnsiChar(act^.wparam)) else if (act^.flags and ACF_WUNICODE)<>0 then DBWriteUnicode(0,DBBranch,section,pWideChar(act^.wparam)) else DBWriteString(0,DBBranch,section,PAnsiChar(act^.wparam)); end; end; if (act^.flags and (ACF_LCURRENT or ACF_LRESULT or ACF_LPARAM))=0 then begin StrCopy(p,opt_lparam); if (act^.flags and ACF_LPARNUM)<>0 then SaveNumValue(section,act^.lparam,(act^.flags2 and ACF2_SRV_LPAR)<>0) // DBWriteDWord(0,DBBranch,section,act^.lparam) else if act^.lparam<>0 then begin if (act^.flags and ACF_LSTRUCT)<>0 then DBWriteUTF8(0,DBBranch,section,pAnsiChar(act^.lparam)) else if (act^.flags and ACF_LUNICODE)<>0 then DBWriteUnicode(0,DBBranch,section,pWideChar(act^.lparam)) else DBWriteString(0,DBBranch,section,PAnsiChar(act^.lparam)); end; end; end; ACT_PROGRAM: begin StrCopy(p,opt_prg ); DBWriteUnicode(0,DBBranch,section,act^.prgname); StrCopy(p,opt_args); DBWriteUnicode(0,DBBranch,section,act^.args); StrCopy(p,opt_time); DBWriteDWord (0,DBBranch,section,act^.time); StrCopy(p,opt_show); DBWriteDWord (0,DBBranch,section,act^.show); end; ACT_TEXT: begin if (act^.flags and ACF_CLIPBRD)=0 then begin StrCopy(p,opt_text); DBWriteUnicode(0,DBBranch,section,act^.text); if (act^.flags and ACF_FILE)<>0 then begin StrCopy(p,opt_file); DBWriteUnicode(0,DBBranch,section,act^.tfile); end; end; end; ACT_ADVANCE: begin StrCopy(p,opt_cond ); DBWriteByte (0,DBBranch,section,act^.condition); StrCopy(p,opt_value ); DBWriteDWord (0,DBBranch,section,act^.value); StrCopy(p,opt_action ); DBWriteByte (0,DBBranch,section,act^.action); StrCopy(p,opt_operval); DBWriteUnicode(0,DBBranch,section,act^.operval); StrCopy(p,opt_oper ); DBWriteByte (0,DBBranch,section,act^.oper); StrCopy(p,opt_mathval); DBWriteDWord (0,DBBranch,section,act^.mathval); StrCopy(p,opt_varval ); DBWriteUnicode(0,DBBranch,section,act^.varval); end; ACT_CHAIN: begin StrCopy(p,opt_text); DBWriteDWord(0,DBBranch,section,act^.id); end; ACT_RW: begin if (act^.flags and ACF_NOCNTCT)=0 then begin p^:=#0; SaveContact(act^.dbcontact,DBBranch,section); end; StrCopy(p,opt_module ); DBWriteString(0,DBBranch,section,act^.dbmodule); StrCopy(p,opt_setting); DBWriteString(0,DBBranch,section,act^.dbsetting); StrCopy(p,opt_value ); if (act^.flags and ACF_DBUTEXT)=0 then begin SaveNumValue(section,act^.dbvalue,(act^.flags2 and ACF2_RW_TVAR)<>0); // DBWriteDWord(0,DBBranch,section,act^.dbvalue) end else DBWriteUnicode(0,DBBranch,section,pWideChar(act^.dbvalue)); end; ACT_MESSAGE: begin StrCopy(p,opt_msgtitle); DBWriteUnicode(0,DBBranch,section,act^.msgtitle); StrCopy(p,opt_msgtext ); DBWriteUnicode(0,DBBranch,section,act^.msgtext); StrCopy(p,opt_boxopts ); DBWriteByte (0,DBBranch,section,act^.boxopts); //!! end; end; inc(result); inc(i); first:=ActionList^[first].next; end; end; procedure SaveGroups; var HK:pHKRecord; NumHK:integer; i,num:integer; section:array [0..127] of AnsiChar; p,p1:PAnsiChar; Actions:integer; begin // even if crap in settings, skip on read // DBDeleteGroup(0,DBBranch,opt_group); HK:=@GroupList^; i:=MaxGroups; NumHK:=0; Actions:=1; DBWriteUnicode(0,DBBranch,'CLformat',fCLformat); DBWriteByte (0,DBBranch,'CLfilter',ord(fCLfilter)); p1:=StrCopyE(section,opt_group); while i>0 do begin with HK^ do begin if (flags and (ACF_ASSIGNED or ACF_VOLATILE))=ACF_ASSIGNED then begin p:=StrEnd(IntToStr(p1,NumHK)); 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); if descr<>nil then DBWriteUnicode (0,DBBranch,section,descr) else DBDeleteSetting(0,DBBranch,section); p^:=#0; //?? num:=SaveActions(section,firstAction); StrCopy(p,opt_numacts); DBWriteWord(0,DBBranch,section,num); inc(Actions,num); inc(NumHK); end; end; inc(HK); dec(i); end; DBWriteWord(0,DBBranch,opt_numhk ,NumHK); DBWriteWord(0,DBBranch,opt_numacts,Actions-1); end; //----- Load settings ----- function LoadNumValue(setting:pAnsiChar;isvar:boolean):uint_ptr; begin if isvar then result:=uint_ptr(DBReadUnicode(0,DBBranch,setting,nil)) else result:=DBReadDWord(0,DBBranch,setting); end; function LoadActions(section:pAnsiChar;count:integer):integer; var p,p1:PAnsiChar; act:tHKAction; i,num,oldnum:integer; begin result:=0; p1:=StrCopyE(StrEnd(section),opt_actions); // "Group#/Action" oldnum:=0; for i:=1 to count do begin p:=StrEnd(IntToStr(p1,i)); p^:='/'; inc(p); // "Group#/Action#/" FillChar(act,SizeOf(act),0); StrCopy(p,opt_flags ); act.flags :=DBReadDWord (0,DBBranch,section,0); if (act.flags and ACF_ASSIGNED)<>0 then begin StrCopy(p,opt_flags2); act.flags2 :=DBReadDWord (0,DBBranch,section,0); StrCopy(p,opt_descr ); act.descr :=DBReadUnicode(0,DBBranch,section,nil); StrCopy(p,opt_type ); act.actionType:=DBReadByte (0,DBBranch,section,ACT_CONTACT); case act.actionType of ACT_CONTACT: begin p^:=#0; act.contact:=LoadContact(DBBranch,section); end; ACT_SERVICE: begin StrCopy(p,opt_service); act.service:=DBReadString(0,DBBranch,section,nil); if (act.flags and (ACF_WCURRENT or ACF_WRESULT or ACF_WPARAM))=0 then begin StrCopy(p,opt_wparam); if (act.flags and ACF_WPARNUM)<>0 then act.wparam:=LoadNumValue(section,(act.flags2 and ACF2_SRV_WPAR)<>0) else if (act.flags and ACF_WSTRUCT)<>0 then act.wparam:=wparam(DBReadUTF8(0,DBBranch,section,nil)) else if (act.flags and ACF_WUNICODE)<>0 then act.wparam:=wparam(DBReadUnicode(0,DBBranch,section,nil)) else act.wparam:=wparam(DBReadString (0,DBBranch,section,nil)); end; if (act.flags and (ACF_LCURRENT or ACF_LRESULT or ACF_LPARAM))=0 then begin StrCopy(p,opt_lparam); if (act.flags and ACF_LPARNUM)<>0 then act.lparam:=LoadNumValue(section,(act.flags2 and ACF2_SRV_LPAR)<>0) // act.lparam:=DBReadDWord(0,DBBranch,section,0) else if (act.flags and ACF_LSTRUCT)<>0 then act.lparam:=lparam(DBReadUTF8(0,DBBranch,section,nil)) else if (act.flags and ACF_LUNICODE)<>0 then act.lparam:=lparam(DBReadUnicode(0,DBBranch,section,nil)) else act.lparam:=lparam(DBReadString(0,DBBranch,section,nil)); end; end; ACT_PROGRAM: begin StrCopy(p,opt_prg ); act.prgname:=DBReadUnicode(0,DBBranch,section,nil); StrCopy(p,opt_args); act.args :=DBReadUnicode(0,DBBranch,section,nil); StrCopy(p,opt_time); act.time :=DBReadDWord (0,DBBranch,section,0); StrCopy(p,opt_show); act.show :=DBReadDWord (0,DBBranch,section,SW_SHOW); end; ACT_TEXT: begin if (act.flags and ACF_CLIPBRD)=0 then begin StrCopy(p,opt_text); act.text:=DBReadUnicode(0,DBBranch,section,nil); if (act.flags and ACF_FILE)<>0 then begin StrCopy(p,opt_file); act.tfile:=DBReadUnicode(0,DBBranch,section,nil); end; end; end; ACT_ADVANCE: begin StrCopy(p,opt_cond ); act.condition:=DBReadByte (0,DBBranch,section); StrCopy(p,opt_value ); act.value :=DBReadDWord (0,DBBranch,section); StrCopy(p,opt_action ); act.action :=DBReadByte (0,DBBranch,section); StrCopy(p,opt_oper ); act.oper :=DBReadByte (0,DBBranch,section); StrCopy(p,opt_mathval); act.mathval :=DBReadDWord (0,DBBranch,section); StrCopy(p,opt_operval); act.operval :=DBReadUnicode(0,DBBranch,section); StrCopy(p,opt_varval ); act.varval :=DBReadUnicode(0,DBBranch,section); end; ACT_CHAIN: begin StrCopy(p,opt_text); act.id:=DBReadDWord(0,DBBranch,section); end; ACT_RW: begin if (act.flags and ACF_NOCNTCT)=0 then begin p^:=#0; act.dbcontact:=LoadContact(DBBranch,section); end; StrCopy(p,opt_module ); act.dbmodule :=DBReadString(0,DBBranch,section); StrCopy(p,opt_setting); act.dbsetting:=DBReadString(0,DBBranch,section); StrCopy(p,opt_value ); if (act.flags and ACF_DBUTEXT)=0 then act.dbvalue:=LoadNumValue(section,(act.flags2 and ACF2_RW_TVAR)<>0) else act.dbvalue:=uint_ptr(DBReadUnicode(0,DBBranch,section)); end; ACT_MESSAGE: begin StrCopy(p,opt_msgtitle); act.msgtitle:=DBReadUnicode(0,DBBranch,section); StrCopy(p,opt_msgtext ); act.msgtext :=DBReadUnicode(0,DBBranch,section); StrCopy(p,opt_boxopts ); act.boxopts :=DBReadByte (0,DBBranch,section); end; end; num:=NewAction(ActionList,MaxActions); move(act,ActionList^[num],SizeOf(tHKAction)); if i=1 then result:=num else ActionList^[oldnum].next:=num; oldnum:=num; end; end; end; procedure LoadGroups; var HK:pHKRecord; i,num:cardinal; p,p1:PAnsiChar; section:array [0..127] of AnsiChar; NumGroups,NumActions:cardinal; begin { remove doubling - no need? (called just once) if MaxGroups>0 then begin while MaxGroups>0 do begin FreeGroup(MaxGroups); dec(MaxGroups); end; FreeMem(GroupList); end; } NumGroups:=DBReadWord(0,DBBranch,opt_numhk,HKListPage); if NumGroups0 then begin act:=@ActionList[1]; while MaxActions>0 do begin FreeAction(act); inc(act); dec(MaxActions); end; FreeMem(ActionList); end; } NumActions:=DBReadWord(0,DBBranch,opt_numacts,ActListPage); if NumActions0 then // not needed in normal cases begin StrCopy(p,opt_id ); id :=DBReadDWord (0,DBBranch,section); StrCopy(p,opt_descr); descr:=DBReadUnicode(0,DBBranch,section,nil); if descr=nil then StrDupW(descr,TranslateW('No description')); StrCopy(p,opt_numacts); num:=DBReadWord(0,DBBranch,section); p^:=#0; firstAction:=LoadActions(section,num); end; end; inc(HK); inc(i); end; fCLfilter:=DBReadByte (0,DBBranch,'CLfilter',0)<>0; fCLformat:=DBReadUnicode(0,DBBranch,'CLformat'); end;