From f2cce78db24a0f0a53b8ca41ff112968a5f2d86b Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Fri, 19 Dec 2014 20:02:47 +0000 Subject: Actman 2.0 is moved to deprecated, Actman 3.0 is a new default Actman (with database settings converter from older version) git-svn-id: http://svn.miranda-ng.org/main/trunk@11533 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/Actman/i_services.inc | 304 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 245 insertions(+), 59 deletions(-) (limited to 'plugins/Actman/i_services.inc') diff --git a/plugins/Actman/i_services.inc b/plugins/Actman/i_services.inc index d835c9225a..2954fa4b15 100644 --- a/plugins/Actman/i_services.inc +++ b/plugins/Actman/i_services.inc @@ -1,5 +1,27 @@ {Basic ActMan services} +function ActSelect(wParam:WPARAM;lParam:LPARAM):int_ptr;cdecl; +begin + if odd(wParam) then + result:=int_ptr(MacroList.GetMacro(lParam)) + else + result:=int_ptr(MacroList.GetMacro(pWideChar(lParam))); + + if result<>0 then + with pMacroRecord(result)^ do + begin + if (wParam and 4)<>0 then + result:=ord((flags and ACF_SELECTED)<>0) + else + begin + if (wParam and 2)<>0 then + flags:=flags and not ACF_SELECTED + else + flags:=flags or ACF_SELECTED; + end; + end; +end; + function ActFreeList(wParam:WPARAM;lParam:LPARAM):int_ptr;cdecl; begin result:=0; @@ -9,12 +31,12 @@ end; function ActGetList(wParam:WPARAM;lParam:LPARAM):int_ptr;cdecl; var pc:^tChain; - p:pHKRecord; + p:pMacroRecord; i,cnt:integer; begin - p:=@GroupList[0]; + p:=MacroList[0]; cnt:=0; - for i:=0 to MaxGroups-1 do + for i:=0 to MacroList.Count-1 do begin if (p^.flags and (ACF_ASSIGNED or ACF_VOLATILE))=ACF_ASSIGNED then inc(cnt); inc(p); @@ -25,12 +47,11 @@ begin begin mGetMem(pc,cnt*SizeOf(tChain)+4); puint_ptr(lParam)^:=uint_ptr(pc); -// {$IFDEF WIN64}pqword{$ELSE}pdword{$ENDIF}(lParam)^:=uint_ptr(pc); pdword(pc)^:=SizeOf(tChain); inc(PByte(pc),4); - p:=@GroupList[0]; - for i:=0 to MaxGroups-1 do + p:=MacroList[0]; + for i:=0 to MacroList.Count-1 do begin if (p^.flags and (ACF_ASSIGNED or ACF_VOLATILE))=ACF_ASSIGNED then begin @@ -44,88 +65,253 @@ begin end else puint_ptr(lParam)^:=0; -// {$IFDEF WIN64}pqword{$ELSE}pdword{$ENDIF}(lParam)^:=0; end; -function ActRun(wParam:WPARAM;lParam:LPARAM):int_ptr;cdecl; +//====================== Execute code ======================= + +{$IFDEF DEBUG} +procedure ActmanMacroDebug(txt:pWideChar); +begin + OutputDebugStringW(txt); +end; +{$ENDIF} + +procedure DoAction(Macro:pMacroRecord;var WorkData:tWorkData); var - i:integer; - p:pHKRecord; + res:LRESULT; + i,cnt:integer; +{$IFDEF DEBUG} + buf:array [0..1023] of WideChar; + buf1,buf2:array [0..31] of WideChar; + p:pWideChar; +{$ENDIF} begin - result:=-1; - p:=@GroupList[0]; - for i:=0 to MaxGroups-1 do + cnt:=Macro^.ActionCount; + if cnt<>0 then begin - if ((p^.flags and ACF_ASSIGNED)<>0) and (p^.id=dword(wParam)) then +//!! act:=CloneActions(action); + i:=0; + WorkData.ActionList :=Macro^.ActionList; + WorkData.ActionCount:=Macro^.ActionCount; + while i0 then // res = next action number+1 + begin + i:=res-1; + continue; + end; + end; + inc(i); end; - inc(p); +//!! FreeActionsContinued(act_org); end; - if result>0 then - result:=ActionStarter(result,lParam,p); end; -function ActRunGroup(wParam:WPARAM;lParam:LPARAM):int_ptr;cdecl; +type + pActStartData = ^tActStartData; + tActStartData = record + macro :pMacroRecord; + event :THANDLE; + WorkData:tWorkData; + flags :dword; + end; + +procedure ThDoAction(arg:pActStartData); cdecl; var i:integer; - p:pHKRecord; begin - result:=-1; - p:=@GroupList[0]; - for i:=0 to MaxGroups-1 do + if (arg^.flags and ACTP_NOTIFY)<>0 then begin - if ((p^.flags and ACF_ASSIGNED)<>0) and (StrCmpW(p^.descr,pWideChar(wParam))=0) then - begin - result:=p^.firstAction; - break; - end; - inc(p); + NotifyEventHooks(hevaction,arg^.macro.id,0); // started + arg^.macro.flags:=arg^.macro.flags or ACF_USEDNOW; + end; + + DoAction(arg^.macro,arg^.WorkData); + + if (arg^.flags and ACTP_NOTIFY)<>0 then + begin + arg^.macro.flags:=arg^.macro.flags and not ACF_USEDNOW; + NotifyEventHooks(hevaction,arg^.macro.id,1); // finished + end; + + if arg^.event<>0 then // service, waiting + SetEvent(arg^.event) + else if (arg^.flags and ACTP_SAMETHREAD)=0 then // no waiting + begin + ClearResult(arg^.WorkData); // free last result memory if needs + // Free Storage + for i:=0 to 9 do + ClearResult(arg^.WorkData,i); + mFreeMem(arg); // free ActStartData (no time to free after) end; - if result>0 then - result:=ActionStarter(result,lParam,p); end; -function ActRunParam(wParam:WPARAM;lParam:LPARAM):int_ptr;cdecl; +function ActionStarter(macro:pMacroRecord;wd:pWorkData;flags:dword):LPARAM; var + tmp:pActStartData; i:integer; - p:pHKRecord; begin - result:=-1; - p:=@GroupList[0]; - - if (pAct_Param(lParam)^.flags and ACTP_BYNAME)=0 then + mGetMem (tmp ,SizeOf(tActStartData)); + FillChar(tmp^,SizeOf(tActStartData),0); + + if wd<>nil then begin - for i:=0 to MaxGroups-1 do - begin - if ((p^.flags and ACF_ASSIGNED)<>0) and (p^.id=pAct_Param(lParam)^.Id) then - begin - result:=p^.firstAction; - break; + tmp^.WorkData.ResultType:=wd^.ResultType; + case wd^.ResultType of + rtInt : tmp^.WorkData.LastResult:=wd^.LastResult; + rtWide: StrDupW(pWideChar(tmp^.WorkData.LastResult),pWideChar(wd^.LastResult)); + rtAnsi: begin + AnsiToWide(pAnsiChar(wd^.LastResult),pWideChar(tmp^.WorkData.LastResult)); + tmp^.WorkData.ResultType:=rtWide; + end; + rtUTF8: begin + UTF8ToWide(pAnsiChar(wd^.LastResult),pWideChar(tmp^.WorkData.LastResult)); + tmp^.WorkData.ResultType:=rtWide; end; - inc(p); end; + tmp^.WorkData.Parameter:=wd^.Parameter; end else + tmp^.WorkData.ResultType:=rtInt; + + tmp^.macro :=macro; + tmp^.flags :=flags; + + if (flags and ACTP_SAMETHREAD)<>0 then // with waiting, macro or service begin - for i:=0 to MaxGroups-1 do + tmp^.event:=0; + ThDoAction(tmp); + // keep text result (for macro from macro) + if (flags and ACTP_KEEPRESULT)<>0 then begin - if ((p^.flags and ACF_ASSIGNED)<>0) and - (StrCmpW(p^.descr,pWideChar(pAct_Param(lParam)^.Id))=0) then - begin - result:=p^.firstAction; - break; - end; - inc(p); - end; - end; + wd^.ResultType:=tmp^.WorkData.ResultType; + if wd^.ResultType=rtInt then + wd^.LastResult:=tmp^.WorkData.LastResult + else + StrDupW(pWideChar(wd^.LastResult),pWideChar(tmp^.WorkData.LastResult)); + result:=0; + end + else if tmp^.WorkData.ResultType=rtInt then + result:=tmp^.WorkData.LastResult + // result no needs or macro from service + else + result:=StrToInt(pWideChar(tmp^.WorkData.LastResult)); + end - if result>0 then + else if (flags and ACTP_WAIT)<>0 then // with waiting, service begin - if (pAct_Param(lParam)^.flags and ACTP_WAIT)=0 then - result:=ActionStarter (result,pAct_Param(lParam)^.wParam,p,pAct_Param(lParam)^.lParam) + tmp^.event:=CreateEvent(nil,FALSE,FALSE,nil); + {CloseHandle}(mir_forkthread(@ThDoAction,tmp)); + //!!!!!!!!! movetmp structure (event handle) to array, not stack? + WaitForSingleObjectEx(tmp^.event,INFINITE,true); + CloseHandle(tmp^.event); + if tmp^.WorkData.ResultType=rtWide then + result:=StrToInt(pWideChar(tmp^.WorkData.LastResult)) else - result:=ActionStarterWait(result,pAct_Param(lParam)^.wParam,p,pAct_Param(lParam)^.lParam); + result:=tmp^.WorkData.LastResult; + end + + else // no waiting, service or macro + begin + tmp^.event:=0; + {CloseHandle}(mir_forkthread(@ThDoAction,tmp)); + result:=0; + exit; + end; + + ClearResult(tmp^.WorkData); // free last result memory if needs + // Free Storage + for i:=0 to 9 do + ClearResult(tmp^.WorkData,i); + mFreeMem(tmp); // free ActStartData (no time to free after) +end; + +//----- execute services ----- + +function ActRun(wParam:WPARAM;lParam:LPARAM):int_ptr;cdecl; +var + p:pMacroRecord; + w:tWorkData; +begin + result:=-1; + p:=MacroList.GetMacro(wParam); + if p<>nil then + begin + FillChar(w,SizeOf(w),0); + w.ResultType:=rtInt; + w.Parameter:=lParam; + result:=ActionStarter(p,@w,ACTP_SAMETHREAD); + end; +end; + +function ActRunGroup(wParam:WPARAM;lParam:LPARAM):int_ptr;cdecl; +var + p:pMacroRecord; + w:tWorkData; +begin + result:=-1; + p:=MacroList.GetMacro(pWideChar(wParam)); + if p<>nil then + begin + FillChar(w,SizeOf(w),0); + w.ResultType:=rtInt; + w.Parameter:=lParam; + result:=ActionStarter(p,@w,ACTP_SAMETHREAD); + end; +end; + +function ActRunParam(wParam:WPARAM;lParam:LPARAM):int_ptr;cdecl; +var + p:pMacroRecord; + w:tWorkData; +begin + result:=-1; + if (pAct_Param(lParam)^.flags and ACTP_BYNAME)=0 then + p:=MacroList.GetMacro(pAct_Param(lParam)^.Id) + else + p:=MacroList.GetMacro(pWideChar(pAct_Param(lParam)^.Id)); + + if p<>nil then + begin + FillChar(w,SizeOf(w),0); + w.Parameter :=pAct_Param(lParam)^.wParam; + w.LastResult:=pAct_Param(lParam)^.lParam; + w.ResultType:=pAct_Param(lParam)^.lPType; + result:=ActionStarter(p,@w,pAct_Param(lParam)^.flags); + if (pAct_Param(lParam)^.flags and (ACTP_KEEPRESULT or ACTP_SAMETHREAD))= + (ACTP_KEEPRESULT or ACTP_SAMETHREAD) then + begin + pAct_Param(lParam)^.lParam:=w.LastResult; + pAct_Param(lParam)^.lPType:=w.ResultType; + end; end; end; -- cgit v1.2.3