summaryrefslogtreecommitdiff
path: root/plugins/Actman
diff options
context:
space:
mode:
authorVadim Dashevskiy <watcherhd@gmail.com>2012-10-08 18:43:29 +0000
committerVadim Dashevskiy <watcherhd@gmail.com>2012-10-08 18:43:29 +0000
commit864081102a5f252415f41950b3039a896b4ae9c5 (patch)
treec6b764651e9dd1f8f53b98eab05f16ba4a492a79 /plugins/Actman
parentdb5149b48346c417e18add5702a9dfe7f6e28dd0 (diff)
Awkwars's plugins - welcome to our trunk
git-svn-id: http://svn.miranda-ng.org/main/trunk@1822 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/Actman')
-rw-r--r--plugins/Actman/actman.dpr189
-rw-r--r--plugins/Actman/global.pas21
-rw-r--r--plugins/Actman/hooks/hooks.pas73
-rw-r--r--plugins/Actman/hooks/hooks.rc28
-rw-r--r--plugins/Actman/hooks/hooks.resbin0 -> 688 bytes
-rw-r--r--plugins/Actman/hooks/i_hconst.inc20
-rw-r--r--plugins/Actman/hooks/i_hook.inc154
-rw-r--r--plugins/Actman/hooks/i_opt_dlg.inc410
-rw-r--r--plugins/Actman/hooks/i_options.inc71
-rw-r--r--plugins/Actman/i_action.inc952
-rw-r--r--plugins/Actman/i_actlow.inc836
-rw-r--r--plugins/Actman/i_const.inc219
-rw-r--r--plugins/Actman/i_contact.inc113
-rw-r--r--plugins/Actman/i_dlglists.inc75
-rw-r--r--plugins/Actman/i_inoutxm.inc1180
-rw-r--r--plugins/Actman/i_opt_dlg.inc215
-rw-r--r--plugins/Actman/i_opt_dlg2.inc2109
-rw-r--r--plugins/Actman/i_options.inc459
-rw-r--r--plugins/Actman/i_services.inc131
-rw-r--r--plugins/Actman/i_vars.inc31
-rw-r--r--plugins/Actman/i_visual.inc1073
-rw-r--r--plugins/Actman/ico/advance.icobin0 -> 2550 bytes
-rw-r--r--plugins/Actman/ico/apply.icobin0 -> 1406 bytes
-rw-r--r--plugins/Actman/ico/chain.icobin0 -> 2550 bytes
-rw-r--r--plugins/Actman/ico/contact.icobin0 -> 2550 bytes
-rw-r--r--plugins/Actman/ico/delete.icobin0 -> 2550 bytes
-rw-r--r--plugins/Actman/ico/down.icobin0 -> 2550 bytes
-rw-r--r--plugins/Actman/ico/export.icobin0 -> 2550 bytes
-rw-r--r--plugins/Actman/ico/format.icobin0 -> 2550 bytes
-rw-r--r--plugins/Actman/ico/import.icobin0 -> 2550 bytes
-rw-r--r--plugins/Actman/ico/insert.icobin0 -> 2550 bytes
-rw-r--r--plugins/Actman/ico/message.icobin0 -> 2550 bytes
-rw-r--r--plugins/Actman/ico/new.icobin0 -> 2550 bytes
-rw-r--r--plugins/Actman/ico/program.icobin0 -> 2550 bytes
-rw-r--r--plugins/Actman/ico/reload.icobin0 -> 2550 bytes
-rw-r--r--plugins/Actman/ico/rw.icobin0 -> 2550 bytes
-rw-r--r--plugins/Actman/ico/service.icobin0 -> 2550 bytes
-rw-r--r--plugins/Actman/ico/test.icobin0 -> 2550 bytes
-rw-r--r--plugins/Actman/ico/up.icobin0 -> 2550 bytes
-rw-r--r--plugins/Actman/ico/vcheck.icobin0 -> 350 bytes
-rw-r--r--plugins/Actman/ico/vuncheck.icobin0 -> 350 bytes
-rw-r--r--plugins/Actman/m_actions.inc193
-rw-r--r--plugins/Actman/m_actman.h96
-rw-r--r--plugins/Actman/m_actman.inc158
-rw-r--r--plugins/Actman/make.bat20
-rw-r--r--plugins/Actman/options.rc328
-rw-r--r--plugins/Actman/options.resbin0 -> 55904 bytes
-rw-r--r--plugins/Actman/question.pas51
-rw-r--r--plugins/Actman/readme.txt126
-rw-r--r--plugins/Actman/services.ini497
-rw-r--r--plugins/Actman/tasks/i_opt_dlg.inc536
-rw-r--r--plugins/Actman/tasks/i_options.inc99
-rw-r--r--plugins/Actman/tasks/i_service.inc87
-rw-r--r--plugins/Actman/tasks/i_task.inc242
-rw-r--r--plugins/Actman/tasks/i_tconst.inc27
-rw-r--r--plugins/Actman/tasks/scheduler.pas86
-rw-r--r--plugins/Actman/tasks/tasks.rc47
-rw-r--r--plugins/Actman/tasks/tasks.resbin0 -> 1288 bytes
-rw-r--r--plugins/Actman/ua/action.icobin0 -> 2550 bytes
-rw-r--r--plugins/Actman/ua/i_inoutxm.inc357
-rw-r--r--plugins/Actman/ua/i_opt_dlg.inc571
-rw-r--r--plugins/Actman/ua/i_options.inc337
-rw-r--r--plugins/Actman/ua/i_ua.inc155
-rw-r--r--plugins/Actman/ua/i_uaplaces.inc831
-rw-r--r--plugins/Actman/ua/i_uavars.inc124
-rw-r--r--plugins/Actman/ua/i_uconst.inc34
-rw-r--r--plugins/Actman/ua/ua.pas124
-rw-r--r--plugins/Actman/ua/ua.rc51
-rw-r--r--plugins/Actman/ua/ua.resbin0 -> 3944 bytes
69 files changed, 13536 insertions, 0 deletions
diff --git a/plugins/Actman/actman.dpr b/plugins/Actman/actman.dpr
new file mode 100644
index 0000000000..caf0319c6a
--- /dev/null
+++ b/plugins/Actman/actman.dpr
@@ -0,0 +1,189 @@
+{$include compilers.inc}
+{$IFDEF COMPILER_16_UP}
+ {$WEAKLINKRTTI ON}
+ {.$RTTI EXPLICIT METHODS([]) PROPERTIES([]) FIELDS([])}
+{$ENDIF}
+{$IMAGEBASE $13200000}
+library actman;
+{%ToDo 'actman.todo'}
+{%File 'i_actlow.inc'}
+{%File 'm_actions.inc'}
+{%File 'm_actman.inc'}
+{%File 'i_action.inc'}
+{%File 'i_const.inc'}
+{%File 'i_contact.inc'}
+{%File 'i_opt_dlg2.inc'}
+{%File 'i_opt_dlg.inc'}
+{%File 'i_visual.inc'}
+{%File 'i_options.inc'}
+{%File 'i_services.inc'}
+{%File 'i_vars.inc'}
+{%File 'i_inoutxm.inc'}
+{%File 'tasks\i_opt_dlg.inc'}
+{%File 'tasks\i_options.inc'}
+{%File 'tasks\i_task.inc'}
+{%File 'hooks\i_options.inc'}
+{%File 'hooks\i_hook.inc'}
+{%File 'hooks\i_opt_dlg.inc'}
+{%File 'ua\i_opt_dlg.inc'}
+{%File 'ua\i_inoutxm.inc'}
+{%File 'ua\i_options.inc'}
+{%File 'ua\i_ua.inc'}
+{%File 'ua\i_uaplaces.inc'}
+{%File 'ua\i_uconst.inc'}
+
+uses
+ m_api,
+ Windows,
+ messages,
+ commctrl,
+ common,
+ wrapper,
+ io,
+ dbsettings,
+ mirutils,
+ syswin,
+ base64,
+ question,
+ mApiCardM,
+ global,
+ sedit,
+ strans,
+ ua in 'ua\ua.pas',
+ hooks in 'hooks\hooks.pas',
+ scheduler in 'tasks\scheduler.pas';
+
+{$r options.res}
+
+const
+ PluginName = 'Action Manager';
+var
+ hHookShutdown,
+ onloadhook,
+ opthook:cardinal;
+ hevaction,hHookChanged,hevinout:cardinal;
+ hsel,hinout,hfree,hget,hrun,hrung,hrunp:cardinal;
+
+{$include m_actions.inc}
+{$include m_actman.inc}
+
+
+function MirandaPluginInfoEx(mirandaVersion:DWORD):PPLUGININFOEX; cdecl;
+begin
+ result:=@PluginInfo;
+ PluginInfo.cbSize :=SizeOf(TPLUGININFOEX);
+ PluginInfo.shortName :='Action manager';
+ PluginInfo.version :=$00020001;
+ PluginInfo.description:='Plugin for manage hotkeys to open contact window, insert text, '+
+ 'run program and call services';
+ PluginInfo.author :='Awkward';
+ PluginInfo.authorEmail:='panda75@bk.ru; awk1975@ya.ru';
+ PluginInfo.copyright :='(c) 2007-2012 Awkward';
+ PluginInfo.homepage :='http://code.google.com/p/delphi-miranda-plugins/';
+ PluginInfo.flags :=UNICODE_AWARE;
+ PluginInfo.uuid :=MIID_ACTMAN;
+end;
+
+{$include i_const.inc}
+{$include i_vars.inc}
+
+{$include i_action.inc}
+{$include i_actlow.inc}
+{$include i_options.inc}
+{$include i_contact.inc}
+{$include i_opt_dlg.inc}
+{$include i_inoutxm.inc}
+{$include i_services.inc}
+
+function PreShutdown(wParam:WPARAM;lParam:LPARAM):int;cdecl;
+var
+ ptr:pActionLink;
+begin
+ result:=0;
+
+ ptr:=ActionLink;
+ while ptr<>nil do
+ begin
+ if @ptr^.DeInit<>nil then
+ ptr^.DeInit;
+ ptr:=ptr^.Next;
+ end;
+
+ FreeGroups;
+
+ UnhookEvent(hHookShutdown);
+ UnhookEvent(opthook);
+
+ DestroyHookableEvent(hHookChanged);
+ DestroyHookableEvent(hevinout);
+ DestroyHookableEvent(hevaction);
+
+ DestroyServiceFunction(hfree);
+ DestroyServiceFunction(hget);
+ DestroyServiceFunction(hrun);
+ DestroyServiceFunction(hrung);
+ DestroyServiceFunction(hrunp);
+ DestroyServiceFunction(hinout);
+ DestroyServiceFunction(hsel);
+end;
+
+function OnModulesLoaded(wParam:WPARAM;lParam:LPARAM):int;cdecl;
+var
+ ptr:pActionLink;
+begin
+ Result:=0;
+ UnhookEvent(onloadhook);
+
+ LoadGroups;
+ RegisterIcons;
+
+ opthook :=HookEvent(ME_OPT_INITIALISE ,@OnOptInitialise);
+ hHookShutdown:=HookEvent(ME_SYSTEM_SHUTDOWN{ME_SYSTEM_OKTOEXIT},@PreShutdown);
+ NotifyEventHooks(hHookChanged,twparam(ACTM_LOADED),0);
+
+ //----- DBEDITOR support -----
+// CallService('DBEditorpp/RegisterSingleModule',dword(PluginShort),0);
+
+ IsMultiThread:=true;
+ // Load additional modules
+ ptr:=ActionLink;
+ while ptr<>nil do
+ begin
+ if @ptr^.Init<>nil then
+ ptr^.Init;
+ ptr:=ptr^.Next;
+ end;
+
+ CallService(MS_ACT_RUNBYNAME,TWPARAM(AutoStartName),0);
+end;
+
+function Load():int; cdecl;
+begin
+ Result:=0;
+ Langpack_register;
+
+ hHookChanged:=CreateHookableEvent(ME_ACT_CHANGED);
+ hevinout :=CreateHookableEvent(ME_ACT_INOUT);
+ hevaction :=CreateHookableEvent(ME_ACT_ACTION);
+
+ hfree :=CreateServiceFunction(MS_ACT_FREELIST ,@ActFreeList);
+ hget :=CreateServiceFunction(MS_ACT_GETLIST ,@ActGetList);
+ hrun :=CreateServiceFunction(MS_ACT_RUNBYID ,@ActRun);
+ hrung :=CreateServiceFunction(MS_ACT_RUNBYNAME,@ActRunGroup);
+ hrunp :=CreateServiceFunction(MS_ACT_RUNPARAMS,@ActRunParam);
+ hinout:=CreateServiceFunction(MS_ACT_INOUT ,@ActInOut);
+ hsel :=CreateServiceFunction(MS_ACT_SELECT ,@ActSelect);
+
+ onloadhook:=HookEvent(ME_SYSTEM_MODULESLOADED,@OnModulesLoaded);
+end;
+
+function Unload: int; cdecl;
+begin
+ Result:=0;
+end;
+
+exports
+ Load, Unload,
+ MirandaPluginInfoEx;
+
+end.
diff --git a/plugins/Actman/global.pas b/plugins/Actman/global.pas
new file mode 100644
index 0000000000..50254b383e
--- /dev/null
+++ b/plugins/Actman/global.pas
@@ -0,0 +1,21 @@
+unit global;
+
+interface
+
+type
+ tAddOption = function(var tmpl:pAnsiChar;var proc:pointer;var name:PAnsiChar):integer;
+type
+ pActionLink=^tActionLink;
+ tActionLink=record
+ Next :pActionLink;
+ Init :procedure;
+ DeInit :procedure;
+ AddOption:tAddOption;
+ end;
+
+const
+ ActionLink:pActionLink=nil;
+
+implementation
+
+end. \ No newline at end of file
diff --git a/plugins/Actman/hooks/hooks.pas b/plugins/Actman/hooks/hooks.pas
new file mode 100644
index 0000000000..b3309c327a
--- /dev/null
+++ b/plugins/Actman/hooks/hooks.pas
@@ -0,0 +1,73 @@
+unit hooks;
+
+interface
+
+procedure Init;
+procedure DeInit;
+function AddOptionPage(var tmpl:pAnsiChar;var proc:pointer;var name:PAnsiChar):integer;
+
+implementation
+
+uses
+ windows, commctrl, messages,
+ mirutils, common, dbsettings, io, m_api, wrapper,
+ global, mApiCardM;
+
+{$R hooks.res}
+
+{$include m_actman.inc}
+
+{$include i_hook.inc}
+{$include i_hconst.inc}
+{$include i_options.inc}
+{$include i_opt_dlg.inc}
+
+// ------------ base interface functions -------------
+
+procedure Init;
+begin
+
+ MessageWindow:=CreateWindowExW(0,'STATIC',nil,0,1,1,1,1,HWND_MESSAGE,0,hInstance,nil);
+ if MessageWindow<>0 then
+ SetWindowLongPtrW(MessageWindow,GWL_WNDPROC,LONG_PTR(@HookWndProc));
+
+ if LoadHooks=0 then
+ begin
+ MaxHooks:=8;
+ GetMem (HookList ,MaxHooks*SizeOf(tHookRec));
+ FillChar(HookList^,MaxHooks*SizeOf(tHookRec),0);
+ end
+ else
+ SetAllHooks;
+end;
+
+procedure DeInit;
+begin
+ ClearHooks;
+ if MessageWindow<>0 then
+ DestroyWindow(MessageWindow);
+end;
+
+function AddOptionPage(var tmpl:pAnsiChar;var proc:pointer;var name:PAnsiChar):integer;
+begin
+ result:=0;
+ tmpl:=PAnsiChar(IDD_HOOKS);
+ proc:=@DlgProcOpt;
+ name:='Hooks';
+end;
+
+var
+ amLink:tActionLink;
+
+procedure InitLink;
+begin
+ amLink.Next :=ActionLink;
+ amLink.Init :=@Init;
+ amLink.DeInit :=@DeInit;
+ amLink.AddOption:=@AddOptionPage;
+ ActionLink :=@amLink;
+end;
+
+initialization
+ InitLink;
+end.
diff --git a/plugins/Actman/hooks/hooks.rc b/plugins/Actman/hooks/hooks.rc
new file mode 100644
index 0000000000..ff351cc94d
--- /dev/null
+++ b/plugins/Actman/hooks/hooks.rc
@@ -0,0 +1,28 @@
+#include "i_hconst.inc"
+
+LANGUAGE 0,0
+
+IDD_HOOKS DIALOGEX 0, 0, 304, 226, 0
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_VISIBLE
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0
+{
+ CONTROL "", IDC_HOOKLIST, "SysListView32",
+ WS_BORDER | WS_TABSTOP |
+ LVS_SHOWSELALWAYS| LVS_REPORT | LVS_EDITLABELS,// | LVS_SINGLESEL
+ 0, 2, 280, 160, WS_EX_CONTROLPARENT
+
+ CONTROL "Help" ,IDC_EVENT_HELP ,"MButtonClass",WS_TABSTOP,284, 2,16,16,$18000000
+ CONTROL "Delete",IDC_HOOK_DELETE,"MButtonClass",WS_TABSTOP,284, 96,16,16,$18000000
+
+ CONTROL "New" ,IDC_HOOK_NEW ,"MButtonClass",WS_TABSTOP,284,126,16,16,$18000000
+ CONTROL "Apply" ,IDC_HOOK_APPLY ,"MButtonClass",WS_TABSTOP,284,146,16,16,$18000000
+
+ CONTROL "Help" ,IDC_EVENT_CHELP,"MButtonClass",WS_TABSTOP,2 ,162,16,16,$18000000
+ CTEXT "Event" ,-1 ,18, 165, 121, 11, SS_CENTERIMAGE
+ COMBOBOX IDC_EVENTLIST , 0, 178, 157, 128, CBS_DROPDOWN | CBS_SORT | WS_VSCROLL
+ CTEXT "Action",-1 , 0, 195, 157, 11, SS_CENTERIMAGE
+ COMBOBOX IDC_ACTIONLIST, 0, 208, 157, 128, CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL
+
+ LTEXT "",IDC_DESCR, 160, 165, 138, 57
+}
diff --git a/plugins/Actman/hooks/hooks.res b/plugins/Actman/hooks/hooks.res
new file mode 100644
index 0000000000..1cf202f414
--- /dev/null
+++ b/plugins/Actman/hooks/hooks.res
Binary files differ
diff --git a/plugins/Actman/hooks/i_hconst.inc b/plugins/Actman/hooks/i_hconst.inc
new file mode 100644
index 0000000000..d011278b7e
--- /dev/null
+++ b/plugins/Actman/hooks/i_hconst.inc
@@ -0,0 +1,20 @@
+{resource constants}
+const
+ // dialogs
+ IDD_HOOKS = 1029;
+
+ // icons
+ IDI_NEW = 1025;
+ IDI_DELETE = 1028;
+
+ // Hook editor
+ IDC_HOOKLIST = 1025;
+ IDC_ACTIONLIST = 1026;
+ IDC_EVENTLIST = 1027;
+ IDC_EVENT_HELP = 1028;
+ IDC_HOOK_NEW = 1029;
+ IDC_HOOK_DELETE = 1030;
+ IDC_HOOK_APPLY = 1031;
+ IDC_EVENT_CHELP = 1032;
+
+ IDC_DESCR = 1040;
diff --git a/plugins/Actman/hooks/i_hook.inc b/plugins/Actman/hooks/i_hook.inc
new file mode 100644
index 0000000000..8b7b487d98
--- /dev/null
+++ b/plugins/Actman/hooks/i_hook.inc
@@ -0,0 +1,154 @@
+{}
+
+const
+ HWND_MESSAGE = HWND(-3);
+const
+ ACF_ASSIGNED = $80000000; // hook assigned
+ ACF_DISABLED = $10000000; // hook disabled
+const
+ WM_RESETHOOKS = WM_USER+1312;
+ WM_FIRSTHOOK = WM_USER+1313;
+ WM_LASTHOOK = WM_FIRSTHOOK+1000;
+
+type
+ pHookRec = ^tHookRec;
+ tHookRec = record
+ flags :dword;
+ name :PAnsiChar; // name for hook
+ handle :THANDLE; // handle of hook
+ descr :PWideChar; // name for list
+ action :dword; // assigned action
+ message:uint; // window message for hook
+ end;
+ pHookList = ^tHookList;
+ tHookList = array [0..1023] of tHookRec;
+
+var
+ HookList:pHookList = nil;
+ MaxHooks:integer = 0;
+ MessageWindow:HWND = 0;
+
+function GetNextMessage:uint;
+var
+ i:uint;
+ j:integer;
+begin
+ result:=0;
+ for i:=WM_FIRSTHOOK to WM_LASTHOOK do
+ begin
+ for j:=0 to MaxHooks-1 do
+ begin
+ with HookList^[j] do
+ begin
+ if ((flags and ACF_ASSIGNED)<>0) and (i=message) then
+ begin
+ inc(result);
+ break;
+ end;
+ end;
+ end;
+ if result=0 then
+ begin
+ result:=i;
+ break;
+ end
+ else
+ result:=0;
+ end;
+end;
+
+procedure SetAllHooks;
+var
+ i:integer;
+ msg:cardinal;
+begin
+ msg:=WM_FIRSTHOOK;
+ for i:=0 to MaxHooks-1 do
+ begin
+ with HookList[i] do
+ begin
+ message:=msg;
+ if (flags and ACF_ASSIGNED)<>0 then
+ begin
+ if (flags and ACF_DISABLED)<>0 then
+ begin
+ if handle<>0 then
+ begin
+ UnhookEvent(handle);
+ handle:=0;
+ end;
+ end
+ else
+ begin
+ if handle<>0 then
+ UnhookEvent(handle);
+ handle:=HookEventMessage(name,MessageWindow,message);
+ end;
+ end;
+ end;
+ inc(msg);
+ end;
+end;
+
+function GetHookByMessage(msg:uint):pHookRec;
+var
+ i:integer;
+begin
+ result:=nil;
+ for i:=0 to MaxHooks-1 do
+ begin
+ with HookList[i] do
+ begin
+ if ((flags and ACF_ASSIGNED)<>0) and (msg=message) then
+ begin
+ result:=@HookList[i];
+ break;
+ end;
+ end;
+ end;
+end;
+
+function HookWndProc(Dialog:HWnd;hMessage:UINT;wParam:WPARAM;lParam:LPARAM):lresult; stdcall;
+var
+ p:pHookRec;
+ ap:tAct_Param;
+begin
+ result:=0;
+ case hMessage of
+ WM_FIRSTHOOK..WM_LASTHOOK: begin
+ p:=GetHookByMessage(hMessage);
+ if p<>nil then
+ begin
+ ap.flags :=ACTP_WAIT;
+ ap.Id :=p^.action;
+ ap.wParam:=wParam;
+ ap.lParam:=lParam;
+ result:=CallService(MS_ACT_RUNPARAMS,0,TLPARAM(@ap));
+ end;
+ end;
+ else
+ result:=DefWindowProc(Dialog,hMessage,wParam,lParam);
+ end;
+end;
+
+procedure ClearHooks;
+var
+ i:integer;
+begin
+ for i:=0 to MaxHooks-1 do
+ begin
+ with HookList[i] do
+ begin
+ if (flags and ACF_ASSIGNED)<>0 then
+ begin
+ mFreeMem(descr);
+ mFreeMem(name);
+ if handle<>0 then
+ UnhookEvent(handle);
+ end;
+ end;
+ end;
+ FreeMem(HookList);
+ MaxHooks:=0;
+end;
+
diff --git a/plugins/Actman/hooks/i_opt_dlg.inc b/plugins/Actman/hooks/i_opt_dlg.inc
new file mode 100644
index 0000000000..d208ec4384
--- /dev/null
+++ b/plugins/Actman/hooks/i_opt_dlg.inc
@@ -0,0 +1,410 @@
+{}
+const
+ settings:HWND = 0;
+var
+ OldTableProc:pointer;
+ onactchanged:THANDLE;
+ ApiCard:tmApiCard;
+
+const
+ ACI_NEW :PAnsiChar = 'ACI_New';
+ ACI_APPLY :PAnsiChar = 'ACI_Apply';
+ ACI_DELETE :PAnsiChar = 'ACI_Delete';
+
+procedure CheckHookList(wnd:HWND);
+var
+ i:integer;
+ li:LV_ITEMW;
+ arr:array [0..127] of WideChar;
+begin
+ ClearHooks;
+
+ li.mask :=LVIF_TEXT or LVIF_PARAM;
+ li.pszText :=@arr;
+ li.cchTextMax:=SizeOf(arr) div SizeOf(WideChar);
+
+ MaxHooks:=SendMessage(wnd,LVM_GETITEMCOUNT,0,0);
+
+ GetMem (HookList ,MaxHooks*SizeOf(tHookRec));
+ FillChar(HookList^,MaxHooks*SizeOf(tHookRec),0);
+ for i:=0 to MaxHooks-1 do
+ begin
+ with HookList[i] do
+ begin
+ flags:=ACF_ASSIGNED;
+ li.iItem :=i;
+ li.iSubItem:=0;
+ SendMessageW(wnd,LVM_GETITEMW,0,LPARAM(@li));
+ StrDupW(descr,arr);
+ action:=li.lParam;
+ li.iSubItem:=1;
+ SendMessageA(wnd,LVM_GETITEMA,0,LPARAM(@li));
+ StrDup(name,pAnsiChar(@arr));
+
+ if ListView_GetCheckState(wnd,i)=0 then // disabled
+ flags:=flags or ACF_DISABLED;
+ end;
+ end;
+end;
+
+procedure FillHookList(wnd:HWND);
+var
+ i:integer;
+ li:LV_ITEMW;
+begin
+ SendMessage(wnd,LVM_DELETEALLITEMS,0,0);
+ for i:=0 to MaxHooks-1 do
+ begin
+ with HookList[i] do
+ begin
+ if (flags and ACF_ASSIGNED)<>0 then
+ begin
+ li.mask :=LVIF_TEXT+LVIF_PARAM;
+ li.iSubItem:=0;
+ li.iItem :=i;
+ li.lParam :=action;
+ li.pszText :=descr;
+ li.iItem :=SendMessageW(wnd,LVM_INSERTITEMW,0,LPARAM(@li));
+ li.mask :=LVIF_TEXT;
+ li.iSubItem:=1;
+ li.pszText :=pWideChar(name);
+ SendMessageA(wnd,LVM_SETITEMA,0,LPARAM(@li));
+ ListView_SetCheckState(wnd,li.iItem,(flags and ACF_DISABLED)=0);
+ end;
+ end;
+ end;
+ ListView_SetItemState(wnd,0,
+ LVIS_FOCUSED or LVIS_SELECTED,
+ LVIS_FOCUSED or LVIS_SELECTED);
+end;
+
+procedure FillActionList(wnd:HWND);
+var
+ ptr,ptr1:pChain;
+ i,cnt:integer;
+begin
+ cnt:=CallService(MS_ACT_GETLIST,0,LPARAM(@ptr));
+ SendMessage(wnd,CB_RESETCONTENT,0,0);
+ if cnt>0 then
+ begin
+ ptr1:=ptr;
+ inc(pbyte(ptr),4);
+ for i:=0 to cnt-1 do
+ begin
+ CB_AddStrDataW(wnd,ptr^.descr,ptr^.id);
+ inc(ptr);
+ end;
+
+ CallService(MS_ACT_FREELIST,0,LPARAM(ptr1));
+ SendMessage(wnd,CB_SETCURSEL,0,0);
+ end;
+end;
+
+function ActListChange(wParam:WPARAM;lParam:LPARAM):integer; cdecl;
+begin
+ result:=0;
+ if settings<>0 then
+ FillActionList(GetDlgItem(settings,IDC_ACTIONLIST));
+end;
+
+procedure ShowHookData(Dialog:HWND; item:integer=-1);
+var
+ li:LV_ITEM;
+ arr:array [0..127] of WideChar;
+ wnd:HWND;
+begin
+ wnd:=GetDlgItem(Dialog,IDC_HOOKLIST);
+ if item<0 then
+ li.iItem:=SendMessage(wnd,LVM_GETNEXTITEM,-1,LVNI_FOCUSED)
+ else
+ li.iItem:=item;
+
+ li.mask :=LVIF_TEXT+LVIF_PARAM;
+ li.iSubItem :=1;
+ li.pszText :=@arr;
+ li.cchTextMax:=SizeOf(arr) div SizeOf(WideChar);
+ arr[0]:=#0;
+ SendMessageW(wnd,LVM_GETITEMW,0,LPARAM(@li));
+ if arr[0]<>#0 then
+ SetDlgItemTextW(Dialog,IDC_EVENTLIST,arr);
+ CB_SelectData(GetDlgItem(Dialog,IDC_ACTIONLIST),li.lParam);
+end;
+
+procedure SaveHookData(Dialog:HWND; item:integer=-1);
+var
+ wnd:HWND;
+ li:LV_ITEM;
+begin
+ wnd:=GetDlgItem(Dialog,IDC_HOOKLIST);
+ if item<0 then
+ li.iItem:=SendMessage(wnd,LVM_GETNEXTITEM,-1,LVNI_FOCUSED)
+ else
+ li.iItem:=item;
+ li.mask :=LVIF_PARAM;
+ li.lParam :=CB_GetData(GetDlgItem(Dialog,IDC_ACTIONLIST));
+ li.iSubItem :=0;
+ SendMessageW(wnd,LVM_SETITEMW,0,LPARAM(@li));
+ li.mask :=LVIF_TEXT;
+ li.iSubItem :=1;
+ li.pszText :=GetDlgText(Dialog,IDC_EVENTLIST);
+ SendMessageW(wnd,LVM_SETITEMW,0,LPARAM(@li));
+ mFreeMem(li.pszText);
+end;
+
+function NewHook(Dialog:HWND;item:integer=-1):integer;
+var
+ wnd:HWND;
+ li:LV_ITEMW;
+begin
+ wnd:=GetDlgItem(Dialog,IDC_HOOKLIST);
+ li.mask :=LVIF_TEXT;
+ if item<0 then
+ li.iItem :=SendMessage(wnd,LVM_GETNEXTITEM,-1,LVNI_FOCUSED)+1
+ else
+ li.iItem :=item;
+ li.iSubItem:=0;
+ li.pszText :=TranslateW('hook sample');
+ result:=SendMessageW(wnd,LVM_INSERTITEMW,0,LPARAM(@li));
+end;
+
+function DeleteHook(Dialog:HWND):integer;
+var
+ wnd:HWND;
+ i:integer;
+begin
+ result:=0;
+ wnd:=GetDlgItem(Dialog,IDC_HOOKLIST);
+ for i:=ListView_GetItemCount(wnd)-1 downto 0 do
+ begin
+ if ListView_GetItemState(wnd,i,LVIS_SELECTED)<>0 then
+ SendMessage(wnd,LVM_DELETEITEM,i,0);
+ end;
+ Listview_SetItemState(wnd,0,LVIS_FOCUSED or LVIS_SELECTED,
+ LVIS_FOCUSED or LVIS_SELECTED);
+end;
+
+function NewHKTableProc(Dialog:HWnd;hMessage:UINT;wParam:WPARAM;lParam:LPARAM):lresult; stdcall;
+var
+ i:integer;
+begin
+ result:=0;
+ case hMessage of
+ WM_KEYDOWN: begin
+ if (lParam and (1 shl 30))=0 then
+ begin
+ case wParam of
+ VK_F2: begin
+ i:=SendMessage(Dialog,LVM_GETNEXTITEM,-1,LVNI_FOCUSED);
+ if i>=0 then
+ PostMessageW(Dialog,LVM_EDITLABELW,i,0);
+ exit;
+ end;
+ VK_INSERT: begin
+ PostMessage(GetParent(Dialog),WM_COMMAND,(BN_CLICKED shl 16)+IDC_HOOK_NEW,0);
+ exit;
+ end;
+ VK_DELETE: begin
+ PostMessage(GetParent(Dialog),WM_COMMAND,(BN_CLICKED shl 16)+IDC_HOOK_DELETE,0);
+ exit;
+ end;
+ end;
+ end;
+ end;
+ end;
+ result:=CallWindowProc(OldTableProc,Dialog,hMessage,wParam,lParam);
+end;
+
+procedure SetIcons(Dialog:HWND);
+var
+ ti:TTOOLINFOW;
+ hwndTooltip:HWND;
+begin
+ hwndTooltip:=CreateWindowW(TOOLTIPS_CLASS,nil,TTS_ALWAYSTIP,
+ integer(CW_USEDEFAULT),integer(CW_USEDEFAULT),
+ integer(CW_USEDEFAULT),integer(CW_USEDEFAULT),
+ Dialog,0,hInstance,nil);
+
+ FillChar(ti,SizeOf(ti),0);
+ ti.cbSize :=sizeof(TOOLINFO);
+ ti.uFlags :=TTF_IDISHWND or TTF_SUBCLASS;
+ ti.hwnd :=dialog;
+ ti.hinst :=hInstance;
+
+ ti.lpszText:=TranslateW('Help');
+ ti.uId :=GetDlgItem(Dialog,IDC_EVENT_HELP);
+ SendMessage(ti.uId,BM_SETIMAGE,IMAGE_ICON,
+ CallService(MS_SKIN_LOADICON,SKINICON_OTHER_HELP,0));
+ SendMessageW(hwndTooltip,TTM_ADDTOOLW,0,LPARAM(@ti));
+ ti.uId :=GetDlgItem(Dialog,IDC_EVENT_CHELP);
+ SendMessage(ti.uId,BM_SETIMAGE,IMAGE_ICON,
+ CallService(MS_SKIN_LOADICON,SKINICON_OTHER_HELP,0));
+ SendMessageW(hwndTooltip,TTM_ADDTOOLW,0,LPARAM(@ti));
+
+ ti.uId :=GetDlgItem(Dialog,IDC_HOOK_NEW);
+ ti.lpszText:=TranslateW('New');
+ SetButtonIcon(ti.uId,ACI_NEW);
+ SendMessageW(hwndTooltip,TTM_ADDTOOLW,0,LPARAM(@ti));
+ ti.uId :=GetDlgItem(Dialog,IDC_HOOK_APPLY);
+ ti.lpszText:=TranslateW('Apply');
+ SetButtonIcon(ti.uId,ACI_APPLY);
+ SendMessageW(hwndTooltip,TTM_ADDTOOLW,0,LPARAM(@ti));
+ ti.uId :=GetDlgItem(Dialog,IDC_HOOK_DELETE);
+ ti.lpszText:=TranslateW('Delete');
+ SetButtonIcon(ti.uId,ACI_DELETE);
+ SendMessageW(hwndTooltip,TTM_ADDTOOLW,0,LPARAM(@ti));
+end;
+
+function DlgProcOpt(Dialog:HWnd;hMessage:UINT;wParam:WPARAM;lParam:LPARAM):lresult; stdcall;
+var
+ wnd:HWND;
+ lv:LV_COLUMNW;
+ i:integer;
+ tmp:pAnsiChar;
+ buf:array [0..255] of AnsiChar;
+begin
+ result:=0;
+ case hMessage of
+ WM_CLOSE: begin
+ ApiCard.Free;
+
+ UnhookEvent(onactchanged);
+ settings:=0;
+ end;
+
+ WM_INITDIALOG: begin
+ ApiCard:=CreateEventCard(Dialog);
+
+ wnd:=GetDlgItem(Dialog,IDC_HOOKLIST);
+ SendMessage(wnd,LVM_SETUNICODEFORMAT,1,0);
+ FillChar(lv,SizeOf(lv),0);
+ lv.mask :=LVCF_TEXT or LVCF_WIDTH;
+ lv.pszText:=TranslateW('Description');
+ lv.cx :=110;
+ SendMessageW(wnd,LVM_INSERTCOLUMNW ,0,TLPARAM(@lv));
+ lv.pszText:=TranslateW('Name');
+ lv.cx :=110;
+ SendMessageW(wnd,LVM_INSERTCOLUMNW ,1,TLPARAM(@lv));
+ SendMessageW(wnd,LVM_SETCOLUMNWIDTH,1,LVSCW_AUTOSIZE_USEHEADER);
+// SendMessage (wnd,LVM_SETEXTENDEDLISTVIEWSTYLE,LVS_EX_CHECKBOXES,LVS_EX_CHECKBOXES);
+ SendMessage (wnd,LVM_SETEXTENDEDLISTVIEWSTYLE,0,
+ LVS_EX_FULLROWSELECT or LVS_EX_CHECKBOXES or LVS_EX_GRIDLINES);
+ SendMessage(wnd,LVM_SETUNICODEFORMAT,1,0);
+ OldTableProc:=pointer(SetWindowLongPtrW(wnd,GWL_WNDPROC,LONG_PTR(@NewHKTableProc)));
+ TranslateDialogDefault(Dialog);
+
+ SetIcons(Dialog);
+
+ ApiCard.FillList(GetDlgItem(Dialog,IDC_EVENTLIST));
+ FillActionList(GetDlgItem(Dialog,IDC_ACTIONLIST));
+ FillHookList(wnd);
+ ShowHookData(Dialog);
+
+ onactchanged:=HookEvent(ME_ACT_CHANGED,@ActListChange);
+ settings:=Dialog;
+ end;
+
+ WM_HELP: begin
+ ApiCard.Show;
+ end;
+
+ WM_RESETHOOKS:begin
+ FillHookList(GetDlgItem(Dialog,IDC_HOOKLIST));
+ end;
+
+ WM_COMMAND: begin
+ case wParam shr 16 of
+ EN_CHANGE,
+ CBN_EDITCHANGE,
+ CBN_SELCHANGE: begin
+ SendMessage(GetParent(Dialog),PSM_CHANGED,0,0);
+ end;
+ end;
+
+ case wParam shr 16 of
+ CBN_EDITCHANGE: begin
+ case loword(wParam) of
+ IDC_EVENTLIST: begin
+ tmp :=GetDlgText(Dialog,IDC_EVENTLIST,true);
+ ApiCard.Event:=tmp;
+ mFreeMem(tmp);
+ tmp:=ApiCard.Description;
+ SetDlgItemTextA(Dialog,IDC_DESCR,Translate(tmp));
+ mFreeMem(tmp);
+ end;
+ end;
+ end;
+
+ CBN_SELENDOK: begin
+ case loword(wParam) of
+ IDC_EVENTLIST: begin
+ i:=SendMessage(LOWORD(lParam),CB_GETCURSEL,0,0);
+ SendMessageA(LOWORD(lParam),CB_GETLBTEXT,i,TLPARAM(@buf));
+ ApiCard.Event:=@buf;
+ tmp:=ApiCard.Description;
+ SetDlgItemTextA(Dialog,IDC_DESCR,Translate(tmp));
+ mFreeMem(tmp);
+ end;
+ end;
+ SendMessage(GetParent(Dialog),PSM_CHANGED,0,0);
+ end;
+
+ BN_CLICKED: begin
+ case loword(wParam) of
+ IDC_EVENT_CHELP: ;
+ IDC_EVENT_HELP : ;
+ IDC_HOOK_NEW : NewHook(Dialog);
+ IDC_HOOK_DELETE: DeleteHook(Dialog);
+ IDC_HOOK_APPLY : SaveHookData(Dialog);
+ end;
+ end;
+ end;
+ end;
+
+ WM_NOTIFY: begin
+ case integer(PNMHdr(lParam)^.code) of
+ PSN_APPLY: begin
+ SaveHookData(Dialog);
+ CheckHookList(GetDlgItem(Dialog,IDC_HOOKLIST));
+ SetAllHooks;
+ SaveHooks;
+ end;
+
+ NM_DBLCLK: begin
+ if PNMListView(lParam)^.iItem>=0 then
+ PostMessageW(PNMHdr(lParam)^.hWndFrom,LVM_EDITLABELW,
+ PNMListView(lParam)^.iItem,0);
+ end;
+
+ LVN_ENDLABELEDITW: begin
+ with PLVDISPINFOW(lParam)^ do
+ begin
+ if item.pszText<>nil then
+ begin
+ item.mask:=LVIF_TEXT;
+ SendMessageW(hdr.hWndFrom,LVM_SETITEMW,0,TLPARAM(@item));
+ end;
+ end;
+ result:=1;
+ end;
+
+ LVN_ITEMCHANGED: begin
+ if PNMLISTVIEW(lParam)^.uChanged=LVIF_STATE then
+ begin
+ i:=(PNMLISTVIEW(lParam)^.uOldState and LVNI_FOCUSED)-
+ (PNMLISTVIEW(lParam)^.uNewState and LVNI_FOCUSED);
+
+ if i>0 then // old focus
+ SaveHookData(Dialog,PNMLISTVIEW(lParam)^.iItem)
+ else if i<0 then // new focus
+ begin
+ ShowHookData(Dialog,PNMLISTVIEW(lParam)^.iItem);
+ end
+ else if (settings<>0) and
+ ((PNMLISTVIEW(lParam)^.uOldState or PNMLISTVIEW(lParam)^.uNewState)=$3000) then
+ SendMessage(GetParent(Dialog),PSM_CHANGED,0,0);
+ end;
+ end;
+ end;
+ end;
+ end;
+end;
diff --git a/plugins/Actman/hooks/i_options.inc b/plugins/Actman/hooks/i_options.inc
new file mode 100644
index 0000000000..4404cfbde6
--- /dev/null
+++ b/plugins/Actman/hooks/i_options.inc
@@ -0,0 +1,71 @@
+{}
+const
+ opt_hook :PAnsiChar = 'Hook';
+ opt_hooks :PAnsiChar = 'Hooks';
+ opt_count :PAnsiChar = 'numhooks';
+ opt_flags :PAnsiChar = 'flags';
+ opt_descr :PAnsiChar = 'descr';
+ opt_name :PAnsiChar = 'name';
+ opt_action:PAnsiChar = 'action';
+
+procedure SaveHooks;
+var
+ section:array [0..63] of AnsiChar;
+ p,p1:PAnsiChar;
+ i,amount:integer;
+begin
+ DBDeleteGroup(0,DBBranch,opt_hooks);
+ amount:=0;
+ p1:=StrCopyE(section,opt_hooks);
+ p1^:='/'; inc(p1);
+ p1:=StrCopyE(p1,opt_hook);
+ for i:=0 to MaxHooks-1 do
+ begin
+ if (HookList[i].flags and ACF_ASSIGNED)=0 then
+ continue;
+
+ p:=StrEnd(IntToStr(p1,amount));
+ p^:='/'; inc(p);
+
+ with HookList[i] do
+ begin
+ StrCopy(p,opt_flags ); DBWriteDWord (0,DBBranch,section,flags);
+ StrCopy(p,opt_descr ); DBWriteUnicode(0,DBBranch,section,descr);
+ StrCopy(p,opt_name ); DBWriteString (0,DBBranch,section,name);
+ StrCopy(p,opt_action); DBWriteDWord (0,DBBranch,section,action);
+ end;
+ inc(amount);
+ end;
+ DBWriteByte(0,DBBranch,opt_count,amount);
+end;
+
+function LoadHooks:integer;
+var
+ section:array [0..63] of AnsiChar;
+ p,p1:PAnsiChar;
+ i:integer;
+begin
+ MaxHooks:=DBReadByte(0,DBBranch,opt_count);
+ result:=MaxHooks;
+ if MaxHooks>0 then
+ begin
+ GetMem (HookList ,MaxHooks*SizeOf(tHookRec));
+ FillChar(HookList^,MaxHooks*SizeOf(tHookRec),0);
+ p1:=StrCopyE(section,opt_hooks);
+ p1^:='/'; inc(p1);
+ p1:=StrCopyE(p1,opt_hook);
+ for i:=0 to MaxHooks-1 do
+ begin
+ p:=StrEnd(IntToStr(p1,i));
+ p^:='/'; inc(p);
+
+ with HookList[i] do
+ begin
+ StrCopy(p,opt_flags ); flags :=DBReadDWord (0,DBBranch,section);
+ StrCopy(p,opt_descr ); descr :=DBReadUnicode(0,DBBranch,section);
+ StrCopy(p,opt_name ); name :=DBReadString (0,DBBranch,section);
+ StrCopy(p,opt_action); action:=DBReadDWord (0,DBBranch,section);
+ end;
+ end;
+ end;
+end;
diff --git a/plugins/Actman/i_action.inc b/plugins/Actman/i_action.inc
new file mode 100644
index 0000000000..1dd9719d35
--- /dev/null
+++ b/plugins/Actman/i_action.inc
@@ -0,0 +1,952 @@
+{Action code}
+const
+ rtInt = 1;
+ rtWide = 2;
+
+const
+ SST_BYTE = 0;
+ SST_WORD = 1;
+ SST_DWORD = 2;
+ SST_QWORD = 3;
+ SST_NATIVE = 4;
+ SST_BARR = 5;
+ SST_WARR = 6;
+ SST_BPTR = 7;
+ SST_WPTR = 8;
+ SST_LAST = 9;
+ SST_PARAM = 10;
+
+const
+ protostr = '<proto>';
+
+const
+ BufferSize = 8192;
+
+function DBRW(act:pHKAction;hContact:THANDLE;avalue:uint_ptr;
+ last,restype:uint_ptr):uint_ptr;
+var
+ buf ,buf1 :array [0..127] of AnsiChar;
+ sbuf:array [0..127] of AnsiChar;
+ module,setting:pAnsiChar;
+ tmp:pWideChar;
+ tmpa,tmpa1:pAnsichar;
+begin
+ module :=act^.dbmodule;
+ setting:=act^.dbsetting;
+
+ with act^ do
+ begin
+ if restype=rtWide then
+ FastWideToAnsiBuf(pWideChar(last),@sbuf)
+ else
+ IntToStr(sbuf,last);
+
+ if (flags2 and ACF2_RW_MVAR)<>0 then module :=ParseVarString(module ,hContact,sbuf);
+ if (flags2 and ACF2_RW_SVAR)<>0 then setting:=ParseVarString(setting,hContact,sbuf);
+ StrCopy(buf,module);
+ StrReplace(buf,protostr,GetContactProtoAcc(hContact));
+
+ StrReplace(buf,'<last>',sbuf);
+ StrCopy(buf1,setting);
+ StrReplace(buf1,'<last>',sbuf);
+
+ if (flags2 and ACF2_RW_TVAR)<>0 then
+ pWideChar(avalue):=ParseVarString(pWideChar(avalue),hContact,@sbuf);
+
+ if ((flags and ACF_DBUTEXT)=0) and
+ ((flags2 and ACF2_RW_TVAR)<>0) then
+ begin
+ tmp:=pWideChar(avalue);
+ avalue:=StrToInt(tmp);
+ mFreeMem(tmp);
+ end;
+
+ if (flags and ACF_DBDELETE)<>0 then
+ begin
+ result:=DBDeleteSetting(hContact,buf,setting);
+ end
+ else if (flags and ACF_DBWRITE)<>0 then
+ begin
+ if (flags and ACF_DBANSI)=ACF_DBANSI then
+ begin
+ WideToAnsi(pWideChar(avalue),tmpa,MirandaCP);
+ DBWriteString(hContact,buf,buf1,tmpa);
+ mFreeMem(tmpa);
+ if (flags2 and ACF2_RW_TVAR)=0 then
+ StrDupW(pWideChar(avalue),pWideChar(avalue));
+ end
+ else if (flags and ACF_DBBYTE )=ACF_DBBYTE then DBWriteByte(hContact,buf,setting,avalue)
+ else if (flags and ACF_DBWORD )=ACF_DBWORD then DBWriteWord(hContact,buf,setting,avalue)
+ else if (flags and ACF_DBUTEXT)=ACF_DBUTEXT then
+ begin
+ DBWriteUnicode(hContact,buf,buf1,pWideChar(avalue));
+ if (flags2 and ACF2_RW_TVAR)=0 then
+ StrDupW(pWideChar(avalue),pWideChar(avalue));
+ end
+ else DBWriteDWord(hContact,buf,setting,avalue);
+
+ result:=avalue;
+ end
+ else
+ begin
+ if (flags and ACF_DBANSI)=ACF_DBANSI then
+ begin
+ WideToAnsi(pWideChar(avalue),tmpa1,MirandaCP);
+ tmpa:=DBReadString(hContact,buf,buf1,tmpa1);
+ AnsiToWide(tmpa,PWideChar(result),MirandaCP);
+ mFreeMem(tmpa1);
+ mFreeMem(tmpa);
+
+ if (flags2 and ACF2_RW_TVAR)<>0 then
+ mFreeMem(avalue);
+ end
+ else if (flags and ACF_DBBYTE )=ACF_DBBYTE then result:=DBReadByte(hContact,buf,setting,avalue)
+ else if (flags and ACF_DBWORD )=ACF_DBWORD then result:=DBReadWord(hContact,buf,setting,avalue)
+ else if (flags and ACF_DBUTEXT)=ACF_DBUTEXT then
+ begin
+ result:=uint_ptr(DBReadUnicode(hContact,buf,buf1,pWideChar(avalue)));
+ if (flags2 and ACF2_RW_TVAR)<>0 then
+ mFreeMem(avalue);
+ end
+ else result:=DBReadDWord(hContact,buf,setting,avalue);
+
+ end;
+ if (flags2 and ACF2_RW_MVAR)<>0 then mFreeMem(module);
+ if (flags2 and ACF2_RW_SVAR)<>0 then mFreeMem(setting);
+ end;
+end;
+
+function OpenContact(hContact:THANDLE):THANDLE;
+begin
+ ShowContactDialog(hContact);
+{
+ if CallService(MS_DB_CONTACT_IS,hContact,0)<>0 then
+ begin
+ if ServiceExists(MS_MSG_CONVERS)<>0 then
+ begin
+ CallService(MS_MSG_CONVERS,hContact,0)
+ end
+ else
+ CallService(MS_MSG_SENDMESSAGE,hContact,0)
+ end;
+}
+ result:=hContact;
+end;
+
+function replany(var str:pWideChar;aparam:LPARAM;alast:pWideChar):boolean;
+var
+ buf:array [0..31] of WideChar;
+ tmp:pWideChar;
+begin
+ if StrScanW(str,'<')<>nil then
+ begin
+ result:=true;
+ mGetMem(tmp,2048);
+ StrCopyW(tmp,str);
+ StrReplaceW(tmp,'<param>',IntToStr(buf,aparam));
+ StrReplaceW(tmp,'<last>' ,alast);
+
+ str:=tmp;
+ end
+ else
+ result:=false;
+end;
+
+function RunProgram(act:pHKAction;aparam:LPARAM;alast:pWideChar):dword;
+var
+ tmp,tmpp,lpath:PWideChar;
+ replPrg ,replArg :PWideChar;
+ replPrg1,replArg1:PWideChar;
+ pd:LPARAM;
+ vars1,vars2,prgs,argss:boolean;
+begin
+ with act^ do
+ begin
+
+ replPrg:=prgname;
+ prgs :=replany(replPrg,aparam,alast);
+
+ replArg:=args;
+ argss :=replany(replArg,aparam,alast);
+
+ if ((flags2 and ACF2_PRG_PRG)<>0) or
+ ((flags2 and ACF2_PRG_ARG)<>0) then
+ begin
+ pd:=WndToContact(WaitFocusedWndChild(GetForegroundwindow){GetFocus});
+ if (pd=0) and (CallService(MS_DB_CONTACT_IS,aparam,0)<>0) then
+ pd:=aparam;
+ end;
+
+ if (flags2 and ACF2_PRG_ARG)<>0 then
+ begin
+ vars2:=true;
+ tmp :=ParseVarString(replArg,pd,alast);
+ end
+ else
+ begin
+ vars2:=false;
+ tmp :=replArg;
+ end;
+
+ if (flags2 and ACF2_PRG_PRG)<>0 then
+ begin
+ vars1:=true;
+ tmpp :=ParseVarString(replPrg,pd,alast);
+ end
+ else
+ begin
+ vars1:=false;
+ tmpp:=replPrg;
+ end;
+
+ if StrScanW(tmpp,'%')<>nil then
+ begin
+ mGetMem(replPrg1,8192*SizeOf(WideChar));
+ ExpandEnvironmentStringsW(tmpp,replPrg1,8191);
+ if vars1 then mFreeMem(tmpp);
+ if prgs then mFreeMem(replPrg);
+ tmpp :=replPrg1;
+ prgs :=false;
+ vars1:=true;
+ end;
+ if StrScanW(tmp,'%')<>nil then
+ begin
+ mGetMem(replArg1,8192*SizeOf(WideChar));
+ ExpandEnvironmentStringsW(tmp,replArg1,8191);
+ if vars2 then mFreeMem(tmp);
+ if argss then mFreeMem(replArg);
+ tmp :=replArg1;
+ argss:=false;
+ vars2:=true;
+ end;
+
+ if (flags and ACF_CURPATH)=0 then
+ lpath:=ExtractW(tmpp,false)
+ else
+ lpath:=nil;
+
+ if (flags and ACF_PRTHREAD)<>0 then
+ time:=0
+ else if time=0 then
+ time:=INFINITE;
+ result:=ExecuteWaitW(tmpp,tmp,lpath,show,time,@pd);
+
+ if vars2 then mFreeMem(tmp);
+ if vars1 then mFreeMem(tmpp);
+
+ if prgs then mFreeMem(replPrg);
+ if argss then mFreeMem(replArg);
+ end;
+ mFreeMem(lpath);
+end;
+{
+function MakeStructure(txt:pWideChar;aparam,alast:LPARAM;
+ var code,alen:integer;var ofs:int_ptr; restype:integer=rtInt):pointer; forward;
+procedure FreeStructure(var struct;descr:pWideChar); forward;
+}
+function RunService(act:pHKAction;LastResult,Param:LPARAM;var restype:dword):uint_ptr;
+var
+ res:int_ptr;
+ buf:array [0..255] of AnsiChar;
+ cc:integer;
+ lservice:pAnsiChar;
+ lwparam,llparam:LPARAM;
+ tmp1,tmp2:pWideChar;
+ code,len:integer;
+begin
+ result:=uint_ptr(-1);
+
+ lservice:=act^.service;
+ lwparam :=act^.wparam;
+ llparam :=act^.lparam;
+ with act^ do
+ begin
+ if (flags2 and ACF2_SRV_SRVC)<>0 then
+ lservice:=ParseVarString(lservice,Param);
+
+ StrCopy(buf,lservice);
+ if StrPos(lservice,protostr)<>nil then
+ if CallService(MS_DB_CONTACT_IS,Param,0)=0 then
+ begin
+ if (flags2 and ACF2_SRV_SRVC)<>0 then
+ mFreeMem(lservice);
+ exit
+ end
+ else
+ StrReplace(buf,protostr,GetContactProtoAcc(Param));
+
+ if ServiceExists(buf)<>0 then
+ begin
+
+ cc:=-1;
+
+ tmp1:=nil;
+ tmp2:=nil;
+ code:=-1;
+ if (flags and ACF_WSTRUCT)<>0 then
+ begin
+ lwparam:=twParam(MakeStructure(pAnsiChar(lwparam),Param,LastResult,restype))
+ end
+ else if (flags and ACF_WPARAM)<>0 then
+ begin
+ lwparam:=Param;
+ end
+ else if (flags and ACF_WRESULT)<>0 then
+ begin
+ lwparam:=LastResult;
+ end
+ else if (flags and ACF_WCURRENT)<>0 then
+ begin
+ cc:=WndToContact(WaitFocusedWndChild(GetForegroundwindow){GetFocus});
+ lwparam:=cc;
+ end
+ else if (flags2 and ACF2_SRV_WPAR)<>0 then
+ begin
+ if (flags and ACF_WPARNUM)=0 then
+ begin
+ if (flags and ACF_WUNICODE)=0 then
+ lwparam:=uint_ptr(ParseVarString(pAnsiChar(lwparam),Param))
+ else
+ lwparam:=uint_ptr(ParseVarString(pWideChar(lwparam),Param))
+ end
+ else
+ begin
+ tmp1:=ParseVarString(pWideChar(lwparam),Param);
+ lwparam:=StrToInt(tmp1);
+ end;
+ end;
+
+ if (flags and ACF_LSTRUCT)<>0 then
+ begin
+ llparam:=tlParam(MakeStructure(pAnsiChar(llparam),Param,LastResult,restype))
+ end
+ else if (flags and ACF_LPARAM)<>0 then
+ begin
+ llparam:=Param;
+ end
+ else if (flags and ACF_LRESULT)<>0 then
+ begin
+ llparam:=LastResult;
+ end
+ else if (flags and ACF_LCURRENT)<>0 then
+ begin
+ if cc<>-1 then
+ llparam:=cc
+ else
+ llparam:=WndToContact(WaitFocusedWndChild(GetForegroundwindow){GetFocus});
+ end
+ else if (flags2 and ACF2_SRV_LPAR)<>0 then
+ begin
+ if (flags and ACF_LPARNUM)=0 then
+ begin
+ if (flags and ACF_LUNICODE)=0 then
+ llparam:=uint_ptr(ParseVarString(pAnsiChar(llparam),Param))
+ else
+ llparam:=uint_ptr(ParseVarString(pWideChar(llparam),Param))
+ end
+ else
+ begin
+ tmp2:=ParseVarString(pWideChar(llparam),Param);
+ llparam:=StrToInt(tmp2);
+ end;
+ end;
+
+ res:=CallServiceSync(buf,lwparam,llparam);
+ result:=res;
+ if (flags and ACF_STRING)<>0 then
+ begin
+//!! delete old or not?
+ if (flags and ACF_UNICODE)=0 then
+ begin
+ AnsiToWide(pAnsiChar(res),pWideChar(result),MirandaCP);
+ if (flags2 and ACF2_FREEMEM)<>0 then
+ mFreeMem(pAnsiChar(res));
+ end
+ else if (flags2 and ACF2_FREEMEM)=0 then
+ StrDupW(pWideChar(result),pWideChar(res));
+ restype:=rtWide;
+ end
+ else if (flags and ACF_STRUCT)=0 then
+ restype:=rtInt;
+
+ if (flags and ACF_WSTRUCT)<>0 then
+ begin
+ if (flags and ACF_STRUCT)<>0 then
+ begin
+ result:=GetStructureResult(lwparam,@code,@len);
+ case code of
+ SST_LAST: begin
+ result:=LastResult;
+ end;
+ SST_PARAM: begin
+ result:=Param;
+ restype:=rtInt;
+ end;
+ SST_BYTE,SST_WORD,SST_DWORD,
+ SST_QWORD,SST_NATIVE: begin
+ restype:=rtInt;
+ end;
+ SST_BARR: begin
+{
+ mGetMem(pAnsiChar(res),len+1);
+ StrCopy(pAnsiChar(res),pAnsiChar(ofs),len);
+}
+ StrDup(pAnsiChar(res),pAnsiChar(result),len);
+ AnsiToWide(pAnsiChar(res),PWideChar(result),MirandaCP);
+ mFreeMem(pAnsiChar(res));
+ restype:=rtWide;
+ end;
+ SST_WARR: begin
+{
+ mGetMem(pWideChar(result),len+2);
+ len:= len div 2;
+ StrCopyW(pWideChar(result),pWideChar(ofs),len);
+}
+ StrDupW(pWideChar(result),pWideChar(result),len);
+ restype:=rtWide;
+ end;
+ SST_BPTR: begin
+ AnsiToWide(pAnsiChar(result),pWideChar(result),MirandaCP);
+ restype:=rtWide;
+ end;
+ SST_WPTR: begin
+ StrDupW(pWideChar(result),pWideChar(result));
+ restype:=rtWide;
+ end;
+ end;
+ end;
+ code:=SST_UNKNOWN;
+ FreeStructure(lwparam);
+ res:=result;
+ end
+ else if (flags2 and ACF2_SRV_WPAR)<>0 then
+ begin
+ if (flags and ACF_LPARNUM)=0 then
+ mFreeMem(pAnsiChar(lwparam))
+ else
+ mFreeMem(tmp1);
+ end;
+
+ if (flags and ACF_LSTRUCT)<>0 then
+ begin
+ if (flags and ACF_STRUCT)<>0 then
+ begin
+ result:=GetStructureResult(llparam,@code,@len);
+ case code of
+ SST_LAST: begin
+ result:=LastResult;
+ end;
+ SST_PARAM: begin
+ result:=Param;
+ restype:=rtInt;
+ end;
+ SST_BYTE,SST_WORD,SST_DWORD,
+ SST_QWORD,SST_NATIVE: begin
+ restype:=rtInt;
+ end;
+ SST_BARR: begin
+{
+ mGetMem(pAnsiChar(res),len+1);
+ StrCopy(pAnsiChar(res),pAnsiChar(ofs),len);
+}
+ StrDup(pAnsiChar(res),pAnsiChar(result),len);
+ AnsiToWide(pAnsiChar(res),PWideChar(result),MirandaCP);
+ mFreeMem(pAnsiChar(res));
+ restype:=rtWide;
+ end;
+ SST_WARR: begin
+{
+ mGetMem(pWideChar(result),len+2);
+ len:= len div 2;
+ StrCopyW(pWideChar(result),pWideChar(ofs),len);
+}
+ StrDupW(pWideChar(result),pWideChar(result),len);
+ restype:=rtWide;
+ end;
+ SST_BPTR: begin
+ AnsiToWide(pAnsiChar(result),pWideChar(result),MirandaCP);
+ restype:=rtWide;
+ end;
+ SST_WPTR: begin
+ StrDupW(pWideChar(result),pWideChar(result));
+ restype:=rtWide;
+ end;
+ end;
+ end;
+ code:=SST_UNKNOWN;
+ FreeStructure(llparam);
+ res:=result;
+ end
+ else if (flags2 and ACF2_SRV_LPAR)<>0 then
+ begin
+ if (flags and ACF_LPARNUM)=0 then
+ mFreeMem(pAnsiChar(llparam))
+ else
+ mFreeMem(tmp2);
+ end;
+
+ if (flags and (ACF_INSERT or ACF_MESSAGE or ACF_POPUP))<>0 then
+ begin
+ if restype=rtInt then
+ begin
+ if (flags and ACF_HEX)<>0 then
+ IntToHex(pWideChar(@buf),result)
+ else if ((flags and ACF_SIGNED)<>0) and (res<0) then
+ begin
+ pWideChar(@buf)[0]:='-';
+ IntToStr(PWideChar(@buf)+1,-result);
+ end
+ else
+ IntToStr(pWideChar(@buf),result);
+ res:=int_ptr(@buf);
+ end
+ else
+ res:=result;
+ end;
+
+ if (flags and ACF_INSERT )<>0 then SendMessageW(WaitFocusedWndChild(GetForegroundwindow){GetFocus},EM_REPLACESEL,0,res);
+ if (flags and ACF_POPUP )<>0 then ShowPopupW(PWideChar(res));
+ if (flags and ACF_MESSAGE)<>0 then MessageBoxW(0,PWideChar(res),'',0);
+
+ end;
+ if (flags2 and ACF2_SRV_SRVC)<>0 then
+ mFreeMem(lservice);
+ end;
+end;
+
+procedure PasteClipboard(dst:pWideChar);
+var
+ p:pWideChar;
+ fh:tHandle;
+begin
+ if StrPosW(dst,'^v')<>nil then
+ begin
+{
+ p:=PasteFromClipboard(false);
+ StrReplaceW(dst,'^v',p);
+ mFreeMem(p);
+}
+ if OpenClipboard(0) then
+ begin
+ fh:=GetClipboardData(cf_UnicodeText);
+ p:=GlobalLock(fh);
+ StrReplaceW(dst,'^v',p);
+ GlobalUnlock(fh);
+ CloseClipboard;
+ end
+ end
+end;
+
+type
+ trec = record
+ text:PAnsiChar;
+ one, two:integer;
+ end;
+
+function GetFileString(fname:PAnsiChar;linenum:integer):pWideChar;
+var
+ pc,FileBuf,CurLine:PAnsiChar;
+ f:THANDLE;
+ NumLines, j:integer;
+begin
+ f:=Reset(fname);
+ if f<>INVALID_HANDLE_VALUE then
+ begin
+ j:=FileSize(f);
+ mGetMem(FileBuf,j+1);
+ BlockRead(f,FileBuf^,j);
+ while (FileBuf+j)^<' ' do dec(j);
+ (FileBuf+j+1)^:=#0;
+ CloseHandle(f);
+ pc:=FileBuf;
+ CurLine:=pc;
+ NumLines:=1;
+ while pc^<>#0 do // count number of lines
+ begin
+ if pc^=#13 then
+ begin
+ if linenum=NumLines then
+ break;
+ inc(pc);
+ if pc^=#10 then
+ inc(pc);
+ inc(NumLines);
+ CurLine:=pc;
+ end
+ else
+ inc(pc);
+ end;
+ if (linenum>NumLines) or (linenum=0) then //ls - lastline
+ else if linenum<0 then
+ begin
+ randomize;
+ linenum:=random(NumLines)+1;
+ pc:=FileBuf;
+ NumLines:=1;
+ CurLine:=pc;
+ repeat
+ if (pc^=#13) or (pc^=#0) then
+ begin
+ if linenum=NumLines then
+ break;
+ if pc^<>#0 then
+ begin
+ inc(pc);
+ if pc^=#10 then
+ inc(pc);
+ end;
+ inc(NumLines);
+ CurLine:=pc;
+ end
+ else
+ inc(pc);
+ until false;
+ end;
+ pc^:=#0;
+ StrReplace(CurLine,'\n',#13#10);
+ StrReplace(CurLine,'\t',#09);
+ AnsiToWide(CurLine,result,CP_ACP);
+ mFreeMem(FileBuf);
+ end
+ else
+ result:=nil;
+end;
+
+function Split(buf:PWideChar;macro:PWideChar;var r:trec):integer;
+type
+ tconv = packed record
+ case boolean of
+ false: (res:int);
+ true: (lo,hi:word);
+ end;
+var
+ i:integer;
+ p,pp,lp:pWideChar;
+ ls:array [0..511] of WideChar;
+begin
+ result:=0;
+ i:=StrIndexW(buf,macro);
+ if i>0 then
+ begin
+ dec(i);
+ p:=buf+i+StrLenW(macro);
+ pp:=p;
+ while (p^<>#0) and (p^<>')') do
+ inc(p);
+ ls[0]:=#0;
+ if p^<>#0 then // correct syntax
+ begin
+ lp:=ls;
+ while (pp<>p) and (pp^<>',') do // filename
+ begin
+ lp^:=pp^;
+ inc(lp);
+ inc(pp);
+ end;
+ lp^:=#0;
+ WideToAnsi(ls,r.text,MirandaCP);
+ r.one:=-1;
+ r.two:=-1;
+ if pp^=',' then
+ begin
+ inc(pp);
+ r.one:=StrToInt(pp);
+ while (pp<>p) and (pp^<>',') do inc(pp);
+ if pp^=',' then
+ begin
+ inc(pp);
+ r.two:=StrToInt(pp);
+ end;
+ end;
+ tconv(result).lo:=p-buf-i+1; // length
+ tconv(result).hi:=i; // position
+ end;
+ end;
+end;
+
+procedure PasteFileString(dst:pWideChar);
+var
+ i:integer;
+ lp:pWideChar;
+ buf:array [0..511] of AnsiChar;
+ r:trec;
+begin
+ repeat
+ i:=Split(dst,'^f(',r);
+ if i>0 then
+ begin
+ StrDeleteW(dst,i shr 16,loword(i));
+ ConvertFileName(r.text,buf);
+// CallService(MS_UTILS_PATHTOABSOLUTE,dword(r.text),dword(@buf));
+ lp:=GetFileString(@buf,r.one);
+ if lp<>nil then
+ begin
+ StrInsertW(lp,dst,i shr 16);
+ mFreeMem(lp);
+ end;
+ end
+ else
+ break;
+ until false;
+end;
+
+procedure PasteSelectedText(wnd:hwnd;dst:pWideChar);
+var
+ sel:integer;
+ buf:pWideChar;
+begin
+ if (StrPosW(dst,'^s')<>nil) and (wnd<>0) then
+ begin
+ sel:=SendMessageW(wnd,EM_GETSEL,0,0);
+ if loword(sel)=(sel shr 16) then
+ StrReplaceW(dst,'^s',nil)
+ else
+ begin
+ buf:=GetDlgText(wnd,false);
+//!! next line was active. why?
+// SendMessageW(wnd,WM_GETTEXT,4095,dword(@buf));
+ buf[sel shr 16]:=#0;
+ StrReplaceW(dst,'^s',buf+loword(sel));
+ mFreeMem(buf);
+ end;
+ end;
+end;
+
+function CheckAuto(dst:pWideChar):bool;
+var
+ p:PWideChar;
+begin
+ result:=false;
+ if dst<>nil then
+ begin
+ p:=StrEndW(dst);
+ if (p-dst)>2 then
+ begin
+ dec(p,2);
+ if (p^='^') and ((p+1)^='a') then
+ begin
+ result:=true;
+ p^:=#0;
+ end;
+ end;
+ end;
+end;
+
+function InsertText(act:pHKAction;param:LPARAM;last:pWideChar):uint_ptr;
+var
+ tmp:PWideChar;
+ blob,p:PAnsiChar;
+ w:PWideChar;
+ hContact:THANDLE;
+ wnd:HWND;
+ fexist,autosend:bool;
+ dbei:TDBEVENTINFO;
+ i:cardinal;
+ cp:integer;
+ fh:THANDLE;
+ lstr:pWideChar;
+ llen:integer;
+ buf:array [0..31] of WideChar;
+ b,b1:array [0..MAX_PATH] of AnsiChar;
+begin
+ result:=uint_ptr(last);
+ with act^ do
+ begin
+ if (flags and ACF_CLIPBRD)<>0 then
+ begin
+ if (flags and ACF_COPYTO)<>0 then
+ CopyToClipboard(last,false)
+ else
+ result:=uint_ptr(PasteFromClipboard(false));
+ exit;
+ end;
+
+ hContact:=0;
+ if (flags and ACF_FILE)=0 then
+ begin
+ wnd:=WaitFocusedWndChild(GetForegroundWindow){GetFocus};
+ if wnd<>0 then
+ hContact:=WndToContact(wnd);
+ end
+ else
+ wnd:=0;
+
+ if hContact=0 then
+ begin
+ if CallService(MS_DB_CONTACT_IS,param,0)<>0 then
+ hContact:=param;
+ end;
+
+ if (flags and (ACF_FILE or ACF_FAPPEND or ACF_FWRITE))<>ACF_FILE then
+ begin
+ mGetMem (w ,BufferSize*SizeOf(WideChar));
+ FillChar(w^,BufferSize*SizeOf(WideChar),0);
+ StrCopyW(w,text);
+ PasteClipboard(w); // ^v
+ PasteFileString(w); // ^f
+ PasteSelectedText(wnd,w); // ^s
+ autosend:=CheckAuto(w); // ^a
+ StrReplaceW(w,'^l',last); // ^l
+ StrReplaceW(w,'^h',IntToHex(buf,StrToInt(last))); // ^h
+ StrReplaceW(w,'^t',#9); // ^t
+ StrReplaceW(w,'^e',nil); // ^e
+ end
+ else
+ autosend:=false;
+
+ if (flags2 and ACF2_TXT_TEXT)<>0 then
+ begin
+ tmp:=ParseVarString(w,hContact,last);
+ mFreeMem(w);
+ w:=tmp;
+ end;
+
+ if (flags and ACF_FILE)<>0 then
+ begin
+ cp:=0;
+ if (flags and ACF_ANSI)=ACF_ANSI then cp:=1
+ else if (flags and (ACF_UTF8 or ACF_SIGN))=ACF_UTF8 then cp:=2
+ else if (flags and (ACF_UTF8 or ACF_SIGN))=ACF_SIGN then cp:=4
+ else if (flags and (ACF_UTF8 or ACF_SIGN))=(ACF_UTF8 or ACF_SIGN) then cp:=3;
+
+ if (flags2 and ACF2_TXT_FILE)<>0 then
+ tmp:=ParseVarString(tfile,hContact,last)
+ else
+ tmp:=tfile;
+
+ if (flags and (ACF_FAPPEND or ACF_FWRITE))<>0 then
+ begin
+ case cp of
+ 1: begin
+ llen:=StrLen(WideToAnsi(w,pAnsiChar(lstr),MirandaCP));
+ end;
+ 2,3: begin
+ llen:=StrLen(WideToUTF8(w,pAnsiChar(lstr)));
+ end;
+ else
+ lstr:=w;
+ llen:=StrLenW(lstr)*SizeOf(WideChar);
+ end;
+ end
+ else
+ llen:=0;
+
+ fexist:=FileExists(tmp);
+ if fexist and ((flags and ACF_FAPPEND)<>0) then
+ begin
+ fh:=Append(tmp);
+ if fh<>THANDLE(INVALID_HANDLE_VALUE) then
+ begin
+ BlockWrite(fh,lstr^,llen);
+ end;
+ if (cp<>0) and (cp<>4) then
+ mFreeMem(lstr);
+ end
+ else if ((flags and ACF_FWRITE)<>0) or
+ (not fexist and ((flags and ACF_FAPPEND)<>0)) then
+ begin
+ fh:=ReWrite(tmp);
+ if fh<>THANDLE(INVALID_HANDLE_VALUE) then
+ begin
+ if cp=3 then
+ begin
+ i:=SIGN_UTF8;
+ BlockWrite(fh,i,3); // UTF8 sign
+ end
+ else if cp=4 then
+ begin
+ i:=SIGN_UNICODE;
+ BlockWrite(fh,i,2); // UTF16 sign
+ end;
+
+ BlockWrite(fh,lstr^,llen);
+ if (cp<>0) and (cp<>4) then
+ mFreeMem(lstr);
+ end;
+ end
+ else
+ begin
+ if StrPosW(tmp,'://')<>nil then // remote
+ begin
+ GetTempPathA(MAX_PATH,b);
+ GetTempFileNameA(b,'wat',GetCurrentTime,b1);
+ GetFile(FastWideToAnsiBuf(tmp,b),b1);
+ if tmp<>tfile then
+ mFreeMem(tmp);
+ FastAnsiToWide(b1,tmp);
+ end
+ else
+ b1[0]:=#0;
+ fh:=Reset(tmp);
+ if fh<>THANDLE(INVALID_HANDLE_VALUE) then
+ begin
+ i:=GetFSize(tmp);
+ mGetMem (w ,i+SizeOf(WideChar));
+ FillChar(w^,i+SizeOf(WideChar),0);
+ BlockRead(fh,w^,i);
+ if (flags and ACF_ANSI)<>0 then
+ begin
+ AnsiToWide(pAnsiChar(w),lstr,MirandaCP);
+ mFreeMem(w);
+ w:=lstr;
+ end
+ else if (flags and ACF_UTF8)<>0 then
+ begin
+ if (pdword(w)^ and $FFFFFF)=SIGN_UTF8 then
+ p:=pAnsiChar(w)+3
+ else
+ p:=pAnsiChar(w);
+ mFreeMem(w);
+ UTF8ToWide(p,w);
+ end
+ else
+ ChangeUnicode(w);
+ end;
+ if b1[0]<>#0 then
+ DeleteFileA(b1);
+ end;
+ if fh<>THANDLE(INVALID_HANDLE_VALUE) then
+ CloseHandle(fh);
+ if tmp<>tfile then
+ mFreeMem(tmp);
+ end;
+
+ result:=uint_ptr(w);
+
+ if (flags and ACF_FILE)=0 then
+ begin
+ if autosend then
+ begin
+ if hContact=0 then exit;
+ p:=GetContactProtoAcc(hContact);
+ cp:=DBReadDWord(hContact,'Tab_SRMsg','ANSIcodepage',MirandaCP);
+ if DBReadByte(hContact,p,'ChatRoom',0)<>1 then
+ begin
+ i:=WideToCombo(w,blob,cp);
+ // if CallContactService(hContact,PSS_MESSAGEW,0,dword(blob))=
+ // ACKRESULT_FAILED then
+ CallContactService(hContact,PSS_MESSAGE,PREF_UNICODE,tlparam(blob));
+ dbei.cbSize :=sizeof(dbei);
+ dbei.cbBlob :=i;
+ dbei.pBlob :=pByte(blob);
+ dbei.eventType:=EVENTTYPE_MESSAGE;
+ dbei.timestamp:=GetCurrentTime;
+ dbei.szModule :=p;
+ dbei.flags :=DBEF_SENT;
+ CallService(MS_DB_EVENT_ADD,hContact,tlparam(@dbei));
+ mFreeMem(blob);
+ end
+ else
+ SendToChat(hContact,w);
+ end
+ else
+ begin
+ GetWindowThreadProcessId(GetForegroundWindow,@i);
+ if (i=GetCurrentProcessId) and (wnd<>0) then
+ SendMessageW(wnd,EM_REPLACESEL,1,tlparam(w))
+ else
+ SendString(0,w);
+ end;
+ end;
+ end;
+end;
diff --git a/plugins/Actman/i_actlow.inc b/plugins/Actman/i_actlow.inc
new file mode 100644
index 0000000000..a749aef27f
--- /dev/null
+++ b/plugins/Actman/i_actlow.inc
@@ -0,0 +1,836 @@
+{Lowlevel actions work: clone, create, delete, execute}
+
+type
+ tAdvExpr = (aeNot,aeAdd,aeSub,aeMul,aeDiv,aeMod,aeAnd,aeOr,aeXor,aeSet);
+
+function GetActNameById(id:dword):PWideChar;
+var
+ i:integer;
+begin
+ for i:=0 to MaxGroups-1 do
+ begin
+ if ((GroupList^[i].flags and ACF_ASSIGNED)<>0) and
+ (id=GroupList^[i].id) then
+ begin
+ result:=GroupList^[i].descr;
+ exit;
+ end;
+ end;
+ result:=nil;
+end;
+
+function GetActIdByName(name:PWideChar):integer;
+var
+ i:integer;
+begin
+ for i:=0 to MaxGroups-1 do
+ begin
+ if ((GroupList^[i].flags and ACF_ASSIGNED)<>0) and
+ (StrCmpW(name,GroupList^[i].descr)=0) then
+ begin
+ result:=GroupList^[i].id;
+ exit;
+ end;
+ end;
+ result:=0;
+end;
+
+function GetActIdxByName(name:PWideChar):integer;
+var
+ i:integer;
+begin
+ for i:=0 to MaxGroups-1 do
+ begin
+ if ((GroupList^[i].flags and ACF_ASSIGNED)<>0) and
+ (StrCmpW(name,GroupList^[i].descr)=0) then
+ begin
+ result:=i;
+ exit;
+ end;
+ end;
+ result:=-1;
+end;
+
+function GetActIdxById(id:dword):integer;
+var
+ i:integer;
+begin
+ for i:=0 to MaxGroups-1 do
+ begin
+ if ((GroupList^[i].flags and ACF_ASSIGNED)<>0) and
+ (id=GroupList^[i].id) then
+ begin
+ result:=i;
+ exit;
+ end;
+ end;
+ result:=-1;
+end;
+
+function FreeAction(act:pHKAction):dword;
+begin
+ result:=act^.next;
+ with act^ do
+ begin
+ if (flags and ACF_ASSIGNED)<>0 then
+ begin
+ mFreeMem(descr);
+ case actionType of
+ ACT_SERVICE: begin
+ mFreeMem(service);
+ if (flags and (ACF_WPARNUM or ACF_WRESULT or ACF_WPARAM))=0 then
+ mFreeMem(pointer(wparam));
+ if ((flags and ACF_WPARNUM)<>0) and ((flags2 and ACF2_SRV_WPAR)<>0) then
+ mFreeMem(pointer(wparam));
+ if (flags and (ACF_LPARNUM or ACF_LRESULT or ACF_LPARAM))=0 then
+ mFreeMem(pointer(lparam));
+ if ((flags and ACF_LPARNUM)<>0) and ((flags2 and ACF2_SRV_LPAR)<>0) then
+ mFreeMem(pointer(lparam));
+ end;
+ ACT_PROGRAM: begin
+ mFreeMem(prgname);
+ mFreeMem(args);
+ end;
+ ACT_TEXT: begin
+ if (flags and ACF_CLIPBRD)=0 then
+ begin
+ mFreeMem(text);
+ if (flags and ACF_FILE)<>0 then
+ mFreeMem(tfile);
+ end;
+ end;
+ ACT_ADVANCE: begin
+ mFreeMem(varval);
+ if (action and ADV_ACT_POST)=ADV_ACT_JUMP then
+ mFreeMem(operval);
+ end;
+ ACT_CHAIN: begin
+ if (flags and ACF_BYNAME)<>0 then
+ mFreeMem(actname);
+ end;
+ ACT_RW: begin
+ mFreeMem(dbmodule);
+ mFreeMem(dbsetting);
+ if (flags and ACF_DBUTEXT)<>0 then
+ mFreeMem(dbvalue)
+ else if (flags2 and ACF2_RW_TVAR)<>0 then
+ mFreeMem(dbvalue);
+ end;
+ ACT_MESSAGE: begin
+ mFreeMem(msgtitle);
+ mFreeMem(msgtext);
+ end;
+ end;
+ end;
+ end;
+ FillChar(act^,SizeOf(act^),0);
+end;
+
+procedure FreeActions(list:pActList;idx:cardinal);
+begin
+ while idx<>0 do
+ idx:=FreeAction(@list^[idx]);
+end;
+
+procedure FreeActionsContinued(act:pHKAction);
+var
+ act_org:pHKAction;
+begin
+ act_org:=act;
+ repeat
+ FreeAction(act);
+ if act^.next<>0 then
+ inc(act)
+ else
+ break;
+ until false;
+ FreeMem(act_org);
+end;
+
+procedure DestroyActions(act:pActList;count:integer);
+var
+ pact:pHKAction;
+begin
+ pact:=@act^;
+ while count>0 do
+ begin
+ FreeAction(pact);
+ inc(pact);
+ dec(count);
+ end;
+ FreeMem(act);
+end;
+
+procedure CloneAction(dst,src:pHKAction);
+begin
+ move(src^,dst^,SizeOf(tHKAction));
+ with dst^ do
+ begin
+ if (flags and ACF_ASSIGNED)<>0 then
+ begin
+ StrDupW(descr,descr);
+ case actionType of
+ ACT_SERVICE: begin
+ StrDup(service,service);
+ if (flags and ACF_WPARNUM)=0 then
+ begin
+ if (flags and ACF_WSTRUCT)<>0 then
+ StrDupW(pWideChar(wparam),pWideChar(wparam))
+ else if (flags and ACF_WUNICODE)<>0 then
+ StrDupW(pWideChar(wparam),pWideChar(wparam))
+ else
+ StrDup(PAnsiChar(wparam),PAnsiChar(wparam));
+ end
+ else if (flags2 and ACF2_SRV_WPAR)<>0 then
+ StrDupW(pWideChar(wparam),pWideChar(wparam));
+
+ if (flags and ACF_LPARNUM)=0 then
+ begin
+ if (flags and ACF_LSTRUCT)<>0 then
+ StrDupW(pWideChar(lparam),pWideChar(lparam))
+ else if (flags and ACF_LUNICODE)<>0 then
+ StrDupW(pWideChar(lparam),pWideChar(lparam))
+ else
+ StrDup(PAnsiChar(lparam),PAnsiChar(lparam));
+ end
+ else if (flags2 and ACF2_SRV_LPAR)<>0 then
+ StrDupW(pWideChar(lparam),pWideChar(lparam));
+ end;
+
+ ACT_PROGRAM: begin
+ StrDupW(prgname,prgname);
+ StrDupW(args,args);
+ end;
+
+ ACT_TEXT: begin
+ if (flags and ACF_CLIPBRD)=0 then
+ begin
+ StrDupW(text,text);
+ if (flags and ACF_FILE)<>0 then
+ StrDupW(tfile,tfile);
+ end;
+ end;
+
+ ACT_ADVANCE: begin
+ StrDupW(varval,varval);
+ if (action and ADV_ACT_POST)=ADV_ACT_JUMP then
+ StrDupW(operval,operval);
+ end;
+
+ ACT_CHAIN: begin
+ if (flags or ACF_BYNAME)<>0 then
+ StrDupW(actname,actname);
+ end;
+
+ ACT_RW: begin
+ StrDup(dbmodule,dbmodule);
+ StrDup(dbsetting,dbsetting);
+ if (flags and ACF_DBUTEXT)<>0 then
+ StrDupW(pWideChar(dbvalue),pWideChar(dbvalue))
+ else if (flags2 and ACF2_RW_TVAR)<>0 then
+ StrDupW(pWideChar(dbvalue),pWideChar(dbvalue));
+ end;
+
+ ACT_MESSAGE: begin
+ StrDupW(msgtitle,msgtitle);
+ StrDupW(msgtext,msgtext);
+ end;
+ end;
+ end;
+ end;
+end;
+
+function CloneActions(idx:cardinal):pointer;
+var
+ i,count:integer;
+ aList:pHKAction;
+begin
+ count:=0;
+ i:=idx;
+ while i<>0 do
+ begin
+ inc(count);
+ i:=ActionList^[i].next;
+ end;
+ if count>0 then
+ begin
+ GetMem(result,count*SizeOf(tHKAction));
+ aList:=result;
+ i:=idx;
+ while i<>0 do
+ begin
+ CloneAction(aList,@ActionList^[i]);
+ i:=ActionList^[i].next;
+ inc(aList);
+ end;
+ end
+ else
+ result:=nil;
+end;
+
+function DoAction(action:dword;aparam:LPARAM;var last:uint_ptr;restype:dword):integer;
+var
+ tmpact,act,act_org:pHKAction;
+ val,prelast:uint_ptr;
+ b:boolean;
+ i:integer;
+ lContact:THANDLE;
+ buf:array [0..31] of WideChar;
+ tmpc,tmpc1,tmpc2,tmpcv1,tmpcv2:pWideChar;
+ oldrestype:integer;
+begin
+ if action<>0 then
+ begin
+ act:=CloneActions(action);
+ // if act=nil then exit;
+ act_org :=act;
+ oldrestype:=restype;
+ prelast :=0;
+ repeat
+ if (act^.flags and ACF_DISABLED)=0 then
+ begin
+
+ if (oldrestype=rtWide) and (last<>prelast) then
+ mFreeMem(prelast);
+ oldrestype:=restype;
+ prelast:=last;
+
+ with act^ do
+ begin
+ case actionType of
+
+ ACT_CONTACT: begin
+ if (flags and ACF_KEEPONLY)=0 then
+ last:=OpenContact(contact)
+ else
+ last:=contact;
+
+ restype:=rtInt;
+ end;
+
+ ACT_SERVICE: begin
+ last:=RunService(act,last,aparam,restype);
+{
+ if (flags and ACF_STRING)<>0 then
+ begin
+ if (flags and ACF_UNICODE)=0 then
+ begin
+ val:=last;
+ AnsiToWide(pAnsiChar(val),pWideChar(last),MirandaCP);
+ mFreeMem(val);
+ end
+ else
+ StrDupW(pWideChar(last),pWideChar(last));
+ restype:=rtWide;
+ end
+ else
+ restype:=rtInt;
+}
+ end;
+
+ ACT_PROGRAM: begin
+ if restype=rtInt then
+ last:=uint_ptr(IntToStr(buf,last));
+
+ last:=RunProgram(act,aparam,pWideChar(last));
+
+ restype:=rtInt;
+ end;
+
+ ACT_TEXT: begin
+ if restype=rtInt then
+ last:=uint_ptr(IntToStr(buf,last));
+
+ last:=InsertText(act,aparam,pWideChar(last));
+
+ restype:=rtWide;
+ end;
+
+ ACT_ADVANCE: begin
+ if restype=rtWide then
+ val:=StrToInt(pWideChar(last))
+ else
+ val:=last;
+
+ case condition and not ADV_COND_NOT of
+ ADV_COND_EQ: b:=val=value;
+ ADV_COND_GT: b:=integer(val)>integer(value);
+ ADV_COND_LT: b:=integer(val)<integer(value);
+ else
+ b:=true;
+ end;
+ if ((condition and ADV_COND_NOT)<>0) and (condition<>ADV_COND_NOP) then
+ b:=not b;
+ if b then
+ begin
+ case action and ADV_ACTION of
+
+ ADV_ACT_MATH: begin
+ case tAdvExpr(oper) of
+ aeNot: last:= not val;
+ aeAdd: last:= integer(val) + integer(mathval);
+ aeSub: last:= integer(val) - integer(mathval);
+ aeMul: last:= integer(val) * integer(mathval);
+ aeDiv: last:= integer(val) div integer(mathval);
+ aeMod: last:= val mod mathval;
+ aeAnd: last:= val and mathval;
+ aeOr : last:= val or mathval;
+ aeXor: last:= val xor mathval;
+ aeSet: last:= mathval;
+ end;
+ restype:=rtInt;
+ end;
+
+ ADV_ACT_VARS: begin
+//!! need to clear 'Last' if was string?
+ if (varval<>NIL) and (varval^<>#0) then
+ begin
+ if CallService(MS_DB_CONTACT_IS,aparam,0)<>0 then
+ lContact:=aparam
+ else
+ lContact:=0;
+ if restype=rtInt then
+ last:=uint_ptr(IntToStr(buf,last));
+
+ pWideChar(last):=ParseVarString(varval,lContact,pWideChar(last));
+
+ if (flags and ACF_VARASINT)<>0 then
+ begin
+ tmpc:=pWideChar(last);
+ last:=StrToInt(tmpc);
+ mFreeMem(tmpc);
+ restype:=rtInt;
+ end
+ else
+ restype:=rtWide;
+ end;
+ end;
+
+ end;
+ case action and ADV_ACT_POST of
+
+ ADV_ACT_JUMP : begin
+ tmpact:=act_org;
+ repeat
+ if StrCmpW(tmpact^.descr,operval)=0 then
+ begin
+ act:=tmpact;
+ tmpact:=nil;
+ break;
+ end;
+ if tmpact^.next=0 then
+ break;
+ inc(tmpact);
+ until false;
+ if tmpact=nil then continue;
+ end;
+
+ ADV_ACT_BREAK: break;
+ end;
+ end;
+ end;//last:=MakeAdvanced(act,last);
+
+ ACT_CHAIN: begin
+ if (flags and ACF_BYNAME)<>0 then
+ i:=GetActIdxByName(actname)
+ else
+ i:=GetActIdxById(id);
+
+ if i>=0 then
+ begin
+ restype:=DoAction(GroupList^[i].firstAction,aparam,last,restype);
+ // cleared in called Action
+ oldrestype:=rtInt;
+ prelast:=0;
+ end
+ else
+ begin
+ restype:=rtInt;
+ last:=0;
+ end;
+ end;
+
+ ACT_RW: begin
+ if (flags and ACF_CURRENT)<>0 then i:=0
+ else if (flags and ACF_PARAM )<>0 then i:=aparam
+ else if (flags and ACF_RESULT )<>0 then i:=last
+ else
+ i:=dbcontact;
+ if (flags and ACF_LAST)=0 then
+ val:=dbvalue
+ else
+ begin
+ val:=last;
+ if (flags and ACF_DBUTEXT)<>0 then
+ begin
+ if restype=rtInt then
+ val:=uint_ptr(IntToStr(buf,val));
+ end
+ else
+ begin
+ if restype=rtWide then
+ val:=StrToInt(pWideChar(val));
+ end;
+ end;
+
+ last:=DBRW(act,i,val,last,restype);
+
+ if (flags and ACF_DBUTEXT)<>0 then
+ restype:=rtWide
+ else
+ restype:=rtInt;
+ end;
+
+ ACT_MESSAGE: begin
+ if restype=rtWide then
+ tmpc:=PWideChar(last)
+ else
+ begin
+ IntToStr(buf,last);
+ tmpc:=@buf;
+ end;
+
+ if StrPosW(msgtitle,'<last>')<>nil then
+ begin
+ mGetMem(tmpc1,8192);
+ StrCopyW(tmpc1,msgtitle);
+ StrReplaceW(tmpc1,'<last>',tmpc);
+ end
+ else
+ tmpc1:=msgtitle;
+ if StrPosW(msgtext,'<last>')<>nil then
+ begin
+ mGetMem(tmpc2,8192);
+ StrCopyW(tmpc2,msgtext);
+ StrReplaceW(tmpc2,'<last>',tmpc);
+ end
+ else
+ tmpc2:=msgtext;
+
+ if (flags2 and ACF2_MSG_TTL)<>0 then
+ tmpcv1:=ParseVarString(tmpc1,aparam,tmpc)
+ else
+ tmpcv1:=tmpc1;
+ if (flags2 and ACF2_MSG_TXT)<>0 then
+ tmpcv2:=ParseVarString(tmpc2,aparam,tmpc)
+ else
+ tmpcv2:=tmpc2;
+
+ i:=MessageBoxW(0,tmpcv2,tmpcv1,boxopts);
+
+ if (flags and ACF_MSG_KEEP)=0 then
+ begin
+ restype:=rtInt;
+ last:=i
+ end;
+
+ if tmpcv1<>tmpc1 then mFreeMem(tmpcv1);
+ if tmpcv2<>tmpc2 then mFreeMem(tmpcv2);
+ if tmpc1 <>msgtitle then mFreeMem(tmpc1);
+ if tmpc2 <>msgtext then mFreeMem(tmpc2);
+ end;
+
+ else
+ last:=0;
+ end;
+ end;
+ end;
+ if (act_org^.flags and ACF_DOBREAK)<>0 then
+ break;
+ if act^.next=0 then
+ break;
+ inc(act);
+ until false;
+ FreeActionsContinued(act_org);
+ if (oldrestype=rtWide) and (last<>prelast) then
+ mFreeMem(prelast);
+ end;
+ result:=restype;
+end;
+
+type
+ pActStartData = ^tActStartData;
+ tActStartData = record
+ event :THANDLE;
+ action:dword;
+ param :LPARAM;
+ group :pHKRecord;
+ last :LPARAM;
+ end;
+
+procedure ThDoAction(arg:pActStartData); cdecl;
+var
+ ltmp:uint_ptr;
+ res:integer;
+begin
+ ltmp:=arg^.last;
+
+ if arg^.group<>nil then
+ begin
+ NotifyEventHooks(hevaction,arg^.group.id,0); // started
+ arg^.group.flags:=arg^.group.flags or ACF_USEDNOW;
+ end;
+
+ res:=DoAction(arg^.action,arg^.param,ltmp,rtInt);
+
+ if arg^.group<>nil then
+ begin
+ arg^.group.flags:=arg^.group.flags and not ACF_USEDNOW;
+ NotifyEventHooks(hevaction,arg^.group.id,1); // finished
+ end;
+
+ if arg^.event<>0 then
+ begin
+ arg^.last:=ltmp;
+ SetEvent(arg^.event);
+ end
+ else if res=rtWide then
+ begin
+ mFreeMem(ltmp);
+ end;
+end;
+
+function ActionStarterWait(action:dword;aparam:LPARAM=0;group:pHKRecord=nil;alast:LPARAM=0):LPARAM;
+var
+ tmp:pActStartData;
+begin
+ mGetMem(tmp,SizeOf(tActStartData));
+ tmp^.action:=action;
+ tmp^.param :=aparam;
+ tmp^.group :=group;
+ tmp^.last :=alast;
+ tmp^.event :=CreateEvent(nil,FALSE,FALSE,nil);
+ CloseHandle(mir_forkthread(@ThDoAction,tmp));
+ WaitForSingleObjectEx(tmp.event,INFINITE,true);
+ CloseHandle(tmp^.event);
+ result:=tmp^.last;
+end;
+
+function ActionStarter(action:dword;aparam:dword=0;group:pHKRecord=nil;alast:dword=0):integer;
+var
+ tmp:pActStartData;
+begin
+ result:=0;
+ mGetMem(tmp,SizeOf(tActStartData));
+ tmp^.action:=action;
+ tmp^.param :=aparam;
+ tmp^.group :=group;
+ tmp^.last :=alast;
+ tmp^.event :=0;
+ CloseHandle(mir_forkthread(@ThDoAction,tmp));
+end;
+
+procedure ReallocActionList(var ActList:pActList;var MaxAct:cardinal);
+var
+ i:cardinal;
+ tmp:pActList;
+begin
+ i:=(MaxAct+ActListPage)*SizeOf(tHKAction);
+ GetMem(tmp,i);
+ FillChar(tmp^,i,0);
+ if MaxAct>0 then
+ begin
+ move(ActList^,tmp^,MaxAct*SizeOf(tHKAction));
+ FreeMem(ActList);
+ end;
+ ActList:=tmp;
+ inc(MaxAct,ActListPage);
+end;
+
+function NewAction(var ActList:pActList;var MaxAct:cardinal):cardinal;
+var
+ i:cardinal;
+ pAct:pHKAction;
+begin
+ i:=1;
+ pAct:=@ActList^;
+ inc(pAct); // skip zero
+ while i<MaxAct do
+ begin
+ if (pAct^.flags and ACF_ASSIGNED)=0 then
+ begin
+ result:=i;
+ FillChar(pAct^,SizeOf(tHKAction),0);
+ pAct^.actionType:=ACT_CONTACT;
+ pAct^.flags :=ACF_ASSIGNED;
+ exit;
+ end;
+ inc(i);
+ inc(pAct);
+ end;
+
+ if MaxAct=0 then
+ result:=1
+ else
+ result:=MaxAct;
+
+ ReallocActionList(ActList,MaxAct);
+
+ ActList^[result].actionType:=ACT_CONTACT;
+ ActList^[result].flags :=ACF_ASSIGNED;
+end;
+
+procedure ReallocHKList(var HKList:pHKList;var MaxHK:cardinal);
+var
+ i:cardinal;
+ tmp:pHKList;
+begin
+ i:=(MaxHK+HKListPage)*SizeOf(tHKRecord);
+ GetMem(tmp,i);
+ FillChar(tmp^,i,0);
+ if MaxHK>0 then
+ begin
+ move(HKList^,tmp^,MaxHK*SizeOf(tHKRecord));
+ FreeMem(HKList);
+ end;
+ HKList:=tmp;
+ inc(MaxHK,HKListPage);
+end;
+
+procedure InitGroupValue(pHK:pHKRecord);
+var
+// time:TSYSTEMTIME;
+ tmp:int64;
+begin
+ with pHK^ do
+ begin
+ StrDupW(descr,NoDescription);
+{
+ GetSystemTime(time);
+ id :=time.wSecond+time.wMinute*60+time.wHour*3600+time.wMilliseconds*86400;
+}
+ QueryPerformanceCounter(tmp);
+ id :=tmp and $FFFFFFFF;
+ firstAction:=0;
+ active :=nil;
+ flags :=ACF_ASSIGNED;
+ end;
+end;
+
+// Root,Size,MaxCount(Page,flag)
+function NewGroup(var HKList:pHKList;var MaxHK:cardinal):cardinal;
+var
+ i:cardinal;
+ pHK:pHKRecord;
+begin
+ i:=0;
+ pHK:=@HKList^;
+ while i<MaxHK do
+ begin
+ if (pHK^.flags and ACF_ASSIGNED)=0 then
+ begin
+ result:=i;
+ InitGroupValue(pHK);
+ exit;
+ end;
+ inc(i);
+ inc(pHK);
+ end;
+ // realloc
+ result:=MaxHK;
+ ReallocHKList(HKList,MaxHK);
+ InitGroupValue(@HKList^[result]);
+end;
+
+procedure FreeGroup(num:cardinal);
+begin
+ with GroupList^[num] do
+ begin
+ if (flags and ACF_ASSIGNED)<>0 then
+ begin
+ flags:=0;
+ mFreeMem(descr);
+ FreeActions(ActionList,firstAction);
+ end;
+ end;
+end;
+
+procedure FreeGroups;
+var
+ i:integer;
+begin
+ for i:=0 to MaxGroups-1 do
+ begin
+ FreeGroup(i);
+ end;
+ MaxGroups:=0;
+ FreeMem(GroupList);
+ FreeMem(ActionList);
+ GroupList:=nil;
+ ActionList:=nil;
+end;
+
+procedure DestroyGroups(HKList:pHKList;count:integer);
+var
+ pHK:pHKRecord;
+begin
+ pHK:=@HKList^;
+ while count>0 do
+ begin
+ if (pHK^.flags and ACF_ASSIGNED)<>0 then
+ mFreeMem(pHK^.descr);
+ inc(pHK);
+ dec(count);
+ end;
+ FreeMem(HKList);
+end;
+
+function CloneActionList:pActList;
+var
+ src,dst:pHKAction;
+ i:integer;
+begin
+ i:=MaxActions;
+ GetMem(result,i*SizeOf(tHKAction));
+ src:=@ActionList^;
+ dst:=@result^;
+ while i>0 do
+ begin
+ CloneAction(dst,src);
+ inc(src);
+ inc(dst);
+ dec(i);
+ end;
+end;
+
+procedure CloneGroup(dst,src:pHKRecord);
+begin
+ move(src^,dst^,SizeOf(tHKRecord));
+ if (src^.flags and ACF_ASSIGNED)<>0 then
+ StrDupW(dst^.descr,src^.descr);
+end;
+
+function CloneGroupList:pHKList;
+var
+ src,dst:pHKRecord;
+ i:integer;
+begin
+ i:=MaxGroups;
+ GetMem(result,i*SizeOf(tHKRecord));
+ src:=@GroupList^;
+ dst:=@result^;
+ while i>0 do
+ begin
+ CloneGroup(dst,src);
+ inc(src);
+ inc(dst);
+ dec(i);
+ end;
+end;
+
+function ActSelect(wParam:WPARAM;lParam:LPARAM):int;cdecl;
+begin
+ if (wParam and ACCF_ID)<>0 then
+ result:=GetActIdxById(lParam)
+ else
+ result:=GetActIdxByName(pWideChar(lParam));
+ if result=-1 then
+ exit;
+ with GroupList^[result] do
+ begin
+ if (wParam and ACCF_CLEAR)<>0 then
+ flags:=flags and not (uint_ptr(wParam) and ACCF_FLAGS)
+ else
+ flags:=flags or (uint_ptr(wParam) and ACCF_FLAGS);
+ end;
+end;
diff --git a/plugins/Actman/i_const.inc b/plugins/Actman/i_const.inc
new file mode 100644
index 0000000000..3e9950414f
--- /dev/null
+++ b/plugins/Actman/i_const.inc
@@ -0,0 +1,219 @@
+{resource constants}
+const
+ // dialogs
+ IDD_ACTION = 1025;
+ IDD_STRUCTURE = 1027;
+ IDD_ASK = 1028;
+
+ // icons
+ IDI_NEW = 1025;
+ IDI_UP = 1026;
+ IDI_DOWN = 1027;
+ IDI_DELETE = 1028;
+ IDI_RELOAD = 1029;
+ IDI_CONTACT = 1030;
+ IDI_SERVICE = 1031;
+ IDI_PROGRAM = 1032;
+ IDI_INSERT = 1033;
+ IDI_ADVANCE = 1034;
+ IDI_CHAIN = 1035;
+ IDI_RW = 1036;
+ IDI_TEST = 1037;
+ IDI_EXPORT = 1038;
+ IDI_IMPORT = 1039;
+ IDI_MESSAGE = 1040;
+ IDI_VAR_CHECKED = 1041;
+ IDI_VAR_UNCHECKED = 1042;
+ IDI_FORMAT = 1043;
+ IDI_APPLY = 1044;
+
+ // Structure editor
+ IDC_DATA_FULL = 2001;
+ IDC_DATA_TYPE = 2002;
+ IDC_DATA_EDIT = 2005;
+ IDC_DATA_LEN = 2006;
+ IDC_DATA_HELP = 2007;
+
+ IDC_DATA_NEW = 2008;
+ IDC_DATA_DELETE = 2009;
+ IDC_DATA_UP = 2010;
+ IDC_DATA_DOWN = 2011;
+ IDC_DATA_CHANGE = 2012;
+ IDC_DATA_VARS = 2013;
+ IDC_DATA_PACKED = 2014;
+
+ // Action page
+// IDC_RESET = 2001;
+
+ IDC_ACTION_TYPE = 2005;
+ IDC_STAT_ACTION = 2006;
+
+ IDC_ACTION_LIST = 2007;
+ IDC_ACTION_NEW = 2008;
+ IDC_ACTION_DELETE = 2009;
+ IDC_ACTION_UP = 2010;
+ IDC_ACTION_DOWN = 2011;
+
+ IDC_ACTION_GROUP = 2012;
+ IDC_GROUP_NEW = 2015;
+ IDC_GROUP_RELOAD = 2016;
+ IDC_GROUP_DELETE = 2017;
+ IDC_GROUP_TEST = 2018;
+ IDC_GROUP_UP = 2019;
+ IDC_GROUP_DOWN = 2020;
+ IDC_GROUP_EXPORT = 2021;
+ IDC_GROUP_IMPORT = 2022;
+ IDC_ACTION_HELP = 2023;
+
+ IDC_STAT_CONTACT = 2140;
+ IDC_CONTACTLIST = 2141;
+ IDC_CNT_KEEP = 2142;
+ IDC_STAT_FORMAT = 2143;
+ IDC_EDIT_FORMAT = 2144;
+ IDC_CNT_FILTER = 2145;
+ IDC_CNT_APPLY = 2146;
+ IDC_STAT_FHELP = 2147;
+
+ IDC_STAT_WPAR1 = 2150;
+ IDC_STAT_LPAR1 = 2151;
+ IDC_STAT_WPAR = 2152;
+ IDC_STAT_LPAR = 2153;
+ IDC_FLAG_WPAR = 2154;
+ IDC_FLAG_LPAR = 2155;
+ IDC_EDIT_WPAR = 2156;
+ IDC_EDIT_LPAR = 2157;
+ IDC_STAT_SERVICE = 2158;
+ IDC_EDIT_SERVICE = 2159;
+ IDC_WSTRUCT = 2160;
+ IDC_LSTRUCT = 2161;
+
+ IDC_RES_POPUP = 2251;
+ IDC_RES_MESSAGE = 2252;
+ IDC_RES_INSERT = 2253;
+ IDC_SRV_RESSTAT = 2254;
+ IDC_SRV_RESULT = 2255;
+ IDC_RES_FREEMEM = 2256;
+ IDC_RES_UNICODE = 2257;
+ IDC_RES_SIGNED = 2258;
+ IDC_RES_GROUP = 2259;
+
+ IDC_FLAG_MINIMIZE = 2350;
+ IDC_STAT_PRGPATH = 2351;
+ IDC_EDIT_PRGPATH = 2352;
+ IDC_PROGRAM = 2353;
+ IDC_STAT_PRGARGS = 2354;
+ IDC_EDIT_PRGARGS = 2355;
+ IDC_EDIT_PROCTIME = 2356;
+ IDC_PROCESS_GROUP = 2357;
+ IDC_STAT_PROCTIME = 2358;
+ IDC_PRSTART_GROUP = 2359;
+ IDC_FLAG_NORMAL = 2360;
+ IDC_FLAG_HIDDEN = 2361;
+ IDC_FLAG_MAXIMIZE = 2362;
+ IDC_FLAG_CURPATH = 2363;
+ IDC_FLAG_PARALLEL = 2364;
+ IDC_FLAG_CONTINUE = 2365;
+ IDC_HLP_FVARS = 2366;
+
+ IDC_HLP_VARS = 2451;
+ IDC_STAT_INSERT = 2452;
+ IDC_EDIT_INSERT = 2453;
+
+ IDC_FLAG_CLIP = 2454;
+ IDC_FLAG_MESSAGE = 2455;
+ IDC_CLIP_COPYTO = 2456;
+ IDC_CLIP_PASTE = 2457;
+ IDC_CLIP_GROUP = 2458;
+ IDC_FILE_ENC = 2459;
+// IDC_CLIP_ANSI = 2459;
+// IDC_CLIP_WIDE = 2460;
+ IDC_FLAG_FILE = 2461;
+ IDC_FILE_PATH = 2462;
+ IDC_FILE_FILEBTN = 2463;
+ IDC_FILE_READ = 2464;
+ IDC_FILE_WRITE = 2465;
+ IDC_FILE_APPEND = 2466;
+ IDC_FILE_GROUP = 2467;
+
+ IDC_STAT_GROUPS = 2500;
+ IDC_GROUP_LIST = 2501;
+
+ IDC_CONDITION = 2505;
+ IDC_FLAG_GT = 2506;
+ IDC_FLAG_LT = 2507;
+ IDC_FLAG_EQ = 2508;
+ IDC_FLAG_NOP = 2509;
+ IDC_FLAG_NOT = 2510;
+
+ IDC_OPERATION = 2511;
+ IDC_FLAG_BREAK = 2512;
+ IDC_FLAG_JUMP = 2513;
+ IDC_FLAG_ANOP = 2514;
+ IDC_ADV_VALUE = 2515;
+ IDC_STAT_VAL = 2516;
+
+ IDC_FLAG_MATH = 2519;
+ IDC_ADV_OPER = 2520;
+ IDC_ADV_VAL1 = 2521;
+ IDC_ADV_VAL2 = 2522;
+ IDC_FLAG_VARS = 2523;
+ IDC_ADV_VARS = 2524;
+ IDC_ADV_HVARS = 2526;
+ IDC_ADV_ASINT = 2527;
+
+ IDC_RW_READ = 2601;
+ IDC_RW_WRITE = 2602;
+ IDC_RW_DELETE = 2603;
+ IDC_RW_STATM = 2605;
+ IDC_RW_MODULE = 2606;
+ IDC_RW_STATS = 2607;
+ IDC_RW_SETTING = 2608;
+ IDC_RW_TEXT = 2609;
+ IDC_RW_VALUE = 2610;
+ IDC_RW_DATATYPE = 2611;
+ IDC_RW_CURRENT = 2614;
+ IDC_RW_PARAM = 2615;
+ IDC_RW_MANUAL = 2616;
+ IDC_RW_OPER = 2617;
+ IDC_RW_VAL = 2618;
+ IDC_RW_RESULT = 2619;
+ IDC_RW_LAST = 2620;
+
+ IDC_MSG_STAT1 = 2701;
+ IDC_MSG_STAT2 = 2702;
+ IDC_MSG_TITLE = 2703;
+ IDC_MSG_TEXT = 2704;
+ IDC_MSG_BTNS = 2705;
+ IDC_MSGB_ARI = 2706;
+ IDC_MSGB_OK = 2707;
+ IDC_MSGB_OC = 2708;
+ IDC_MSGB_RC = 2709;
+ IDC_MSGB_YN = 2710;
+ IDC_MSGB_YNC = 2711;
+ IDC_MSG_ICONS = 2712;
+ IDC_MSGI_NONE = 2713;
+ IDC_MSGI_WARN = 2714;
+ IDC_MSGI_INFO = 2715;
+ IDC_MSGI_QUEST = 2716;
+ IDC_MSGI_ERROR = 2717;
+ IDC_MSG_KEEP = 2718;
+
+// Variables buttons
+ IDC_SRV_WPAR = 3000;
+ IDC_SRV_LPAR = 3001;
+ IDC_SRV_SRVC = 3002;
+ IDC_PRG_PRG = 3003;
+ IDC_PRG_ARG = 3004;
+ IDC_TXT_FILE = 3005;
+ IDC_TXT_TEXT = 3006;
+ IDC_RW_MVAR = 3008;
+ IDC_RW_SVAR = 3009;
+ IDC_RW_TVAR = 3010;
+ IDC_MSG_TTL = 3011;
+ IDC_MSG_TXT = 3012;
+
+// Question
+ IDC_ASK = 1025;
+ IDC_YESALL = 1026;
+ IDC_NOALL = 1027;
+ IDC_APPEND = 1028;
diff --git a/plugins/Actman/i_contact.inc b/plugins/Actman/i_contact.inc
new file mode 100644
index 0000000000..40cd6f18f7
--- /dev/null
+++ b/plugins/Actman/i_contact.inc
@@ -0,0 +1,113 @@
+{hkContact}
+const
+ defformat = '%name% - %uid% (%account%:%group%)';
+
+procedure FillContactList(list:hwnd; filter:boolean=true;format:pWideChar=nil);
+var
+ hContact:THANDLE;
+ buf:array [0..511] of WideChar;
+ buf1:array [0..63] of WideChar;
+ p:PWideChar;
+ uid:pAnsiChar;
+ ldbv:TDBVARIANT;
+ acc:pAnsiChar;
+ lName,
+ lGroup,
+ lAccount,
+ lUID:boolean;
+begin
+ if format=nil then format:=defformat;
+
+ SendMessage(list,CB_RESETCONTENT,0,0);
+ hContact:=CallService(MS_DB_CONTACT_FINDFIRST,0,0);
+
+ lName :=StrPosW(format,'%name%')<>nil;
+ lGroup :=StrPosW(format,'%group%')<>nil;
+ lAccount:=StrPosW(format,'%account%')<>nil;
+ lUID :=StrPosW(format,'%uid%')<>nil;
+
+ while hContact<>0 do
+ begin
+ if ((not filter) and ((IsContactActive(hContact)+1)>=0)) or // + disabled (not deleted)
+ (filter and (IsContactActive(hContact) >=0)) then
+ begin
+ StrCopyW(buf,format);
+ if lName then
+ StrReplaceW(buf,'%name%',
+ PWideChar(CallService(MS_CLIST_GETCONTACTDISPLAYNAME,hContact,GCDNF_UNICODE)));
+
+ if lGroup then
+ begin
+ p:=DBReadUnicode(hContact,strCList,'Group',nil);
+ StrReplaceW(buf,'%group%',p);
+ mFreeMem(p);
+ end;
+
+ if lAccount then
+ begin
+ acc:=GetContactProtoAcc(hContact);
+ StrReplaceW(buf,'%account%',FastAnsiToWideBuf(acc,buf1));
+ end
+ else
+ acc:=nil;
+
+ if lUID then
+ begin
+ if acc=nil then
+ acc:=GetContactProtoAcc(hContact);
+ if IsChat(hContact) then
+ begin
+ p:=DBReadUnicode(hContact,acc,'ChatRoomID');
+ StrReplaceW(buf,'%uid%',p);
+ mFreeMem(p);
+ end
+ else
+ begin
+ uid:=pAnsiChar(CallProtoService(acc,PS_GETCAPS,PFLAG_UNIQUEIDSETTING,0));
+ if uint_ptr(uid)<>CALLSERVICE_NOTFOUND then
+ begin
+ if DBReadSetting(hContact,acc,uid,@ldbv)=0 then
+ begin
+ case ldbv._type of
+ DBVT_DELETED: p:='[deleted]';
+ DBVT_BYTE : p:=IntToStr(buf1,ldbv.bVal);
+ DBVT_WORD : p:=IntToStr(buf1,ldbv.wVal);
+ DBVT_DWORD : p:=IntToStr(buf1,ldbv.dVal);
+ DBVT_UTF8 : UTF8ToWide(ldbv.szVal.A,p);
+ DBVT_ASCIIZ : AnsiToWide(ldbv.szVal.A,p,MirandaCP);
+ DBVT_WCHAR : p:=ldbv.szVal.W;
+ DBVT_BLOB : p:='blob';
+ end;
+ StrReplaceW(buf,'%uid%',p);
+ if ldbv._type in [DBVT_UTF8,DBVT_ASCIIZ] then
+ mFreeMem(p);
+ DBFreeVariant(@ldbv);
+ end;
+ end;
+ StrReplaceW(buf,'%uid%',nil);
+ end;
+ end;
+
+ SendMessage(list,CB_SETITEMDATA,
+ SendMessageW(list,CB_ADDSTRING,0,tlparam(@buf)),
+ hContact);
+ end;
+ hContact:=CallService(MS_DB_CONTACT_FINDNEXT,hContact,0);
+ end;
+end;
+
+function FindContact(list:hwnd;contact:THANDLE):integer;
+var
+ i,j:integer;
+begin
+ result:=0;
+ j:=SendMessage(list,CB_GETCOUNT,0,0);
+ for i:=0 to j-1 do
+ begin
+ if THANDLE(SendMessage(list,CB_GETITEMDATA,i,0))=contact then
+ begin
+ result:=i;
+ break;
+ end;
+ end;
+end;
diff --git a/plugins/Actman/i_dlglists.inc b/plugins/Actman/i_dlglists.inc
new file mode 100644
index 0000000000..ce2cc2138d
--- /dev/null
+++ b/plugins/Actman/i_dlglists.inc
@@ -0,0 +1,75 @@
+{Dialog list filling}
+ procedure InsertString(wnd:HWND;num:dword;str:PAnsiChar);
+ var
+ buf:array [0..127] of WideChar;
+ begin
+ SendMessageW(wnd,CB_SETITEMDATA,
+ SendMessageW(wnd,CB_ADDSTRING,0,
+ lparam(TranslateW(FastAnsiToWideBuf(str,buf)))),
+ num);
+ {
+ SendMessageW(wnd,CB_INSERTSTRING,num,
+ dword(TranslateW(FastAnsiToWideBuf(str,buf))));
+ }
+ end;
+
+ procedure MakeMathOperList(wnd:HWND);
+ begin
+ SendMessage(wnd,CB_RESETCONTENT,0,0);
+ InsertString(wnd,cardinal(aeNot),'! not');
+ InsertString(wnd,cardinal(aeAdd),'+ add');
+ InsertString(wnd,cardinal(aeSub),'- sub');
+ InsertString(wnd,cardinal(aeMul),'* mul');
+ InsertString(wnd,cardinal(aeDiv),'/ div');
+ InsertString(wnd,cardinal(aeMod),'% mod');
+ InsertString(wnd,cardinal(aeAnd),'& and');
+ InsertString(wnd,cardinal(aeOr ),'| or');
+ InsertString(wnd,cardinal(aeXor),'^ xor');
+ InsertString(wnd,cardinal(aeSet),'= set');
+ SendMessage(wnd,CB_SETCURSEL,0,0);
+ end;
+
+ procedure MakeParamTypeList(wnd:HWND);
+ begin
+ SendMessage(wnd,CB_RESETCONTENT,0,0);
+ InsertString(wnd,ptNumber ,'number value');
+ InsertString(wnd,ptString ,'ANSI string');
+ InsertString(wnd,ptUnicode,'Unicode string');
+ InsertString(wnd,ptCurrent,'current contact');
+ InsertString(wnd,ptResult ,'last result');
+ InsertString(wnd,ptParam ,'parameter');
+ InsertString(wnd,ptStruct ,'structure');
+ SendMessage(wnd,CB_SETCURSEL,0,0);
+ end;
+
+ procedure MakeResultTypeList(wnd:HWND);
+ begin
+ SendMessage(wnd,CB_RESETCONTENT,0,0);
+ InsertString(wnd,sresInt ,'Integer');
+ InsertString(wnd,sresHex ,'Hexadecimal');
+ InsertString(wnd,sresString,'String');
+ InsertString(wnd,sresStruct,'Structure');
+ SendMessage(wnd,CB_SETCURSEL,0,0);
+ end;
+
+ procedure MakeFileEncList(wnd:HWND);
+ begin
+ SendMessage(wnd,CB_RESETCONTENT,0,0);
+ InsertString(wnd,0,'Ansi');
+ InsertString(wnd,1,'UTF8');
+ InsertString(wnd,2,'UTF8+sign');
+ InsertString(wnd,3,'UTF16');
+ InsertString(wnd,4,'UTF16+sign');
+ SendMessage(wnd,CB_SETCURSEL,0,0);
+ end;
+
+ procedure MakeDataTypeList(wnd:HWND);
+ begin
+ SendMessage(wnd,CB_RESETCONTENT,0,0);
+ InsertString(wnd,0,'Byte');
+ InsertString(wnd,1,'Word');
+ InsertString(wnd,2,'DWord');
+ InsertString(wnd,3,'Ansi');
+ InsertString(wnd,4,'Unicode');
+ SendMessage(wnd,CB_SETCURSEL,0,0);
+ end;
diff --git a/plugins/Actman/i_inoutxm.inc b/plugins/Actman/i_inoutxm.inc
new file mode 100644
index 0000000000..8795d566e7
--- /dev/null
+++ b/plugins/Actman/i_inoutxm.inc
@@ -0,0 +1,1180 @@
+{}
+var
+ xmlparser:XML_API_W;
+const
+ // Nodes
+ ioRoot :PWideChar = 'ActMan_Export';
+ ioAction :PWideChar = 'Action';
+ ioSubAction :PWideChar = 'SubAction';
+ ioContactWindow:PWideChar = 'ContactWindow';
+ ioCallService :PWideChar = 'CallService';
+ ioRunProgram :PWideChar = 'RunProgram';
+ ioInsertText :PWideChar = 'InsertText';
+ ioAdvanced :PWideChar = 'Advanced';
+ ioLinkAction :PWideChar = 'LinkAction';
+ ioProfile :PWideChar = 'Profile';
+ ioMessageBox :PWideChar = 'MessageBox';
+ ioWParam :PWideChar = 'WPARAM';
+ ioLParam :PWideChar = 'LPARAM';
+ ioItem :PWideChar = 'ITEM';
+ ioPost :PWideChar = 'POST';
+ ioIf :PWideChar = 'IF';
+ ioAct :PWideChar = 'ACT';
+ ioOutput :PWideChar = 'OUTPUT';
+ // Attributes
+ ioType :PWideChar = 'type';
+ ioInverse :PWideChar = 'inverse';
+ ioName :PWideChar = 'name';
+ ioDisabled :PWideChar = 'disabled';
+ ioVolatile :PWideChar = 'volatile';
+ ioLast :PWideChar = 'last';
+ ioWindow :PWideChar = 'window';
+ ioParallel :PWideChar = 'parallel';
+ ioArgs :PWideChar = 'args';
+ ioWait :PWideChar = 'wait';
+ ioObject :PWideChar = 'object';
+ ioOper :PWideChar = 'oper';
+ ioMessage :PWideChar = 'message';
+// ioDest :PWideChar = 'dest';
+ ioEnc :PWideChar = 'enc';
+ ioValue :PWideChar = 'value';
+ ioService :PWideChar = 'service';
+ ioNot :PWideChar = 'not';
+ ioCond :PWideChar = 'cond';
+ ioVariables :PWideChar = 'variables';
+ ioFileVariable :PWideChar = 'modvariables';
+ ioArgVariable :PWideChar = 'argvariables';
+ ioModule :PWideChar = 'module';
+ ioSetting :PWideChar = 'setting';
+ ioCProto :PWideChar = 'cproto';
+ ioCUIDType :PWideChar = 'cuidtype';
+ ioCUID :PWideChar = 'cuid';
+ ioIsChat :pWideChar = 'ischat';
+ ioTitle :PWideChar = 'title';
+ ioFile :PWideChar = 'file';
+ ioAsInt :PWideChar = 'asint';
+ ioKeepOnly :PWideChar = 'keeponly';
+ ioKeepLast :PWideChar = 'keeplast';
+ ioReturn :PWideChar = 'return';
+ ioLength :PWideChar = 'length';
+ ioFree :PWideChar = 'free';
+ ioPacked :PWideChar = 'packed';
+
+ // Values
+ ioNumber :PWideChar = 'number';
+ ioCurrent :PWideChar = 'current';
+ ioContact :PWideChar = 'contact';
+ ioStruct :PWideChar = 'struct';
+ ioResult :PWideChar = 'result';
+ ioParam :PWideChar = 'param';
+ ioByte :PWideChar = 'byte';
+ ioWord :PWideChar = 'word';
+ ioDword :PWideChar = 'dword';
+ ioAnsi :PWideChar = 'ansi';
+ ioUnicode :PWideChar = 'unicode';
+// ioWStruct :PWideChar = 'wordstruct';
+// ioBStruct :PWideChar = 'bytestruct';
+ ioHex :PWideChar = 'hex';
+ ioInt :PWideChar = 'int';
+ ioSigned :PWideChar = 'signed';
+ ioPopup :PWideChar = 'popup';
+ ioMsgBox :PWideChar = 'msgbox';
+ ioHidden :PWideChar = 'hidden';
+ ioMinimized :PWideChar = 'minimized';
+ ioMaximized :PWideChar = 'maximized';
+ ioNormal :PWideChar = 'normal';
+ ioClipboard :PWideChar = 'clipboard';
+ ioCopy :PWideChar = 'copy';
+ ioPaste :PWideChar = 'paste';
+ ioBreak :PWideChar = 'break';
+ ioJump :PWideChar = 'jump';
+ ioNop :PWideChar = 'nop';
+// ioArray :PWideChar = 'array';
+ ioScript :PWideChar = 'script';
+ ioWrite :PWideChar = 'write';
+ ioRead :PWideChar = 'read';
+ ioAppend :PWideChar = 'append';
+ ioDelete :PWideChar = 'delete';
+
+const
+ imp_yes = 1;
+ imp_yesall = 2;
+ imp_no = 3;
+ imp_noall = 4;
+ imp_append = 5;
+
+function ReadStruct(act:HXML):int_ptr;
+{
+var
+ child,i:integer;
+ tmp:pWideChar;
+ sub:HXML;
+ typ:pWideChar;
+}
+begin
+ result:=0;
+(*
+ mGetMem (tmp ,32768);
+ FillChar(tmp^,32768,0);
+ result:=int_ptr(tmp);
+ with xmlparser do
+ begin
+{
+ typ:=getAttrValue(act,ioPacked);
+ if (typ<>nil) and (typ^<>#0) and (typ^<>'0') then
+ begin
+ tmp^:=char_packed; inc(tmp);
+ end;
+}
+ child:=0;
+ repeat
+ sub:=getNextChild(act,ioItem,@child);
+ if sub=0 then break;
+
+ typ:=getAttrValue(sub,ioType);
+ for i:=0 to MaxStructTypes-1 do
+ begin
+ if lstrcmpiw(typ,StructElems[i].short)=0 then break;
+ end;
+ if StrToInt(getAttrValue(sub,ioReturn))=1 then
+ begin
+ tmp^:=char_return; inc(tmp);
+ end;
+ if StrToInt(getAttrValue(sub,ioScript))=1 then
+ begin
+ tmp^:=char_script; inc(tmp);
+ end;
+ tmp:=StrCopyEW(tmp,typ);
+ tmp^:=' '; inc(tmp);
+ case StructElems[i].typ of
+ SST_LAST, SST_PARAM: ;
+ SST_BYTE,
+ SST_WORD,
+ SST_DWORD,
+ SST_QWORD,
+ SST_NATIVE: begin
+ tmp:=StrCopyEW(tmp,getAttrValue(sub,ioValue));
+ end;
+ SST_BARR, SST_WARR,
+ SST_BPTR, SST_WPTR: begin
+ tmp:=StrCopyEW(tmp,getAttrValue(sub,ioLength));
+ tmp^:=' '; inc(tmp);
+ tmp:=StrCopyEW(tmp,getAttrValue(sub,ioValue));
+ end;
+ end;
+ tmp^:='|'; inc(tmp);
+ until false;
+ dec(tmp); tmp^:=#0;
+ end;
+*)
+end;
+
+function ReadParam(act:HXML; var param:int_ptr;isvar:boolean):dword;
+var
+ tmp:pWideChar;
+begin
+ result:=0;
+ if act=0 then
+ exit;
+ with xmlparser do
+ begin
+ tmp:=getAttrValue(act,ioType);
+ if lstrcmpiw(tmp,ioCurrent)=0 then result:=result or ACF_WCURRENT
+ else if lstrcmpiw(tmp,ioResult )=0 then result:=result or ACF_WRESULT
+ else if lstrcmpiw(tmp,ioParam )=0 then result:=result or ACF_WPARAM
+ else if lstrcmpiw(tmp,ioNumber )=0 then
+ begin
+ result:=result or ACF_WPARNUM;
+ tmp:=getAttrValue(act,ioValue);
+ if isvar then
+ StrDupW(pWideChar(param),tmp)
+ else
+ param:=StrToInt(tmp);
+ end
+ else if lstrcmpiw(tmp,ioStruct)=0 then
+ begin
+ result:=result or ACF_WSTRUCT;
+ param:=ReadStruct(act);
+ end
+ else if lstrcmpiw(tmp,ioUnicode)=0 then
+ begin
+ result:=result or ACF_WUNICODE;
+ StrDupW(pWideChar(param),getAttrValue(act,ioValue));
+ end
+ else if lstrcmpiw(tmp,ioAnsi)=0 then
+ begin
+ WideToAnsi(getAttrValue(act,ioValue),pAnsiChar(param),MirandaCP);
+ end;
+ end;
+end;
+
+function ImportContact(node:HXML):THANDLE;
+var
+ proto:pAnsiChar;
+ tmpbuf:array [0..63] of AnsiChar;
+ dbv:TDBVARIANT;
+ is_chat:boolean;
+begin
+ with xmlparser do
+ begin
+ proto:=FastWideToAnsiBuf(getAttrValue(node,ioCProto),tmpbuf);
+ if (proto=nil) or (proto^=#0) then
+ begin
+ result:=0;
+ exit;
+ end;
+ is_chat:=StrToInt(getAttrValue(node,ioIsChat))<>0;
+
+ if is_chat then
+ begin
+ dbv.szVal.W:=getAttrValue(node,ioCUID);
+ end
+ else
+ begin
+ FillChar(dbv,SizeOf(TDBVARIANT),0);
+ dbv._type:=StrToInt(getAttrValue(node,ioCUIDType));
+ case dbv._type of
+ DBVT_BYTE : dbv.bVal:=StrToInt(getAttrValue(node,ioCUID));
+ DBVT_WORD : dbv.wVal:=StrToInt(getAttrValue(node,ioCUID));
+ DBVT_DWORD : dbv.dVal:=StrToInt(getAttrValue(node,ioCUID));
+ DBVT_ASCIIZ: FastWideToAnsi(getAttrValue(node,ioCUID),dbv.szVal.A);
+ DBVT_UTF8 : WideToUTF8(getAttrValue(node,ioCUID),dbv.szVal.A);
+ DBVT_WCHAR : StrDupW(dbv.szVal.W,getAttrValue(node,ioCUID));
+ DBVT_BLOB : begin
+ Base64Decode(FastWideToAnsi(getAttrValue(node,ioCUID),pAnsiChar(dbv.pbVal)),dbv.pbVal);
+ end;
+ end;
+ end;
+ end;
+ result:=FindContactHandle(proto,dbv,is_chat);
+ if not is_chat then
+ case dbv._type of
+ DBVT_WCHAR,
+ DBVT_ASCIIZ,
+ DBVT_UTF8 : mFreeMem(dbv.szVal.A);
+ DBVT_BLOB : mFreeMem(dbv.pbVal);
+ end;
+end;
+
+function ImportAction(actnode:HXML):integer;
+var
+ tmp:pWideChar;
+ act:tHKAction;
+ sub:HXML;
+begin
+ FillChar(act,SizeOf(act),0);
+ with xmlparser,act do
+ begin
+ flags:=ACF_ASSIGNED;
+ if StrToInt(getAttrValue(actnode,ioDisabled))=1 then
+ flags:=flags or ACF_DISABLED;
+
+ StrDupW(descr,getAttrValue(actnode,ioName));
+
+ actnode:=getChild(actnode,0);
+ tmp:=getName(actnode);
+MessageBoxW(0,tmp,'node',0);
+
+ // CONTACT
+ if StrCmpW(tmp,ioContactWindow)=0 then
+ begin
+ actionType:=ACT_CONTACT;
+ contact:=ImportContact(actnode);
+// contact:=StrToInt(getAttrValue(actnode,ioNumber));
+ if StrToInt(getAttrValue(actnode,ioKeepOnly))=1 then
+ flags:=flags or ACF_KEEPONLY;
+ end
+
+ // SERVICE
+ else if StrCmpW(tmp,ioCallService)=0 then
+ begin
+ actionType:=ACT_SERVICE;
+ FastWideToAnsi(getAttrValue(actnode,ioService),service);
+MessageBoxA(0,service,'service',0);
+ if StrToInt(getAttrValue(actnode,ioVariables))=1 then
+ flags2:=flags2 or ACF2_SRV_SRVC;
+
+ sub:=getNthChild(actnode,ioWParam,0);
+ if StrToInt(getAttrValue(sub,ioVariables))=1 then
+ flags2:=flags2 or ACF2_SRV_WPAR;
+ if StrToInt(getAttrValue(sub,ioHex))=1 then
+ flags2:=flags2 or ACF2_SRV_WHEX;
+ flags:=flags or ReadParam(sub,int_ptr(wparam),(flags2 and ACF2_SRV_WPAR)<>0);
+
+ sub:=getNthChild(actnode,ioLParam,0);
+ if StrToInt(getAttrValue(sub,ioVariables))=1 then
+ flags2:=flags2 or ACF2_SRV_LPAR;
+ if StrToInt(getAttrValue(sub,ioHex))=1 then
+ flags2:=flags2 or ACF2_SRV_LHEX;
+ flags:=flags or (ReadParam(sub,lparam,(flags2 and ACF2_SRV_LPAR)<>0) shl 1);
+
+ sub:=getNthChild(actnode,ioOutput,0);
+ if StrToInt(getAttrValue(sub,ioMessage))=1 then flags:=flags or ACF_INSERT;
+ if StrToInt(getAttrValue(sub,ioPopup ))=1 then flags:=flags or ACF_POPUP;
+ if StrToInt(getAttrValue(sub,ioMsgBox ))=1 then flags:=flags or ACF_MESSAGE;
+
+ if StrToInt(getAttrValue(sub,ioFree))=1 then flags2:=flags2 or ACF2_FREEMEM;
+
+ tmp:=getAttrValue(sub,ioType);
+ if lstrcmpiw(tmp,ioUnicode)=0 then flags:=flags or ACF_UNICODE+ACF_STRING
+ else if lstrcmpiw(tmp,ioAnsi )=0 then flags:=flags or ACF_STRING
+ else if lstrcmpiw(tmp,ioSigned )=0 then flags:=flags or ACF_SIGNED
+ else if lstrcmpiw(tmp,ioHex )=0 then flags:=flags or ACF_HEX
+ else if lstrcmpiw(tmp,ioStruct )=0 then flags:=flags or ACF_STRUCT
+ else if lstrcmpiw(tmp,ioInt )=0 then ;
+MessageBoxW(0,'','end',0);
+ end
+
+ // PROGRAM
+ else if StrCmpW(tmp,ioRunProgram)=0 then
+ begin
+ actionType:=ACT_PROGRAM;
+ StrDupW(prgname,getText(actnode));
+ StrDupW(args,getAttrValue(actnode,ioArgs));
+ if StrToInt(getAttrValue(actnode,ioCurrent))=1 then
+ flags:=flags or ACF_CURPATH;
+
+ if StrToInt(getAttrValue(actnode,ioParallel))=1 then
+ flags:=flags or ACF_PRTHREAD
+ else
+ time:=StrToInt(getAttrValue(actnode,ioWait));
+
+ if StrToInt(getAttrValue(actnode,ioFileVariable))=1 then
+ flags2:=flags2 or ACF2_PRG_PRG;
+
+ if StrToInt(getAttrValue(actnode,ioArgVariable))=1 then
+ flags2:=flags2 or ACF2_PRG_ARG;
+
+ tmp:=getAttrValue(actnode,ioWindow);
+ if lstrcmpiw(tmp,ioHidden )=0 then show:=SW_HIDE
+ else if lstrcmpiw(tmp,ioMinimized)=0 then show:=SW_SHOWMINIMIZED
+ else if lstrcmpiw(tmp,ioMaximized)=0 then show:=SW_SHOWMAXIMIZED
+ else show:=SW_SHOWNORMAL;
+ end
+
+ // INSERT TEXT
+ else if StrCmpW(tmp,ioInsertText)=0 then
+ begin
+ actionType:=ACT_TEXT;
+ tmp:=getAttrValue(actnode,ioObject);
+ if lstrcmpiw(tmp,ioClipboard)=0 then
+ begin
+ flags:=flags or ACF_CLIPBRD;
+ tmp:=getAttrValue(actnode,ioOper);
+ if lstrcmpiw(tmp,ioCopy)=0 then flags:=flags or ACF_COPYTO;
+// else if lstrcmpiw(tmp,'paste')=0 then ;
+ tmp:=getAttrValue(actnode,ioEnc);
+ if lstrcmpiw(tmp,ioAnsi)=0 then flags:=flags or ACF_ANSI;
+// else if lstrcmpiw(tmp,'unicode')=0 then ;
+ end
+ else
+ begin
+ StrDupW(text,getText(actnode));
+
+ if StrToInt(getAttrValue(actnode,ioVariables))=1 then
+ flags2:=flags2 or ACF2_TXT_TEXT;
+
+ if lstrcmpiw(tmp,ioFile)=0 then
+ begin
+
+ if StrToInt(getAttrValue(actnode,ioFileVariable))=1 then
+ flags2:=flags2 or ACF2_TXT_FILE;
+
+ flags:=flags or ACF_FILE;
+ StrDupW(tfile,getAttrValue(actnode,ioFile));
+ tmp:=getAttrValue(actnode,ioOper);
+ if lstrcmpiw(tmp,ioWrite )=0 then flags:=flags or ACF_FWRITE
+ else if lstrcmpiw(tmp,ioAppend)=0 then flags:=flags or ACF_FAPPEND;
+ case StrToInt(getAttrValue(actnode,ioEnc)) of
+ 0: flags:=flags or ACF_ANSI;
+ 1: flags:=flags or ACF_UTF8;
+ 2: flags:=flags or ACF_UTF8 or ACF_SIGN;
+ 3: flags:=flags or 0;
+ 4: flags:=flags or ACF_SIGN;
+ end;
+ end;
+ end;
+ end
+
+ // ADVANCED
+ else if StrCmpW(tmp,ioAdvanced)=0 then
+ begin
+ actionType:=ACT_ADVANCE;
+ sub:=getNthChild(actnode,ioIf,0);
+ if sub<>0 then
+ begin
+ tmp:=getAttrValue(sub,ioCond);
+ if lstrcmpiw(tmp,'gt' )=0 then condition:=condition or ADV_COND_GT
+ else if lstrcmpiw(tmp,'lt' )=0 then condition:=condition or ADV_COND_LT
+ else if lstrcmpiw(tmp,'eq' )=0 then condition:=condition or ADV_COND_EQ
+ else if lstrcmpiw(tmp,ioNop)=0 then ;
+
+ if StrToInt(getAttrValue(sub,ioNot))=1 then
+ condition:=condition or ADV_COND_NOT;
+
+ value:=StrToInt(getAttrValue(sub,ioValue));
+ end;
+
+ sub:=getNthChild(actnode,ioAct,0);
+ tmp:=getAttrValue(sub,ioType);
+ if lstrcmpiw(tmp,ioValue)=0 then
+ begin
+ action:=action or ADV_ACT_MATH;
+ tmp:=getAttrValue(sub,ioOper);
+ if lstrcmpiw(tmp,ioInverse)=0 then
+ oper:=Cardinal(aeNot)
+ else
+ begin
+ case tmp^ of
+ '+': oper:=Cardinal(aeAdd);
+ '-': oper:=Cardinal(aeSub);
+ '*': oper:=Cardinal(aeMul);
+ '\': oper:=Cardinal(aeDiv);
+ '%': oper:=Cardinal(aeMod);
+ '&': oper:=Cardinal(aeAnd);
+ '|': oper:=Cardinal(aeOr );
+ '^': oper:=Cardinal(aeXor);
+ '=': oper:=Cardinal(aeSet);
+ end;
+ mathval:=StrToInt(getAttrValue(sub,ioValue));
+ end;
+ end
+ else if lstrcmpiw(tmp,ioScript)=0 then
+ begin
+ if StrToInt(getAttrValue(sub,ioAsInt))<>0 then
+ flags:=flags or ACF_VARASINT;
+ action:=action or ADV_ACT_VARS;
+ StrDupW(varval,getText(sub));
+ end;
+
+ sub:=getNthChild(actnode,ioPost,0);
+ if sub<>0 then
+ begin
+ tmp:=getAttrValue(sub,ioOper);
+ if lstrcmpiw(tmp,ioBreak)=0 then action:=action or ADV_ACT_BREAK
+ else if lstrcmpiw(tmp,ioJump )=0 then action:=action or ADV_ACT_JUMP
+ else if lstrcmpiw(tmp,ioNop )=0 then ;
+
+ tmp:=getAttrValue(sub,ioValue);
+ case action and ADV_ACT_POST of
+ ADV_ACT_JUMP: StrDupW(operval,tmp);
+ end;
+ end;
+ end
+
+ // CHAIN
+ else if StrCmpW(tmp,ioLinkAction)=0 then
+ begin
+ actionType:=ACT_CHAIN;
+ StrDupW(actname,getText(actnode));
+ flags:=flags or ACF_BYNAME;
+ end
+
+ // DBRW
+ else if StrCmpW(tmp,ioProfile)=0 then
+ begin
+ actionType:=ACT_RW;
+ tmp:=getAttrValue(actnode,ioOper);
+ if lstrcmpiw(tmp,ioDelete)=0 then flags:=flags or ACF_DBDELETE
+ else if lstrcmpiw(tmp,ioWrite )=0 then flags:=flags or ACF_DBWRITE;
+// else if lstrcmpiw(tmp,ioRead)=0 then ;
+ tmp:=getAttrValue(actnode,ioContact);
+ if lstrcmpiw(tmp,ioCurrent)=0 then flags:=flags or ACF_CURRENT
+ else if lstrcmpiw(tmp,ioResult )=0 then flags:=flags or ACF_RESULT
+ else if lstrcmpiw(tmp,ioParam )=0 then flags:=flags or ACF_PARAM
+ else if lstrcmpiw(tmp,ioContact)=0 then
+ begin
+ contact:=ImportContact(actnode);
+ end;
+
+ FastWideToAnsi(getAttrValue(actnode,ioModule ),dbmodule);
+ FastWideToAnsi(getAttrValue(actnode,ioSetting),dbsetting);
+
+ if StrToInt(getAttrValue(actnode,ioFileVariable))=1 then flags2:=flags2 or ACF2_RW_MVAR;
+ if StrToInt(getAttrValue(actnode,ioArgVariable ))=1 then flags2:=flags2 or ACF2_RW_SVAR;
+ if StrToInt(getAttrValue(actnode,ioVariables ))=1 then flags2:=flags2 or ACF2_RW_TVAR;
+ if StrToInt(getAttrValue(actnode,ioHex ))=1 then flags2:=flags2 or ACF2_RW_HEX;
+
+ tmp:=getAttrValue(actnode,ioType);
+ if lstrcmpiw(tmp,ioByte )=0 then flags:=flags or ACF_DBBYTE
+ else if lstrcmpiw(tmp,ioWord )=0 then flags:=flags or ACF_DBWORD
+ else if lstrcmpiw(tmp,ioDword)=0 then
+ else // if lstrcmpiw(tmp,ioUnicode)=0 then
+ begin
+ if lstrcmpiw(tmp,ioAnsi)=0 then
+ flags:=flags or ACF_DBANSI
+ else
+ flags:=flags or ACF_DBUTEXT;
+ StrDupW(pWideChar(dbvalue),getText(actnode));
+ end;
+
+ if StrToInt(getAttrValue(actnode,ioLast))=1 then
+ flags:=flags or ACF_LAST
+ else if (flags and ACF_DBUTEXT)=0 then
+ begin
+ if (flags2 and ACF2_RW_TVAR)<>0 then
+ StrDupW(pWideChar(dbvalue),getText(actnode))
+ else
+ dbvalue:=StrToInt(getAttrValue(actnode,ioValue));
+ end;
+ end
+
+ // MessageBox
+ else if StrCmpW(tmp,ioMessageBox)=0 then
+ begin
+ actionType:=ACT_MESSAGE;
+ StrDupW(msgtitle,getAttrValue(actnode,ioTitle));
+ StrDupW(msgtext,getText(actnode));
+ boxopts:=StrToInt(getAttrValue(actnode,ioType));
+ if StrToInt(getAttrValue(actnode,ioArgVariable))=1 then flags2:=flags2 or ACF2_MSG_TXT;
+ if StrToInt(getAttrValue(actnode,ioVariables ))=1 then flags2:=flags2 or ACF2_MSG_TTL;
+ if StrToInt(getAttrValue(actnode,ioKeepLast ))=1 then flags :=flags or ACF_MSG_KEEP;
+ end
+
+ else
+ begin
+ actionType:=ACT_UNKNOWN;
+ result:=0;
+ Exit;
+ end;
+ end;
+ result:=NewAction(ActionList,MaxActions);
+ move(act,ActionList^[result],SizeOf(tHKAction));
+end;
+
+function Import(fname:PWideChar;aflags:dword):integer;
+var
+ f:THANDLE;
+ i,j:integer;
+ tmp,res:pWideChar;
+ root,actnode:HXML;
+ last,next:integer;
+ impact:integer;
+ buf:array [0..511] of WideChar;
+ oldid:dword;
+begin
+ result:=0;
+ for i:=0 to MaxGroups-1 do
+ with GroupList[i] do
+ if (flags and (ACF_IMPORT or ACF_ASSIGNED))=
+ (ACF_IMPORT or ACF_ASSIGNED) then
+ flags:=flags and not (ACF_IMPORT or ACF_OVERLOAD);
+
+ if (fname=nil) or (fname^=#0) then
+ exit;
+ i:=GetFSize(fname);
+ if i=0 then
+ exit;
+ mGetMem (res ,i+SizeOf(WideChar));
+ FillChar(res^,i+SizeOf(WideChar),0);
+ f:=Reset(fname);
+ BlockRead(f,res^,i);
+ CloseHandle(f);
+
+MessageBoxW(0,res,'SRC',0);
+ xmlparser.cbSize:={XML_API_SIZEOF_V1;//}SizeOf(XML_API_W);
+ CallService(MS_SYSTEM_GET_XI,0,lparam(@xmlparser));
+ with xmlparser do
+ begin
+ root:=parseString(ChangeUnicode(res),@i,nil);
+ j:=0;
+ impact:=imp_yes;
+ repeat
+ actnode:=getNthChild(root,ioAction,j);
+ if actnode=0 then break;
+MessageBoxW(0,'not zero','actnode',0);
+//?? if StrCmpW(getName(actnode),ioAction)<>0 then break;
+ tmp:=getAttrValue(actnode,ioName);
+MessageBoxW(0,tmp,'nodename',0);
+ if tmp<>nil then //!!
+ begin
+ i:=GetActIdxByName(tmp);
+ oldid:=$FFFFFFFF;
+ if i>=0 then
+ begin
+ if (impact<>imp_yesall) and (impact<>imp_noall) then
+ begin
+ StrCopyW(buf,TranslateW('Action "$" exists, do you want to rewrite it?'));
+ impact:=DialogBoxParam(hInstance,MAKEINTRESOURCE(IDD_ASK),0,
+ @QuestionDlg,TLPARAM(StrReplaceW(buf,'$',tmp)));
+ end;
+ if (impact=imp_yesall) or (impact=imp_yes) then
+ begin
+ oldid:=GroupList^[i].id;
+ FreeGroup(i);
+ end;
+ end;
+ if (i<0) or (impact=imp_yesall) or (impact=imp_yes) or (impact=imp_append) then
+ begin
+ with GroupList^[NewGroup(GroupList,MaxGroups)] do
+ begin
+ if (i>=0) and (oldid<>$FFFFFFFF) then // set old id to keep UseAction setting
+ begin
+ flags:=flags or ACF_IMPORT or ACF_OVERLOAD;
+ id:=oldid;
+ end;
+ flags:=flags or ACF_IMPORT;
+ if StrToInt(getAttrValue(actnode,ioDisabled))=1 then flags:=flags or ACF_DISABLED;
+ if StrToInt(getAttrValue(actnode,ioVolatile))=1 then flags:=flags or ACF_VOLATILE;
+ mFreeMem(descr);
+ StrDupW(descr,tmp);
+ i:=0;
+ last:=-1;
+MessageBoxW(0,descr,'descr',0);
+ repeat
+ next:=ImportAction(getChild(actnode,i));
+ if next=0 then
+ break;
+ if last<0 then
+ firstAction:=next
+ else
+ ActionList[last].next:=next;
+ last:=next;
+ inc(i);
+ until false;
+ inc(result);
+ end;
+ end;
+ end;
+ inc(j);
+ until false;
+ DestroyNode(root);
+ end;
+ mFreeMem(res);
+end;
+
+//--------------------------
+
+procedure WriteStruct(node:HXML;struct:PWideChar);
+{var
+ sub:HXML;
+ ppc,value,lsrc,p,pc:pWideChar;
+ i,len:integer;
+ typ:integer;
+}
+begin
+(*
+ if struct=nil then exit;
+
+ mGetMem(pc,4096);
+ lsrc:=pWideChar(struct);
+ with xmlparser do
+ begin
+{
+ if lsrc^=char_packed then
+ begin
+ AddAttrInt(node,ioPacked,1);
+ inc(lsrc);
+ end;
+}
+ while lsrc^<>#0 do
+ begin
+ sub:=AddChild(node,ioItem,nil);
+ p:=StrScanW(lsrc,'|');
+ StrCopyW(pc,lsrc,p-lsrc);
+
+ ppc:=pc;
+ if ppc^=char_return then
+ begin
+ AddAttrInt(sub,ioReturn,1);
+ inc(ppc);
+ end;
+
+ if ppc^=char_script then
+ begin
+ AddAttrInt(sub,ioScript,1);
+ inc(ppc);
+ end;
+
+ typ:=GetOneElement(ppc,len,value);
+
+ i:=0;
+ while i<MaxStructTypes do
+ begin
+ if StructElems[i].typ=typ then //!!
+ break;
+ inc(i);
+ end;
+ AddAttr(sub,ioType,StructElems[i].short);
+
+
+ case typ of
+ SST_LAST,SST_PARAM: ;
+ SST_BYTE,SST_WORD,SST_DWORD,SST_QWORD,SST_NATIVE: begin
+ AddAttr(sub,ioValue,value);
+ end;
+ SST_BARR,SST_WARR,SST_BPTR,SST_WPTR: begin
+ AddAttrInt(sub,ioLength,len);
+ AddAttr (sub,ioValue ,value);
+ end;
+ end;
+
+ if p=nil then break;
+ lsrc:=p+1;
+ end;
+ end;
+ mFreeMem(pc);
+*)
+end;
+
+procedure WriteParam(node:HXML;flags,param:int_ptr;flags2:integer);
+var
+ s:pWideChar;
+ tmp:pWideChar;
+begin
+ with xmlparser do
+ begin
+ if (flags and ACF_WPARNUM)<>0 then
+ begin
+ s:=ioNumber;
+ if (flags2 and ACF2_SRV_WPAR)<>0 then
+ AddAttr(node,ioValue,PWideChar(param))
+ else
+ AddAttrInt(node,ioValue,param);
+ end
+ else if (flags and ACF_WCURRENT)<>0 then
+ begin
+ s:=ioCurrent;
+ end
+ else if (flags and ACF_WRESULT)<>0 then
+ begin
+ s:=ioResult;
+ end
+ else if (flags and ACF_WPARAM)<>0 then
+ begin
+ s:=ioParam;
+ end
+ else if (flags and ACF_WSTRUCT)<>0 then
+ begin
+ s:=ioStruct;
+ WriteStruct(node,pointer(param));
+ end
+ else if (flags and ACF_WUNICODE)<>0 then
+ begin
+ s:=ioUnicode;
+ AddAttr(node,ioValue,PWideChar(param));
+ end
+ else
+ begin
+ s:=ioAnsi;
+ AddAttr(node,ioValue,AnsiToWide(PAnsiChar(param),tmp));
+ mFreeMem(tmp);
+ end;
+ AddAttr(node,ioType,s);
+ end;
+end;
+
+function ExportContact(node:HXML;hContact:THANDLE):integer;
+var
+ proto,uid:pAnsiChar;
+ cws:TDBVARIANT;
+ p1:pAnsiChar;
+ p:pWideChar;
+ tmpbuf:array [0..63] of WideChar;
+ is_chat:boolean;
+begin
+ result:=0;
+ proto:=GetContactProtoAcc(hContact);
+ if proto<>nil then
+ begin
+ is_chat:=IsChat(hContact);
+ if is_chat then
+ begin
+ with xmlparser do
+ begin
+ p:=DBReadUnicode(hContact,proto,'ChatRoomID');
+ addAttr(node,ioCUID,p);
+ mFreeMem(p);
+ end;
+ result:=1;
+ end
+ else
+ begin
+ uid:=pAnsiChar(CallProtoService(proto,PS_GETCAPS,PFLAG_UNIQUEIDSETTING,0));
+ if DBReadSetting(hContact,proto,uid,@cws)=0 then
+ begin
+ result:=1;
+ with xmlparser do
+ begin
+ addAttrInt(node,ioCUIDType,cws._type);
+ case cws._type of
+ DBVT_BYTE : AddAttrInt(node,ioCUID,cws.bVal);
+ DBVT_WORD : AddAttrInt(node,ioCUID,cws.wVal);
+ DBVT_DWORD : AddAttrInt(node,ioCUID,cws.dVal);
+ DBVT_ASCIIZ: begin
+ AddAttr(node,ioCUID,FastAnsiToWide(cws.szVal.A,p));
+ mFreeMem(p);
+ end;
+ DBVT_UTF8 : begin
+ AddAttr(node,ioCUID,UTF8ToWide(cws.szVal.A,p));
+ // AddAttr(node,'cuid',FastAnsiToWide(cws.szVal.A,p));
+ mFreeMem(p);
+ end;
+ DBVT_WCHAR : AddAttr(node,ioCUID,cws.szVal.W);
+ DBVT_BLOB : begin
+ p1:=Base64Encode(cws.pbVal,cws.cpbVal);
+ AddAttr(node,ioCUID,FastAnsiToWide(p1,p));
+ mFreeMem(p1);
+ mFreeMem(p);
+ end;
+ end;
+ end;
+ end;
+ DBFreeVariant(@cws);
+ end;
+ if result<>0 then
+ begin
+ with xmlparser do
+ begin
+ addAttr (node,ioCProto,FastAnsiToWideBuf(proto,tmpbuf));
+ addAttrInt(node,ioIsChat,ord(is_chat));
+ end;
+ end;
+ end;
+end;
+
+procedure WriteAction(actnode:HXML;idx:integer);
+var
+ sub, act: HXML;
+ s:PWideChar;
+ i:integer;
+ tmp:pWideChar;
+begin
+ with xmlparser,ActionList[idx] do
+ begin
+ actnode:=AddChild(actnode,ioSubAction,nil);
+ if descr<>nil then
+ AddAttr(actnode,ioName,descr);
+ if (flags and ACF_DISABLED)<>0 then
+ AddAttrInt(actnode,ioDisabled,1);
+
+ case actionType of
+// ----- CONTACT -----
+ ACT_CONTACT: begin
+ sub:=AddChild(actnode,ioContactWindow,nil);
+ ExportContact(sub,contact);
+// AddAttrInt(sub,ioNumber,0); // contact
+ if (flags and ACF_KEEPONLY)<>0 then AddAttrInt(sub,ioKeepOnly,1);
+ end;
+// ----- SERVICE -----
+ ACT_SERVICE: begin
+ sub:=AddChild(actnode,ioCallService,nil);
+ AddAttr(sub,ioService,FastAnsiToWide(service,tmp));
+ if (flags2 and ACF2_SRV_SRVC)<>0 then AddAttrInt(sub,ioVariables,1);
+ mFreeMem(tmp);
+ act:=AddChild(sub,ioWParam,nil); WriteParam(act,flags ,wparam,flags2);
+ if (flags2 and ACF2_SRV_WPAR)<>0 then AddAttrInt(act,ioVariables,1);
+ if (flags2 and ACF2_SRV_WHEX)<>0 then AddAttrInt(act,ioHex ,1);
+ act:=AddChild(sub,ioLParam,nil); WriteParam(act,flags shr 1,lparam,flags2 shr 1);
+ if (flags2 and ACF2_SRV_LPAR)<>0 then AddAttrInt(act,ioVariables,1);
+ if (flags2 and ACF2_SRV_LHEX)<>0 then AddAttrInt(act,ioHex ,1);
+
+ act:=AddChild(sub,ioOutput,nil);
+ if (flags and (ACF_MESSAGE+ACF_POPUP+ACF_INSERT))<>0 then
+ begin
+ if (flags and ACF_INSERT )<>0 then AddAttrInt(act,ioMessage,1);
+ if (flags and ACF_POPUP )<>0 then AddAttrInt(act,ioPopup ,1);
+ if (flags and ACF_MESSAGE)<>0 then AddAttrInt(act,ioMsgBox ,1);
+ end;
+
+ if (flags2 and ACF2_FREEMEM)<>0 then AddAttrInt(sub,ioFree,1);
+
+ if (flags and ACF_STRUCT)<>0 then
+ s:=ioStruct
+ else if (flags and ACF_STRING)<>0 then
+ begin
+ if (flags and ACF_UNICODE)<>0 then
+ s:=ioUnicode
+ else
+ s:=ioAnsi;
+ end
+ else
+ begin
+ if (flags and ACF_SIGNED)<>0 then s:=ioSigned
+ else if (flags and ACF_HEX )<>0 then s:=ioHex
+ else s:=ioInt;
+ end;
+ AddAttr(act,ioType,s);
+ end;
+// ----- PROGRAM -----
+ ACT_PROGRAM: begin
+ sub:=AddChild(actnode,ioRunProgram,prgname);
+ if args<>nil then
+ AddAttr(sub,ioArgs,args);
+ if (flags and ACF_CURPATH)<>0 then AddAttrInt(sub,ioCurrent,1);
+ if (flags and ACF_PRTHREAD)=0 then AddAttrInt(sub,ioWait,time)
+ else AddAttrInt(sub,ioParallel,1);
+
+ if (flags2 and ACF2_PRG_PRG)<>0 then AddAttrInt(sub,ioFileVariable,1);
+ if (flags2 and ACF2_PRG_ARG)<>0 then AddAttrInt(sub,ioArgVariable ,1);
+
+ case show of
+ SW_HIDE : s:=ioHidden;
+ SW_SHOWMINIMIZED: s:=ioMinimized;
+ SW_SHOWMAXIMIZED: s:=ioMaximized;
+ else
+ s:=ioNormal;
+ end;
+ AddAttr(sub,ioWindow,s);
+ end;
+// ----- TEXT -----
+ ACT_TEXT: begin
+ if (flags and ACF_CLIPBRD)<>0 then
+ tmp:=nil
+ else
+ tmp:=text;
+ sub:=AddChild(actnode,ioInsertText,tmp);
+ if (flags and ACF_CLIPBRD)<>0 then
+ begin
+ AddAttr(sub,ioObject,ioClipboard);
+ if (flags and ACF_COPYTO)<>0 then
+ s:=ioCopy
+ else
+ s:=ioPaste;
+ AddAttr(sub,ioOper,s);
+ if (flags and ACF_ANSI)=0 then
+ s:=ioUnicode
+ else
+ s:=ioAnsi;
+ AddAttr(sub,ioEnc,s);
+ end
+ else
+ begin
+ if (flags and ACF_FILE)<>0 then
+ begin
+ if (flags2 and ACF2_TXT_FILE)<>0 then
+ AddAttrInt(sub,ioFileVariable,1);
+ AddAttr(sub,ioObject,ioFile);
+ AddAttr(sub,ioFile,tfile);
+ if (flags and ACF_FWRITE )<>0 then AddAttr(sub,ioOper,ioWrite)
+ else if (flags and ACF_FAPPEND)<>0 then AddAttr(sub,ioOper,ioAppend);
+
+ if (flags and ACF_ANSI)<>0 then
+ i:=0
+ else if (flags and ACF_UTF8)<>0 then
+ begin
+ if (flags and ACF_SIGN)<>0 then
+ i:=2
+ else
+ i:=1;
+ end
+ else if (flags and ACF_SIGN)<>0 then
+ i:=4
+ else
+ i:=3;
+ AddAttrInt(sub,ioEnc,i);
+ end
+ else
+ AddAttr(sub,ioObject,ioWindow);
+
+ if (flags2 and ACF2_TXT_TEXT)<>0 then
+ AddAttrInt(sub,ioVariables,1);
+ end;
+ end;
+// ----- ADVANCED -----
+ ACT_ADVANCE: begin
+ sub:=AddChild(actnode,ioAdvanced,nil);
+ if lobyte(condition)<>0 then
+ begin
+ act:=AddChild(sub,ioIf,nil);
+ if (lobyte(condition) and ADV_COND_NOT)<>0 then
+ AddAttrInt(act,ioNot,1);
+ case lobyte(condition) and not ADV_COND_NOT of
+ ADV_COND_GT: s:='gt';
+ ADV_COND_LT: s:='lt';
+ ADV_COND_EQ: s:='eq';
+ else
+ s:=ioNop;
+ end;
+ AddAttr(act,ioCond,s);
+ AddAttrInt(act,ioValue,value);
+ end;
+
+ if (action and not 3)<>ADV_ACT_VARS then
+ tmp:=nil
+ else
+ tmp:=varval;
+ act:=AddChild(sub,ioAct,tmp);
+ case action and ADV_ACTION of
+ ADV_ACT_MATH: begin
+ AddAttr(act,ioType,ioValue);
+ if tAdvExpr(oper)=aeNot then
+ AddAttr(act,ioOper,ioInverse)
+ else
+ begin
+ case tAdvExpr(oper) of
+ aeAdd: s:='+';
+ aeSub: s:='-';
+ aeMul: s:='*';
+ aeDiv: s:='\';
+ aeMod: s:='%';
+ aeAnd: s:='&';
+ aeOr : s:='|';
+ aeXor: s:='^';
+ aeSet: s:='=';
+ else
+ s:=nil;
+ end;
+ AddAttr(act,ioOper,s);
+ AddAttrInt(act,ioValue,mathval);
+ end;
+ end;
+ ADV_ACT_VARS: begin
+ if (flags and ACF_VARASINT)<>0 then
+ AddAttrInt(act,ioAsInt,1);
+ AddAttr(act,ioType,ioScript);
+ end;
+ end;
+
+ if (action and ADV_ACT_POST)<>0 then
+ begin
+ act:=AddChild(sub,ioPost,nil);
+ case action and ADV_ACT_POST of
+ ADV_ACT_BREAK: s:=ioBreak;
+ ADV_ACT_JUMP : begin
+ s:=ioJump;
+ AddAttr(act,ioValue,operval);
+ end;
+ else
+ s:=ioNop
+ end;
+ AddAttr(act,ioOper,s);
+ end;
+ //!!
+ end;
+// ----- LINK -----
+ ACT_CHAIN: begin
+ if (flags and ACF_BYNAME)<>0 then
+ s:=actname
+ else
+ s:=GetActNameById(id);
+ AddChild(actnode,ioLinkAction,s);
+ end;
+// ----- DATABASE -----
+ ACT_RW: begin
+ if ((flags and ACF_DBUTEXT)=0) and ((flags2 and ACF2_RW_TVAR)=0) then
+ tmp:=nil
+ else
+ tmp:=pWideChar(dbvalue);
+ sub:=AddChild(actnode,ioProfile,tmp);
+ if (flags and ACF_DBDELETE)<>0 then s:=ioDelete
+ else if (flags and ACF_DBWRITE )<>0 then s:=ioWrite
+ else s:=ioRead;
+ AddAttr(sub,ioOper,s);
+ if (flags and ACF_CURRENT)<>0 then s:=ioCurrent
+ else if (flags and ACF_RESULT )<>0 then s:=ioResult
+ else if (flags and ACF_PARAM )<>0 then s:=ioParam
+ else
+ begin
+ s:=ioContact;
+ ExportContact(sub,dbcontact);
+ end;
+ AddAttr(sub,ioContact,s);
+ AddAttr(sub,ioModule ,FastAnsiToWide(dbmodule ,tmp)); mFreeMem(tmp);
+ AddAttr(sub,ioSetting,FastAnsiToWide(dbsetting,tmp)); mFreeMem(tmp);
+
+ if (flags and ACF_DBANSI )=ACF_DBANSI then s:=ioAnsi
+ else if (flags and ACF_DBBYTE )=ACF_DBBYTE then s:=ioByte
+ else if (flags and ACF_DBWORD )=ACF_DBWORD then s:=ioWord
+ else if (flags and ACF_DBUTEXT)= 0 then s:=ioDword
+ else s:=ioUnicode;
+ AddAttr(sub,ioType,s);
+
+ if (flags2 and ACF2_RW_MVAR)<>0 then AddAttrInt(sub,ioFileVariable,1);
+ if (flags2 and ACF2_RW_SVAR)<>0 then AddAttrInt(sub,ioArgVariable ,1);
+ if (flags2 and ACF2_RW_TVAR)<>0 then AddAttrInt(sub,ioVariables ,1);
+ if (flags2 and ACF2_RW_HEX )<>0 then AddAttrInt(sub,ioHex ,1);
+
+ if ( flags and ACF_LAST )<>0 then AddAttrInt(sub,ioLast ,1)
+ else if ((flags and ACF_DBUTEXT )=0) and
+ ((flags2 and ACF2_RW_TVAR)=0) then AddAttrInt(sub,ioValue,dbvalue);
+ end;
+// ----- MESSAGEBOX -----
+ ACT_MESSAGE: begin
+ sub:=AddChild(actnode,ioMessageBox,msgtext);
+ if (flags2 and ACF2_MSG_TTL)<>0 then AddAttrInt(sub,ioVariables ,1);
+ if (flags2 and ACF2_MSG_TXT)<>0 then AddAttrInt(sub,ioArgVariable,1);
+ if (flags and ACF_MSG_KEEP)<>0 then AddAttrInt(sub,ioKeepLast ,1);
+ AddAttr (sub,ioTitle,msgtitle);
+ AddAttrInt(sub,ioType ,boxopts);
+ end;
+ end;
+ end;
+end;
+
+procedure Export({act:integer;}fname:pWideChar;aflags:dword);
+var
+ i:integer;
+ f:THANDLE;
+ root,actnode:HXML;
+ res:pWideChar;
+ act:integer;
+begin
+ xmlparser.cbSize:={XML_API_SIZEOF_V1;//}SizeOf(XML_API_W);
+ CallService(MS_SYSTEM_GET_XI,0,lparam(@xmlparser));
+ root:=0;
+ with xmlparser do
+ begin
+ i:=0;
+ if (aflags and ACIO_APPEND)<>0 then
+ begin
+ i:=GetFSize(fname);
+ if i<>0 then
+ begin
+ mGetMem (res ,i+SizeOf(WideChar));
+ FillChar(res^,i+SizeOf(WideChar),0);
+ f:=Reset(fname);
+ BlockRead(f,res^,i);
+ CloseHandle(f);
+ root:=parseString(res,@i,nil);
+ mFreeMem(res);
+ i:=1;
+ end;
+ end;
+ if i=0 then // new file
+ root:=CreateNode(ioRoot,nil,false);
+
+ for act:=0 to MaxGroups-1 do
+ if ((aflags and ACIO_SELECTED)=0) or
+ ((GroupList[act].flags and (ACF_EXPORT or ACF_ASSIGNED))=
+ (ACF_EXPORT or ACF_ASSIGNED)) then
+ begin
+// GroupList[act].flags:=GroupList[act].flags and not ACF_EXPORT;
+ actnode:=addChild(root,ioAction,nil);
+ AddAttr(actnode,ioName,GroupList[act].descr);
+ if (GroupList[act].flags and ACF_DISABLED)<>0 then
+ AddAttrInt(actnode,ioDisabled,1);
+
+ i:=GroupList[act].firstAction;
+ if i<>0 then
+ repeat
+ WriteAction(actnode,i);
+ i:=ActionList[i].next;
+ until i=0;
+ end;
+
+ res:=toString(root,@i);
+ if i>0 then
+ begin
+ f:=Rewrite(fname);
+ BlockWrite(f,res^,i*SizeOf(WideChar));
+ CloseHandle(f);
+ end;
+ xmlparser.FreeMem(res);
+ DestroyNode(root);
+ end;
+end;
+
+function ActInOut(wParam:WPARAM;lParam:LPARAM):int_ptr; cdecl;
+begin
+ if (wParam and ACIO_EXPORT)=0 then
+ begin
+ result:=Import(pWideChar(lParam),wParam);
+ end
+ else
+ begin
+ result:=1;
+ Export(pWideChar(lParam),wParam);
+ end;
+ NotifyEventHooks(hevinout,wParam,lParam);
+end;
diff --git a/plugins/Actman/i_opt_dlg.inc b/plugins/Actman/i_opt_dlg.inc
new file mode 100644
index 0000000000..8b9e3fb32b
--- /dev/null
+++ b/plugins/Actman/i_opt_dlg.inc
@@ -0,0 +1,215 @@
+{}
+const
+ etHK = 1; // Groups changed
+ etACT = 2; // Actions changed
+const
+ ACI_APPLY :PAnsiChar = 'ACI_Apply';
+ ACI_NEW :PAnsiChar = 'ACI_New';
+ ACI_UP :PAnsiChar = 'ACI_Up';
+ ACI_DOWN :PAnsiChar = 'ACI_Down';
+ ACI_DELETE :PAnsiChar = 'ACI_Delete';
+ ACI_RELOAD :PAnsiChar = 'ACI_Reload';
+ ACI_TEST :PAnsiChar = 'ACI_Test';
+ ACI_IMPORT :PAnsiChar = 'ACI_Import';
+ ACI_EXPORT :PAnsiChar = 'ACI_Export';
+const
+ ACI_CONTACT = 'ACI_Contact';
+ ACI_SERVICE = 'ACI_Service';
+ ACI_PROGRAM = 'ACI_Program';
+ ACI_INSERT = 'ACI_Insert';
+ ACI_ADVANCE = 'ACI_Advanced';
+ ACI_CHAIN = 'ACI_Chain';
+ ACI_RW = 'ACI_Database';
+ ACI_MESSAGE = 'ACI_Message';
+
+ ACI_FORMAT = 'ACI_Format';
+
+ ACI_VAR_UNCHECKED = 'ACI_VarUnChecked';
+ ACI_VAR_CHECKED = 'ACI_VarChecked';
+
+const
+ sresInt = 0;
+ sresHex = 1;
+ sresString = 2;
+ sresStruct = 3;
+type
+ tActId = record
+ code:dword;
+ id :dword;
+ icon:PAnsiChar;
+ text:PAnsiChar;
+ end;
+const
+ ActIds:array [0..ACT_MAXTYPE-1] of tActId = (
+ (code:ACT_CONTACT; id:IDI_CONTACT; icon:ACI_CONTACT; text:'Open contact window'),
+ (code:ACT_SERVICE; id:IDI_SERVICE; icon:ACI_SERVICE; text:'Call service'),
+ (code:ACT_PROGRAM; id:IDI_PROGRAM; icon:ACI_PROGRAM; text:'Execute program'),
+ (code:ACT_TEXT ; id:IDI_INSERT ; icon:ACI_INSERT ; text:'Insert text'),
+ (code:ACT_ADVANCE; id:IDI_ADVANCE; icon:ACI_ADVANCE; text:'Advanced'),
+ (code:ACT_CHAIN ; id:IDI_CHAIN ; icon:ACI_CHAIN ; text:'Link to action'),
+ (code:ACT_RW ; id:IDI_RW ; icon:ACI_RW ; text:'Profile'),
+ (code:ACT_MESSAGE; id:IDI_MESSAGE; icon:ACI_MESSAGE; text:'MessageBox'));
+
+procedure RegisterIcon(var sid:TSKINICONDESC;id:uint_ptr;name:PAnsiChar;descr:PAnsiChar);
+var
+ buf:array [0..63] of WideChar;
+begin
+ sid.hDefaultIcon :=LoadImage(hInstance,MAKEINTRESOURCE(id),IMAGE_ICON,16,16,0);
+ sid.pszName :=name;
+ sid.szDescription.w:=FastAnsiToWideBuf(descr,buf);
+ Skin_AddIcon(@sid);
+ DestroyIcon(sid.hDefaultIcon);
+end;
+
+procedure RegisterIcons;
+var
+ sid:TSKINICONDESC;
+ i:integer;
+begin
+ FillChar(sid,SizeOf(TSKINICONDESC),0);
+ sid.cbSize :=SizeOf(TSKINICONDESC);
+ sid.cx :=16;
+ sid.cy :=16;
+ sid.flags :=SIDF_UNICODE;
+ sid.szSection.w:='Actions';
+
+ RegisterIcon(sid,IDI_APPLY ,ACI_APPLY ,'Apply');
+ RegisterIcon(sid,IDI_NEW ,ACI_NEW ,'New');
+ RegisterIcon(sid,IDI_DELETE ,ACI_DELETE ,'Delete');
+ RegisterIcon(sid,IDI_UP ,ACI_UP ,'Up');
+ RegisterIcon(sid,IDI_DOWN ,ACI_DOWN ,'Down');
+ RegisterIcon(sid,IDI_RELOAD ,ACI_RELOAD ,'Reload');
+ RegisterIcon(sid,IDI_TEST ,ACI_TEST ,'Test');
+ RegisterIcon(sid,IDI_IMPORT ,ACI_IMPORT ,'Import');
+ RegisterIcon(sid,IDI_EXPORT ,ACI_EXPORT ,'Export');
+
+ RegisterIcon(sid,IDI_FORMAT ,ACI_FORMAT ,'Contact list format');
+
+ for i:=0 to ACT_MAXTYPE-1 do
+ with ActIds[i] do
+ RegisterIcon(sid,id,icon,text);
+
+ sid.cx:=8;
+ sid.cy:=8;
+ RegisterIcon(sid,IDI_VAR_CHECKED ,ACI_VAR_CHECKED ,'Use Variables');
+ RegisterIcon(sid,IDI_VAR_UNCHECKED,ACI_VAR_UNCHECKED,'Don''t use Variables');
+end;
+
+procedure SetStart;
+begin
+ if NewGroupList=nil then
+ begin
+ NewGroupList:=GroupList;
+ NewMaxGroups:=MaxGroups;
+ end;
+ if NewActionList=nil then
+ begin
+ NewActionList:=ActionList;
+ NewMaxActions:=MaxActions;
+ end;
+end;
+
+procedure SetChanged(wnd:HWND;atype:integer);
+begin
+ SendMessage(GetParent(wnd),PSM_CHANGED,0,0);
+ if ((atype and etHK )<>0) and (NewGroupList =GroupList ) then NewGroupList :=CloneGroupList;
+ if ((atype and etACT)<>0) and (NewActionList=ActionList) then NewActionList:=CloneActionList;
+end;
+
+procedure SetSave(Dialog:HWND;curIdx:integer);
+var
+ i,j:integer;
+ li:LV_ITEMW;
+ wnd:HWND;
+begin
+ if NewGroupList<>GroupList then
+ begin
+
+ DestroyGroups(GroupList,MaxGroups);
+ wnd:=GetDlgItem(Dialog,IDC_ACTION_GROUP);
+ j:=SendMessageW(wnd,LVM_GETITEMCOUNT,0,0);
+ MaxGroups:=j;
+ if j>0 then
+ begin
+ GetMem (GroupList ,MaxGroups*SizeOf(tHKRecord));
+ FillChar(GroupList^,MaxGroups*SizeOf(tHKRecord),0);
+ li.mask :=LVIF_PARAM;
+ li.iSubItem:=0;
+ for i:=0 to j-1 do
+ begin
+ li.iItem:=i;
+ SendMessageW(wnd,LVM_GETITEMW,0,lparam(@li)); // GetLParam(wnd,i);
+ move(NewGroupList^[li.lParam],GroupList^[i],SizeOf(tHKRecord));
+ li.lParam:=i;
+ SendMessageW(wnd,LVM_SETITEMW,0,lparam(@li));
+ end;
+ end
+ else
+ GroupList:=nil;
+
+ FreeMem(NewGroupList);
+ NewGroupList:=GroupList;
+ NewMaxGroups:=MaxGroups;
+ end;
+end;
+
+procedure SetCancel;
+begin
+ if NewActionList<>nil then
+ begin
+ if (NewActionList<>ActionList) then
+ DestroyActions(NewActionList,NewMaxActions);
+ NewActionList:=nil;
+ end;
+ if NewGroupList<>nil then
+ begin
+ if (NewGroupList<>GroupList) then
+ DestroyGroups(NewGroupList,NewMaxGroups);
+ NewGroupList:=nil;
+ end;
+end;
+
+{$include i_opt_dlg2.inc}
+
+function OnOptInitialise(wParam:WPARAM;lParam:LPARAM):int;cdecl;
+var
+ odp:TOPTIONSDIALOGPAGE;
+ ptr:pActionLink;
+ tmpl:pAnsiChar;
+ name:pansiChar;
+ proc:pointer;
+ i:integer;
+begin
+ result:=0;
+ NoDescription :=TranslateW('No Description');
+ StrCopyW(xmlfilename,'c:\export.xml');
+
+ DoInitCommonControls(ICC_USEREX_CLASSES);
+
+ FillChar(odp,SizeOf(odp),0);
+ odp.cbSize :=SizeOf(odp);
+ odp.flags :=ODPF_BOLDGROUPS or ODPF_EXPERTONLY;
+ odp.Position :=900003000;
+ odp.hInstance :=hInstance;
+ odp.szGroup.a :='Services';
+ odp.szTitle.a :='Actions';
+ odp.szTab.a :='Actions';
+ odp.pfnDlgProc :=@DlgProcOpt2;
+ odp.pszTemplate:=PAnsiChar(IDD_ACTION);
+ Options_AddPage(wParam,@odp);
+
+ ptr:=ActionLink;
+ while ptr<>nil do
+ begin
+ if @ptr^.AddOption<>nil then
+ begin
+ i:=ptr^.AddOption(tmpl,proc,name);
+ odp.pszTemplate:=tmpl;
+ odp.pfnDlgProc :=proc;
+ odp.szTab.a :=name;
+ Options_AddPage(wParam,@odp);
+ if i>0 then continue;
+ end;
+ ptr:=ptr^.Next;
+ end;
+end;
diff --git a/plugins/Actman/i_opt_dlg2.inc b/plugins/Actman/i_opt_dlg2.inc
new file mode 100644
index 0000000000..3c6b4e974b
--- /dev/null
+++ b/plugins/Actman/i_opt_dlg2.inc
@@ -0,0 +1,2109 @@
+{}
+
+const
+ inoutfilter:pWideChar = 'XML files'#0'*.xml'#0'All files'#0'*.*'#0#0;
+const
+ NoChainText:PWideChar = 'not defined';
+const
+ ActionNames:array [0..ACT_MAXTYPE] of pWideChar=(
+ 'Unknown','Contact','Service','Program','Text','Advanced','Action','Profile','Message');
+const
+ checknames:array [BST_UNCHECKED..BST_CHECKED] of PAnsiChar=(
+ ACI_VAR_UNCHECKED,ACI_VAR_CHECKED);
+const
+ MaxDescrLen = 128;
+const
+ hlpContact = 0;
+ hlpService = 1;
+ hlpProgram = 2;
+ hlpText = 3;
+ hlpAdvance = 4;
+ hlpChain = 5;
+ hlpDBRW = 6;
+ hlpMessage = 7;
+ hlpVariables = 30;
+ hlpAdvVariables = 31;
+const
+ ptNumber = 0;
+ ptString = 1;
+ ptUnicode = 2;
+ ptCurrent = 3;
+ ptResult = 4;
+ ptParam = 5;
+ ptStruct = 6;
+
+var
+ wstruct,lstruct:pAnsiChar;
+ DontReact:bool;
+ OldGroupTableProc,
+ OldActTableProc:pointer;
+ ChMask:dword;
+
+function GetNumValue(wnd:HWND;usevar:boolean;var dst):boolean;
+var
+ tmp:pWideChar;
+begin
+ result:=false;
+ pWideChar(dst):=GetDlgText(wnd);
+ if Pointer(dst)=nil then exit;
+ if not usevar then
+ begin
+ tmp:=PWideChar(dst);
+ if pWideChar(dst)^='$' then
+ begin
+ integer(dst):=HexToInt(pWideChar(dst)+1);
+ result:=true;
+ end
+ else
+ integer(dst):=StrToInt(pWideChar(dst));
+ mFreeMem(tmp);
+ end;
+end;
+
+function GetGroupName(id:dword):pWideChar;
+var
+ i:integer;
+begin
+ for i:=0 to NewMaxGroups-1 do
+ begin
+ if ((NewGroupList^[i].flags and ACF_ASSIGNED)<>0) and (id=NewGroupList^[i].id) then
+ begin
+ result:=NewGroupList^[i].descr;
+ exit;
+ end;
+ end;
+ result:=NoChainText;
+end;
+
+function AddGroup(Dialog:HWND;HKnum:dword):integer;
+var
+ li:LV_ITEMW;
+ list:HWND;
+begin
+ with NewGroupList^[HKnum] do
+ begin
+ if (flags and ACF_ASSIGNED)<>0 then
+ begin
+ list:=GetDlgItem(Dialog,IDC_ACTION_GROUP);
+ li.mask :=LVIF_PARAM+LVIF_TEXT;
+ li.iItem :=SendMessage(list,LVM_GETNEXTITEM,-1,LVNI_FOCUSED)+1;
+ li.iSubItem :=0;
+ li.lParam :=HKnum;
+ if descr=nil then
+ li.pszText:=NoDescription
+ else
+ li.pszText:=descr;
+ li.iItem :=SendMessageW(list,LVM_INSERTITEMW,0,lparam(@li));
+ if li.iItem>0 then
+ dec(li.iItem);
+ ListView_SetItemState(list,li.iItem,LVIS_FOCUSED or LVIS_SELECTED,
+ LVIS_FOCUSED or LVIS_SELECTED);
+ result:=li.iItem;
+ end
+ else
+ result:=-1;
+ end;
+end;
+
+// Fill action type combobox
+procedure FillActTypeList(list:hwnd);
+var
+ cbei:TCOMBOBOXEXITEMW;
+ il:HIMAGELIST;
+ i:integer;
+ buf:array [0..127] of WideChar;
+begin
+ SendMessage(list,CB_RESETCONTENT,0,0);
+ il:=ImageList_Create(16,16,ILC_COLOR32 or ILC_MASK,0,1);
+
+ cbei.mask:=CBEIF_IMAGE or CBEIF_SELECTEDIMAGE or CBEIF_TEXT; //!!
+ for i:=0 to ACT_MAXTYPE-1 do
+ begin
+ ImageList_AddIcon(il,CallService(MS_SKIN2_GETICON,0,lparam(ActIds[i].icon)));
+
+ cbei.pszText :=TranslateW(FastAnsiToWideBuf(ActIds[i].text,buf));
+ cbei.iItem :=i;
+ cbei.iImage :=i;
+ cbei.iSelectedImage:=i;
+ if SendMessageW(list,CBEM_INSERTITEMW,0,lparam(@cbei))=-1 then break;
+ end;
+ ImageList_Destroy(SendMessage(list,CBEM_SETIMAGELIST,0,il));
+ SendMessage(list,CB_SETCURSEL,0,0);
+end;
+
+procedure FillSubList(Dialog:hwnd);
+var
+ list,wnd:HWND;
+ i,act:integer;
+ arr:array [0..127] of WideChar;
+ li:LV_ITEMW;
+begin
+ wnd:=GetDlgItem(Dialog,IDC_ADV_VAL2);
+
+ SendMessage(wnd,CB_RESETCONTENT,0,0);
+
+ list:=GetDlgItem(Dialog,IDC_ACTION_LIST);
+ act:=SendMessageW(list,LVM_GETITEMCOUNT,0,0);
+ i:=0;
+ li.mask :=LVIF_TEXT;
+ li.iSubItem :=0;
+ li.pszText :=@arr;
+ li.cchTextMax:=SizeOf(arr) div SizeOf(WideChar);
+ while i<act do
+ begin
+ li.iItem:=i;
+ SendMessageW(list,LVM_GETITEMW,0,lparam(@li));
+ SendMessageW(wnd,CB_ADDSTRING,0,lparam(PWideChar(@arr)));
+ inc(i);
+ end;
+ SendMessage(wnd,CB_SETCURSEL,0,0);
+end;
+
+procedure FillChainList(Dialog:hwnd);
+var
+ wnd:HWND;
+ i:integer;
+// num:integer;
+begin
+ wnd:=GetDlgItem(Dialog,IDC_GROUP_LIST);
+// for current chain exclude
+// num:=SendDlgItemMessage(Dialog,IDC_ACTION_GROUP,LVM_GETNEXTITEM,-1,LVNI_FOCUSED);
+
+ SendMessage(wnd,CB_RESETCONTENT,0,0);
+ SendMessage(wnd,CB_SETITEMDATA,
+ SendMessageW(wnd,CB_ADDSTRING,0,lparam(TranslateW(NoChainText))),0);
+ for i:=0 to NewMaxGroups-1 do
+ begin
+ if (NewGroupList^[i].flags and (ACF_ASSIGNED or ACF_VOLATILE))=ACF_ASSIGNED then
+ begin
+ SendMessage(wnd,CB_SETITEMDATA,
+ SendMessageW(wnd,CB_ADDSTRING,0,lparam(NewGroupList^[i].descr)),
+ NewGroupList^[i].id);
+ end;
+ end;
+end;
+
+// action group table procedure (key hook)
+function NewGroupTableProc(Dialog:HWnd;hMessage:uint;wParam:WPARAM;lParam:LPARAM):lresult; stdcall;
+var
+ i:integer;
+begin
+ result:=0;
+ case hMessage of
+ WM_KEYDOWN: begin
+ if (lParam and (1 shl 30))=0 then
+ begin
+ case wParam of
+ VK_F2: begin
+ i:=SendMessage(Dialog,LVM_GETNEXTITEM,-1,LVNI_FOCUSED);
+ if i>=0 then
+ PostMessageW(Dialog,LVM_EDITLABELW,i,0);
+ exit;
+ end;
+ VK_INSERT: begin
+ PostMessage(GetParent(Dialog),WM_COMMAND,(BN_CLICKED shl 16)+IDC_GROUP_NEW,0);
+ exit;
+ end;
+ VK_DELETE: begin
+ PostMessage(GetParent(Dialog),WM_COMMAND,(BN_CLICKED shl 16)+IDC_GROUP_DELETE,0);
+ exit;
+ end;
+ VK_UP: begin
+ if (GetKeyState(VK_CONTROL) and $8000)<>0 then
+ begin
+ PostMessage(GetParent(Dialog),WM_COMMAND,(BN_CLICKED shl 16)+IDC_GROUP_UP,0);
+ exit;
+ end;
+ end;
+ VK_DOWN: begin
+ if (GetKeyState(VK_CONTROL) and $8000)<>0 then
+ begin
+ PostMessage(GetParent(Dialog),WM_COMMAND,(BN_CLICKED shl 16)+IDC_GROUP_DOWN,0);
+ exit;
+ end;
+ end;
+ end;
+ end;
+ end;
+ end;
+ result:=CallWindowProc(OldGroupTableProc,Dialog,hMessage,wParam,lParam);
+end;
+
+// action (chain) table procedure (key hook)
+function NewActTableProc(Dialog:HWnd;hMessage:uint;wParam:WPARAM;lParam:LPARAM):lresult; stdcall;
+var
+ i:integer;
+begin
+ result:=0;
+ case hMessage of
+ WM_KEYDOWN: begin
+ if (lParam and (1 shl 30))=0 then
+ begin
+ case wParam of
+ VK_F2: begin
+ i:=SendMessage(Dialog,LVM_GETNEXTITEM,-1,LVNI_FOCUSED);
+ if i>=0 then
+ PostMessageW(Dialog,LVM_EDITLABELW,i,0);
+ exit;
+ end;
+ VK_UP: begin
+ if (GetKeyState(VK_CONTROL) and $8000)<>0 then
+ begin
+ PostMessage(GetParent(Dialog),WM_COMMAND,(BN_CLICKED shl 16)+IDC_ACTION_UP,0);
+ exit;
+ end;
+ end;
+ VK_DOWN: begin
+ if (GetKeyState(VK_CONTROL) and $8000)<>0 then
+ begin
+ PostMessage(GetParent(Dialog),WM_COMMAND,(BN_CLICKED shl 16)+IDC_ACTION_DOWN,0);
+ exit;
+ end;
+ end;
+ VK_INSERT: begin
+ PostMessage(GetParent(Dialog),WM_COMMAND,(BN_CLICKED shl 16)+IDC_ACTION_NEW,0);
+ exit;
+ end;
+ VK_DELETE: begin
+ PostMessage(GetParent(Dialog),WM_COMMAND,(BN_CLICKED shl 16)+IDC_ACTION_DELETE,0);
+ exit;
+ end;
+ end;
+ end;
+ end;
+ end;
+ result:=CallWindowProc(OldActTableProc,Dialog,hMessage,wParam,lParam);
+end;
+
+// miranda button icon paint
+procedure SetButtonIcons2(Dialog:HWND);
+var
+ ti:TTOOLINFOW;
+ hwndTooltip:HWND;
+begin
+ hwndTooltip:=CreateWindowW(TOOLTIPS_CLASS,nil,TTS_ALWAYSTIP,
+ integer(CW_USEDEFAULT),integer(CW_USEDEFAULT),
+ integer(CW_USEDEFAULT),integer(CW_USEDEFAULT),
+ Dialog,0,hInstance,nil);
+
+ FillChar(ti,SizeOf(ti),0);
+ ti.cbSize :=sizeof(TOOLINFO);
+ ti.uFlags :=TTF_IDISHWND or TTF_SUBCLASS;
+ ti.hwnd :=Dialog;
+ ti.hinst :=hInstance;
+
+ ti.uId :=GetDlgItem(Dialog,IDC_ACTION_HELP);
+ ti.lpszText:=TranslateW('Help');
+ SendMessage(ti.uId,BM_SETIMAGE,IMAGE_ICON,
+ CallService(MS_SKIN_LOADICON,SKINICON_OTHER_HELP,0));
+ SendMessageW(hwndTooltip,TTM_ADDTOOLW,0,lparam(@ti));
+
+ ti.uId :=GetDlgItem(Dialog,IDC_ACTION_NEW);
+ ti.lpszText:=TranslateW('New');
+ SetButtonIcon(ti.uId,ACI_NEW);
+ SendMessageW(hwndTooltip,TTM_ADDTOOLW,0,lparam(@ti));
+
+ ti.uId :=GetDlgItem(Dialog,IDC_GROUP_NEW);
+ SetButtonIcon(ti.uId,ACI_NEW);
+ SendMessageW(hwndTooltip,TTM_ADDTOOLW,0,lparam(@ti));
+
+ ti.uId :=GetDlgItem(Dialog,IDC_ACTION_UP);
+ ti.lpszText:=TranslateW('Up');
+ SetButtonIcon(ti.uId,ACI_UP);
+ SendMessageW(hwndTooltip,TTM_ADDTOOLW,0,lparam(@ti));
+
+ ti.uId :=GetDlgItem(Dialog,IDC_GROUP_UP);
+ SetButtonIcon(ti.uId,ACI_UP);
+ SendMessageW(hwndTooltip,TTM_ADDTOOLW,0,lparam(@ti));
+
+ ti.uId :=GetDlgItem(Dialog,IDC_ACTION_DOWN);
+ ti.lpszText:=TranslateW('Down');
+ SetButtonIcon(ti.uId,ACI_DOWN);
+ SendMessageW(hwndTooltip,TTM_ADDTOOLW,0,lparam(@ti));
+
+ ti.uId :=GetDlgItem(Dialog,IDC_GROUP_DOWN);
+ SetButtonIcon(ti.uId,ACI_DOWN);
+ SendMessageW(hwndTooltip,TTM_ADDTOOLW,0,lparam(@ti));
+
+ ti.uId :=GetDlgItem(Dialog,IDC_ACTION_DELETE);
+ ti.lpszText:=TranslateW('Delete');
+ SetButtonIcon(ti.uId,ACI_DELETE);
+ SendMessageW(hwndTooltip,TTM_ADDTOOLW,0,lparam(@ti));
+
+ ti.uId :=GetDlgItem(Dialog,IDC_GROUP_DELETE);
+ SetButtonIcon(ti.uId,ACI_DELETE);
+ SendMessageW(hwndTooltip,TTM_ADDTOOLW,0,lparam(@ti));
+
+ ti.uId :=GetDlgItem(Dialog,IDC_GROUP_RELOAD);
+ ti.lpszText:=TranslateW('Reload');
+ SetButtonIcon(ti.uId,ACI_RELOAD);
+ SendMessageW(hwndTooltip,TTM_ADDTOOLW,0,lparam(@ti));
+
+ ti.uId :=GetDlgItem(Dialog,IDC_GROUP_TEST);
+ ti.lpszText:=TranslateW('Test');
+ SetButtonIcon(ti.uId,ACI_TEST);
+ SendMessageW(hwndTooltip,TTM_ADDTOOLW,0,lparam(@ti));
+
+ ti.uId :=GetDlgItem(Dialog,IDC_CNT_APPLY);
+ ti.lpszText:=TranslateW('Apply format');
+ SetButtonIcon(ti.uId,ACI_FORMAT);
+ SendMessageW(hwndTooltip,TTM_ADDTOOLW,0,lparam(@ti));
+
+ ti.uId :=GetDlgItem(Dialog,IDC_GROUP_IMPORT);
+ ti.lpszText:=TranslateW('Import');
+ SetButtonIcon(ti.uId,ACI_IMPORT);
+ SendMessageW(hwndTooltip,TTM_ADDTOOLW,0,lparam(@ti));
+
+ ti.uId :=GetDlgItem(Dialog,IDC_GROUP_EXPORT);
+ ti.lpszText:=TranslateW('Export');
+ SetButtonIcon(ti.uId,ACI_EXPORT);
+ SendMessageW(hwndTooltip,TTM_ADDTOOLW,0,lparam(@ti));
+
+ ti.lpszText:=TranslateW('Use Variables');
+ ti.uId:=GetDlgItem(Dialog,IDC_SRV_WPAR);
+ SetButtonIcon(ti.uId,ACI_VAR_UNCHECKED);
+ SendMessageW(hwndTooltip,TTM_ADDTOOLW,0,lparam(@ti));
+
+{
+ pc:=TranslateW('');
+ wnd:=GetDlgItem(Dialog,IDC_NEW);
+ SendMessage(hNew,BUTTONADDTOOLTIP,TWPARAM(pc),BATF_UNICODE);
+ SetButtonIcon(wnd,QS_NEW);
+}
+ ti.uId:=GetDlgItem(Dialog,IDC_SRV_LPAR);
+ SetButtonIcon(ti.uId,ACI_VAR_UNCHECKED);
+ SendMessageW(hwndTooltip,TTM_ADDTOOLW,0,lparam(@ti));
+
+ ti.uId:=GetDlgItem(Dialog,IDC_SRV_SRVC);
+ SetButtonIcon(ti.uId,ACI_VAR_UNCHECKED);
+ SendMessageW(hwndTooltip,TTM_ADDTOOLW,0,lparam(@ti));
+
+ ti.uId:=GetDlgItem(Dialog,IDC_PRG_PRG);
+ SetButtonIcon(ti.uId,ACI_VAR_UNCHECKED);
+ SendMessageW(hwndTooltip,TTM_ADDTOOLW,0,lparam(@ti));
+
+ ti.uId:=GetDlgItem(Dialog,IDC_PRG_ARG);
+ SetButtonIcon(ti.uId,ACI_VAR_UNCHECKED);
+ SendMessageW(hwndTooltip,TTM_ADDTOOLW,0,lparam(@ti));
+
+ ti.uId:=GetDlgItem(Dialog,IDC_TXT_FILE);
+ SetButtonIcon(ti.uId,ACI_VAR_UNCHECKED);
+ SendMessageW(hwndTooltip,TTM_ADDTOOLW,0,lparam(@ti));
+
+ ti.uId:=GetDlgItem(Dialog,IDC_TXT_TEXT);
+ SetButtonIcon(ti.uId,ACI_VAR_UNCHECKED);
+ SendMessageW(hwndTooltip,TTM_ADDTOOLW,0,lparam(@ti));
+
+ ti.uId:=GetDlgItem(Dialog,IDC_RW_MVAR);
+ SetButtonIcon(ti.uId,ACI_VAR_UNCHECKED);
+ SendMessageW(hwndTooltip,TTM_ADDTOOLW,0,lparam(@ti));
+
+ ti.uId:=GetDlgItem(Dialog,IDC_RW_SVAR);
+ SetButtonIcon(ti.uId,ACI_VAR_UNCHECKED);
+ SendMessageW(hwndTooltip,TTM_ADDTOOLW,0,lparam(@ti));
+
+ ti.uId:=GetDlgItem(Dialog,IDC_RW_TVAR);
+ SetButtonIcon(ti.uId,ACI_VAR_UNCHECKED);
+ SendMessageW(hwndTooltip,TTM_ADDTOOLW,0,lparam(@ti));
+
+ ti.uId:=GetDlgItem(Dialog,IDC_MSG_TTL);
+ SetButtonIcon(ti.uId,ACI_VAR_UNCHECKED);
+ SendMessageW(hwndTooltip,TTM_ADDTOOLW,0,lparam(@ti));
+
+ ti.uId:=GetDlgItem(Dialog,IDC_MSG_TXT);
+ SetButtonIcon(ti.uId,ACI_VAR_UNCHECKED);
+ SendMessageW(hwndTooltip,TTM_ADDTOOLW,0,lparam(@ti));
+
+end;
+
+function MoveLVItem(list:HWND;num:integer;incr:integer):integer;
+var
+ li:LV_ITEM;
+ buf:array [0..127] of WideChar;
+begin
+ li.mask :=LVIF_PARAM+LVIF_STATE+LVIF_TEXT;
+ li.iItem :=num;
+ li.iSubItem :=0;
+ li.StateMask :=dword(-1);
+ li.pszText :=@buf;
+ li.cchTextMax:=127;
+ SendMessageW(list,LVM_GETITEMW,0,lparam(@li));
+ SendMessageW(list,LVM_DELETEITEM,li.iItem,0);
+ inc(li.iItem,incr);
+
+ SendMessageW(list,LVM_INSERTITEMW,0,lparam(@li));
+ SendMessageW(list,LVM_SETITEMSTATE,li.iItem,lparam(@li));
+ result:=li.iItem;
+end;
+
+function MoveGroup(list:HWND;num:integer=-1;incr:integer=0):integer;
+var
+ i,j:integer;
+begin
+ if num<0 then
+ begin
+ result:=-1;
+ j:=SendMessage(list,LVM_GETITEMCOUNT,0,0)-1;
+ if incr<0 then // up, from beginning
+ begin
+ for i:=0 to j do
+ begin
+ if SendMessage(list,LVM_GETITEMSTATE,i,LVIS_SELECTED)<>0 then
+ begin
+ if i=0 then break;
+ LV_MoveItem(list,incr,i);
+// MoveLVItem(list,i,incr);
+ if result<0 then result:=i+incr;
+ end;
+ end;
+ end
+ else // down, from the end
+ begin
+ for i:=j downto 0 do
+ begin
+ if SendMessage(list,LVM_GETITEMSTATE,i,LVIS_SELECTED)<>0 then
+ begin
+ if i=j then break;
+ LV_MoveItem(list,incr,i);
+// MoveLVItem(list,i,incr);
+ if result<0 then result:=i+incr;
+ end;
+ end;
+ end;
+ end
+ else
+ begin
+ MoveLVItem(list,num,incr);
+ result:=num;
+ end;
+end;
+
+{$include i_dlglists.inc}
+
+procedure SetNumValue(wnd:HWND;value:dword;isvar:boolean;ishex:boolean);
+var
+ buf:array [0..31] of WideChar;
+begin
+ if isvar then
+ SendMessageW(wnd,WM_SETTEXT,0,value)
+ else if ishex then
+ begin
+ buf[0]:='$';
+ IntToHex(PWideChar(@buf[1]),value);
+ SendMessageW(wnd,WM_SETTEXT,0,tlparam(@buf));
+ end
+ else
+ SendMessageW(wnd,WM_SETTEXT,0,tlparam(IntToStr(buf,value)));
+end;
+
+function DlgProcOpt2(Dialog:HWnd;hMessage:uint;wParam:WPARAM;lParam:LPARAM):lresult; stdcall;
+
+ {$include i_visual.inc}
+
+ procedure ShowHelp(code:integer);
+ var
+ buf:PAnsiChar;
+ vhi:TVARHELPINFO;
+ begin
+ case code of
+ hlpVariables: begin
+ FillChar(vhi,SizeOf(vhi),0);
+ with vhi do
+ begin
+ cbSize:=SizeOf(vhi);
+ flags:=VHF_NOINPUTDLG;
+ end;
+ CallService(MS_VARS_SHOWHELPEX,Dialog,tlparam(@vhi));
+ end;
+ hlpAdvVariables: begin
+ FillChar(vhi,SizeOf(vhi),0);
+ with vhi do
+ begin
+ cbSize :=SizeOf(vhi);
+ flags :=VHF_FULLDLG or VHF_SETLASTSUBJECT;
+ hwndCtrl :=GetDlgItem(Dialog,IDC_ADV_VARS);
+ szSubjectDesc:='test your variables';
+ end;
+ CallService(MS_VARS_SHOWHELPEX,Dialog,tlparam(@vhi));
+ end;
+ hlpContact: begin
+{
+ MessageBoxW(0,
+ TranslateW('Select contact to open it''s window'),
+ TranslateW('Contacts'),0);
+}
+ end;
+ hlpService: begin
+ buf:=GetDlgText(Dialog,IDC_EDIT_SERVICE,true);
+//!! if buf<>nil then
+ begin
+ ApiCard.Service:=buf;
+ mFreeMem(buf);
+ ApiCard.Show;
+ end;
+ end;
+ hlpProgram: begin
+ MessageBoxW(0,
+ TranslateW('Text <last> replacing'#13#10+
+ 'by last result'#13#10#13#10+
+ 'Text <param> replacing'#13#10+
+ 'by parameter'),
+ TranslateW('Text'),0);
+ end;
+ hlpText: begin
+ MessageBoxW(0,
+ TranslateW('^s - selected (and replaced) part'#13#10+
+ '^e - replaced by empty string'#13#10+
+ '^v - paste text from Clipboard'#13#10+
+ '^t - replaced by tabulation'#13#10+
+ '^l - replaced by last result as unicode'#13#10+
+ '^h - replaced by last result as hex'#13#10+
+ '^a - in the end: autosend'#13#10+
+ '^f(name[,str])'#13#10+
+ ' paste line from text file.'#13#10+
+ ' brackets contents must be w/o spaces'),
+ TranslateW('Text'),0);
+ end;
+ hlpAdvance: begin
+ end;
+ hlpChain: begin
+{
+ MessageBoxW(0,
+ TranslateW('You can select another group from combobox, '+
+ 'then it will be executed, after that current '+
+ 'action group will be continued.'),
+ TranslateW('Macros'),0);
+}
+ end;
+ hlpDBRW: begin
+ end;
+ hlpMessage: begin
+ MessageBoxW(0,
+ TranslateW(
+ 'Text <last> replacing'#13#10+
+ 'by last result'#13#10#13#10+
+ 'Returns:'#13#10+
+ '--------'#13#10+
+ 'OK'#9'= 1'#13#10+
+ 'CANCEL'#9'= 2'#13#10+
+ 'ABORT'#9'= 3'#13#10+
+ 'RETRY'#9'= 4'#13#10+
+ 'IGNORE'#9'= 5'#13#10+
+ 'YES'#9'= 6'#13#10+
+ 'NO'#9'= 7'#13#10+
+ 'CLOSE'#9'= 8'),
+ TranslateW('MessageBox'),0);
+ end;
+ end;
+ end;
+
+ // enable/disable navigation chain buttons
+ procedure CheckGrpList(num:integer=-1);
+ var
+ wnd:HWND;
+ dir:integer;
+ okup,okdown:boolean;
+ begin
+ wnd:=GetDlgItem(Dialog,IDC_ACTION_GROUP);
+// if num<0 then
+ begin
+ dir:=LV_CheckDirection(wnd);
+ okup :=odd(loword(dir));
+ okdown:=(loword(dir) and 2)<>0;
+ end;
+{
+ else
+ begin
+ okup :=num>0;
+ okdown:=(num+1)<SendMessage(wnd,LVM_GETITEMCOUNT,0,0);
+ SendMessage(wnd,LVM_ENSUREVISIBLE,num,0);
+ end;
+}
+ EnableWindow(GetDlgItem(Dialog,IDC_GROUP_UP ),okup);
+ EnableWindow(GetDlgItem(Dialog,IDC_GROUP_DOWN),okdown);
+ SendMessage(wnd,LVM_ENSUREVISIBLE,hiword(dir)-1,0);
+(*
+ wnd:=GetDlgItem(Dialog,IDC_ACTION_GROUP);
+ if num<0 then
+ num:=SendMessage(wnd,LVM_GETNEXTITEM,-1,LVNI_FOCUSED);
+ EnableWindow(GetDlgItem(Dialog,IDC_GROUP_UP),num>0);
+ EnableWindow(GetDlgItem(Dialog,IDC_GROUP_DOWN),
+ (num+1)<SendMessage(wnd,LVM_GETITEMCOUNT,0,0));
+ SendMessage(wnd,LVM_ENSUREVISIBLE,num,0);
+ result:=num;
+*)
+ end;
+ procedure CheckActList(num:integer=-1);
+ var
+ wnd:HWND;
+ dir:integer;
+ okup,okdown:boolean;
+ begin
+ wnd:=GetDlgItem(Dialog,IDC_ACTION_LIST);
+// if num<0 then
+ begin
+ dir:=LV_CheckDirection(wnd);
+ okup :=odd(loword(dir));
+ okdown:=(loword(dir) and 2)<>0;
+ end;
+{
+ else
+ begin
+ okup :=num>0;
+ okdown:=(num+1)<SendMessage(wnd,LVM_GETITEMCOUNT,0,0);
+ SendMessage(wnd,LVM_ENSUREVISIBLE,num,0);
+ end;
+}
+ EnableWindow(GetDlgItem(Dialog,IDC_ACTION_UP ),okup);
+ EnableWindow(GetDlgItem(Dialog,IDC_ACTION_DOWN),okdown);
+ SendMessage(wnd,LVM_ENSUREVISIBLE,hiword(dir)-1,0);
+(*
+ wnd:=GetDlgItem(Dialog,IDC_ACTION_LIST);
+ if num<0 then
+ num:=SendMessage(wnd,LVM_GETNEXTITEM,-1,LVNI_FOCUSED);
+ EnableWindow(GetDlgItem(Dialog,IDC_ACTION_UP),num>0);
+ EnableWindow(GetDlgItem(Dialog,IDC_ACTION_DOWN),
+ (num+1)<SendMessage(wnd,LVM_GETITEMCOUNT,0,0));
+ SendMessage(wnd,LVM_ENSUREVISIBLE,num,0);
+*)
+ end;
+
+ // change current action name (by type)
+ procedure ChangeActionName(num:integer=-1;acttype:integer=0;str:PWideChar=nil);
+ var
+ li:LV_ITEMW;
+ wnd:HWND;
+ str1:pWideChar;
+ begin
+ wnd:=GetDlgItem(Dialog,IDC_ACTION_LIST);
+ if num<0 then
+ li.iItem:=SendMessage(wnd,LVM_GETNEXTITEM,-1,LVNI_FOCUSED)
+ else
+ li.iItem:=num;
+ if li.iItem>=0 then
+ begin
+ li.iSubItem:=0;
+ // getting SubAction number
+ li.mask:=LVIF_PARAM;
+ SendMessage(wnd,LVM_GETITEM,0,tlparam(@li));
+
+ // changing to default name
+ if str=nil then
+ begin
+ if num>=0 then // new item - screen only
+ str1:=TranslateW(ActionNames[ACT_CONTACT])
+ else // change action type
+ begin
+ str1:=NewActionList[li.lParam].descr;
+ if str1=nil then // not in memory yet
+ str1:=TranslateW(ActionNames[acttype])
+ else
+ exit;
+ end;
+ end
+ else // rename
+ begin
+ str1:=str;
+ mFreeMem(NewActionList[li.lParam].descr);
+ StrDupW (NewActionList[li.lParam].descr,str);
+ end;
+
+// screen
+ li.mask :=LVIF_TEXT;
+ li.pszText:=str1;
+ SendMessageW(wnd,LVM_SETITEMW,0,tlparam(@li));
+ end;
+ end;
+
+ // Fill Chain list
+ procedure MakeActionList(HK:pHKRecord);
+ var
+ i,idx:integer;
+ wnd:HWND;
+ li:LV_ITEMW;
+ p:pWideChar;
+ begin
+ wnd:=GetDlgItem(Dialog,IDC_ACTION_LIST);
+ SendMessage(wnd,LVM_DELETEALLITEMS,0,0);
+
+ EnableWindow(GetDlgItem(Dialog,IDC_ACTION_UP),false);
+ if (HK=nil) or (HK^.firstAction=0) then
+ begin
+ SHWindows;
+ SHActButtons(SW_HIDE);
+ EnableWindow(GetDlgItem(Dialog,IDC_ACTION_LIST ),false);
+ EnableWindow(GetDlgItem(Dialog,IDC_GROUP_TEST ),false);
+ EnableWindow(GetDlgItem(Dialog,IDC_ACTION_HELP ),false);
+ EnableWindow(GetDlgItem(Dialog,IDC_ACTION_DELETE),false);
+ EnableWindow(GetDlgItem(Dialog,IDC_ACTION_DOWN ),false);
+ exit;
+ end;
+ SHActButtons(SW_SHOW);
+
+ li.mask :=LVIF_TEXT or LVIF_PARAM;
+ li.iSubitem:=0;
+ i:=HK^.firstAction;
+ idx:=0;
+ repeat
+ p:=NewActionList^[i].descr;
+ if p=nil then
+ p:=TranslateW(ActionNames[NewActionList^[i].actionType]);
+ li.pszText:=p;
+ li.iItem :=idx;
+ li.lParam :=i;
+ SendMessageW(wnd,LVM_INSERTITEMW,0,tlparam(@li));
+ ListView_SetCheckState(wnd,idx,(NewActionList^[i].flags and ACF_DISABLED)=0);
+
+ i:=NewActionList^[i].next;
+ inc(idx);
+ until i=0;
+
+ Listview_SetItemState(wnd,0,
+ LVIS_FOCUSED or LVIS_SELECTED,
+ LVIS_FOCUSED or LVIS_SELECTED);
+ EnableWindow(GetDlgItem(Dialog,IDC_ACTION_LIST ),true);
+ EnableWindow(GetDlgItem(Dialog,IDC_GROUP_TEST ),true);
+ EnableWindow(GetDlgItem(Dialog,IDC_ACTION_HELP ),true);
+ EnableWindow(GetDlgItem(Dialog,IDC_ACTION_DELETE),true);
+ EnableWindow(GetDlgItem(Dialog,IDC_ACTION_DOWN),idx>1);
+// FillSubList(Dialog);
+ FillAction(HK^.firstAction);
+ CheckActList(0);
+ end;
+
+ procedure SaveAction(listnum,actnum:integer);
+ var
+ wnd:HWND;
+ i:integer;
+ tmp:pWideChar;
+ arr: array [0..255] of WideChar;
+ li:LV_ITEMW;
+ begin
+ if (ChMask and ACTM_ACT)=0 then exit;
+ ChMask:=ChMask and not ACTM_ACT;
+ wnd:=GetDlgItem(Dialog,IDC_ACTION_LIST);
+ if listnum<0 then
+ begin
+ listnum:=SendMessageW(wnd,LVM_GETNEXTITEM,-1,LVNI_FOCUSED);
+ if listnum<0 then
+ exit;
+ end;
+ if actnum<0 then
+ actnum:=LV_GetLParam(wnd,listnum);
+ StrDupW(tmp,NewActionList^[actnum].descr); // keeping old name
+ FreeAction(@NewActionList^[actnum]);
+ with NewActionList^[actnum] do
+ begin
+ flags :=ACF_ASSIGNED;
+ flags2:=0;
+
+ descr:=tmp;
+ if descr=nil then
+ begin
+ li.iItem :=listnum;
+ li.mask :=LVIF_TEXT;
+ li.iSubItem :=0;
+ li.pszText :=@arr;
+ li.cchTextMax:=SizeOf(arr) div SizeOf(WideChar);
+ SendDlgItemMessageW(Dialog,IDC_ACTION_LIST,LVM_GETITEMW,0,tlparam(@li));
+ StrDupW(descr,arr);
+ end;
+
+ if ListView_GetCheckState(wnd,listnum)=0 then
+ flags:=flags or ACF_DISABLED;
+
+ actionType:=ActIds[SendDlgItemMessage(Dialog,IDC_ACTION_TYPE,CB_GETCURSEL,0,0)].code;
+ case actionType of
+ ACT_CONTACT: begin
+ contact:=SendDlgItemMessage(Dialog,IDC_CONTACTLIST,CB_GETITEMDATA,
+ SendDlgItemMessage(Dialog,IDC_CONTACTLIST,CB_GETCURSEL,0,0),0);
+ if IsDlgButtonChecked(Dialog,IDC_CNT_KEEP)=BST_CHECKED then
+ flags:=flags or ACF_KEEPONLY;
+ end;
+
+ ACT_SERVICE: begin
+ if IsDlgButtonChecked(Dialog,IDC_SRV_WPAR)=BST_CHECKED then
+ flags2:=flags2 or ACF2_SRV_WPAR;
+ if IsDlgButtonChecked(Dialog,IDC_SRV_LPAR)=BST_CHECKED then
+ flags2:=flags2 or ACF2_SRV_LPAR;
+ if IsDlgButtonChecked(Dialog,IDC_SRV_SRVC)=BST_CHECKED then
+ flags2:=flags2 or ACF2_SRV_SRVC;
+
+ case CB_GetData(GetDlgItem(Dialog,IDC_FLAG_WPAR)) of
+ ptParam: begin
+ flags:=flags or ACF_WPARAM
+ end;
+ ptResult: begin
+ flags:=flags or ACF_WRESULT
+ end;
+ ptCurrent: begin
+ flags:=flags or ACF_WPARNUM or ACF_WCURRENT
+ end;
+ ptNumber: begin
+ flags:=flags or ACF_WPARNUM;
+ if GetNumValue(GetDlgItem(Dialog,IDC_EDIT_WPAR),
+ (flags2 and ACF2_SRV_WPAR)<>0,wparam) then
+ flags2:=flags2 or ACF2_SRV_WHEX;
+// wparam:=GetDlgItemInt(Dialog,IDC_EDIT_WPAR,pbool(nil)^,true);
+ end;
+ ptStruct: begin
+ flags:=flags or ACF_WSTRUCT;
+ StrDup(pAnsiChar(wparam),wstruct);
+ end;
+ ptUnicode: begin
+ flags:=flags or ACF_WUNICODE;
+ pointer(wparam):=GetDlgText(Dialog,IDC_EDIT_WPAR);
+ end;
+ ptString: pointer(wparam):=GetDlgText(Dialog,IDC_EDIT_WPAR,true);
+ end;
+
+ case CB_GetData(GetDlgItem(Dialog,IDC_FLAG_LPAR)) of
+ ptParam: begin
+ flags:=flags or ACF_LPARAM
+ end;
+ ptResult: begin
+ flags:=flags or ACF_LRESULT
+ end;
+ ptCurrent: begin
+ flags:=flags or ACF_LPARNUM or ACF_LCURRENT
+ end;
+ ptNumber: begin
+ flags:=flags or ACF_LPARNUM;
+ if GetNumValue(GetDlgItem(Dialog,IDC_EDIT_LPAR),
+ (flags2 and ACF2_SRV_LPAR)<>0,lparam) then
+ flags2:=flags2 or ACF2_SRV_LHEX;
+// lparam:=GetDlgItemInt(Dialog,IDC_EDIT_LPAR,pbool(nil)^,true);
+ end;
+ ptStruct: begin
+ flags:=flags or ACF_LSTRUCT;
+ StrDup(pAnsiChar(lparam),lstruct);
+ end;
+ ptUnicode: begin
+ flags:=flags or ACF_LUNICODE;
+ pointer(lparam):=GetDlgText(Dialog,IDC_EDIT_LPAR);
+ end;
+ ptString: pointer(lparam):=GetDlgText(Dialog,IDC_EDIT_LPAR,true);
+ end;
+
+ if IsDlgButtonChecked(Dialog,IDC_RES_INSERT)=BST_CHECKED then
+ flags:=flags or ACF_INSERT;
+ if IsDlgButtonChecked(Dialog,IDC_RES_MESSAGE)=BST_CHECKED then
+ flags:=flags or ACF_MESSAGE;
+ if IsDlgButtonChecked(Dialog,IDC_RES_POPUP)=BST_CHECKED then
+ flags:=flags or ACF_POPUP;
+
+ case CB_GetData(GetDlgItem(Dialog,IDC_SRV_RESULT)) of
+ sresHex: flags:=flags or ACF_HEX;
+ sresInt: begin
+ if IsDlgButtonChecked(Dialog,IDC_RES_SIGNED)=BST_CHECKED then
+ flags:=flags or ACF_SIGNED;
+ end;
+ sresString: begin
+ flags:=flags or ACF_STRING;
+ if IsDlgButtonChecked(Dialog,IDC_RES_UNICODE)=BST_CHECKED then
+ flags:=flags or ACF_UNICODE;
+ if IsDlgButtonChecked(Dialog,IDC_RES_FREEMEM)=BST_CHECKED then
+ flags2:=flags2 or ACF2_FREEMEM;
+ end;
+ sresStruct: flags:=flags or ACF_STRUCT;
+ end;
+
+ service:=GetDlgText(Dialog,IDC_EDIT_SERVICE,true);
+
+ end;
+
+ ACT_PROGRAM: begin
+ prgname:=GetDlgText(Dialog,IDC_EDIT_PRGPATH);
+ {
+ p:=GetDlgText(IDC_EDIT_PRGPATH);
+ if p<>nil then
+ begin
+ CallService(MS_UTILS_PATHTORELATIVE,dword(p),dword(@buf));
+ StrDupW(prgname,@buf);
+ mFreeMem(p);
+ end;
+ }
+ args:=GetDlgText(Dialog,IDC_EDIT_PRGARGS);
+ if IsDlgButtonChecked(Dialog,IDC_FLAG_PARALLEL)=BST_CHECKED then
+ flags:=flags or ACF_PRTHREAD;
+ if IsDlgButtonChecked(Dialog,IDC_FLAG_CURPATH)=BST_CHECKED then
+ flags:=flags or ACF_CURPATH;
+ time:=GetDlgItemInt(Dialog,IDC_EDIT_PROCTIME,pbool(nil)^,false);
+ if IsDlgButtonChecked(Dialog,IDC_FLAG_MINIMIZE)=BST_CHECKED then
+ show:=SW_SHOWMINIMIZED
+ else if IsDlgButtonChecked(Dialog,IDC_FLAG_MAXIMIZE)=BST_CHECKED then
+ show:=SW_SHOWMAXIMIZED
+ else if IsDlgButtonChecked(Dialog,IDC_FLAG_HIDDEN)=BST_CHECKED then
+ show:=SW_HIDE
+ else //if IsDlgButtonChecked(Dialog,IDC_FLAG_NORMAL)=BST_CHECKED then
+ show:=SW_SHOWNORMAL;
+
+ if IsDlgButtonChecked(Dialog,IDC_PRG_PRG)=BST_CHECKED then
+ flags2:=flags2 or ACF2_PRG_PRG;
+ if IsDlgButtonChecked(Dialog,IDC_PRG_ARG)=BST_CHECKED then
+ flags2:=flags2 or ACF2_PRG_ARG;
+ end;
+
+ ACT_TEXT: begin
+ if IsDlgButtonChecked(Dialog,IDC_FLAG_CLIP)<>BST_UNCHECKED then
+ begin
+ flags:=flags or ACF_CLIPBRD;
+ if IsDlgButtonChecked(Dialog,IDC_CLIP_COPYTO)<>BST_UNCHECKED then
+ flags:=flags or ACF_COPYTO;
+ end
+ else
+ begin
+ if IsDlgButtonChecked(Dialog,IDC_TXT_TEXT)=BST_CHECKED then
+ flags2:=flags2 or ACF2_TXT_TEXT;
+ text:=GetDlgText(Dialog,IDC_EDIT_INSERT);
+ if IsDlgButtonChecked(Dialog,IDC_FLAG_FILE)<>BST_UNCHECKED then
+ begin
+ flags:=flags or ACF_FILE;
+ case CB_GetData(GetDlgItem(Dialog,IDC_FILE_ENC)) of
+ 0: flags:=flags or ACF_ANSI;
+ 1: flags:=flags or ACF_UTF8;
+ 2: flags:=flags or ACF_UTF8 or ACF_SIGN;
+ 3: flags:=flags or 0;
+ 4: flags:=flags or ACF_SIGN;
+ end;
+
+ if IsDlgButtonChecked(Dialog,IDC_TXT_FILE)=BST_CHECKED then
+ flags2:=flags2 or ACF2_TXT_FILE;
+ tfile:=GetDlgText(Dialog,IDC_FILE_PATH);
+ if IsDlgButtonChecked(Dialog,IDC_FILE_APPEND)<>BST_UNCHECKED then
+ flags:=flags or ACF_FAPPEND
+ else if IsDlgButtonChecked(Dialog,IDC_FILE_WRITE)<>BST_UNCHECKED then
+ flags:=flags or ACF_FWRITE;
+ end;
+ end;
+ end;
+
+ ACT_ADVANCE: begin
+ condition:=ADV_COND_NOP;
+ if IsDlgButtonChecked(Dialog,IDC_FLAG_GT )=BST_CHECKED then
+ condition:=ADV_COND_GT
+ else if IsDlgButtonChecked(Dialog,IDC_FLAG_LT )=BST_CHECKED then
+ condition:=ADV_COND_LT
+ else if IsDlgButtonChecked(Dialog,IDC_FLAG_EQ )=BST_CHECKED then
+ condition:=ADV_COND_EQ;
+ value:=GetDlgItemInt(Dialog,IDC_ADV_VALUE,pbool(nil)^,false);
+
+ if IsDlgButtonChecked(Dialog,IDC_FLAG_NOT)=BST_CHECKED then
+ condition:=condition or ADV_COND_NOT;
+
+ if IsDlgButtonChecked(Dialog,IDC_FLAG_BREAK)=BST_CHECKED then
+ action:=ADV_ACT_BREAK
+ else if IsDlgButtonChecked(Dialog,IDC_FLAG_JUMP )=BST_CHECKED then
+ action:=ADV_ACT_JUMP
+ else
+ action:=ADV_ACT_NOP;
+
+ case action of
+ ADV_ACT_JUMP: operval:=GetDlgText(Dialog,IDC_ADV_VAL2);
+ end;
+
+ if IsDlgButtonChecked(Dialog,IDC_FLAG_VARS)<>BST_UNCHECKED then
+ begin
+ varval:=GetDlgText(Dialog,IDC_ADV_VARS);
+ action:=action or ADV_ACT_VARS;
+ if IsDlgButtonChecked(Dialog,IDC_ADV_ASINT)<>BST_UNCHECKED then
+ flags:=flags or ACF_VARASINT;
+ end
+;{//!!executively!!
+ else }if IsDlgButtonChecked(Dialog,IDC_FLAG_MATH)=BST_CHECKED then
+ begin
+ mathval:=GetDlgItemInt(Dialog,IDC_ADV_VAL1,pbool(nil)^,true);
+ action :=action or ADV_ACT_MATH;
+ oper :=CB_GetData(GetDlgItem(Dialog,IDC_ADV_OPER));
+// oper :=SendDlgItemMessage(Dialog,IDC_ADV_OPER,CB_GETCURSEL,0,0);
+ end;
+ end;
+
+ ACT_CHAIN: begin
+ wnd:=GetDlgItem(Dialog,IDC_GROUP_LIST);
+ i:=SendMessage(wnd,CB_GETCURSEL,0,0);
+ if i>0 then
+ id:=SendMessage(wnd,CB_GETITEMDATA,i,0)
+ else
+ id:=0;
+ end;
+
+ ACT_RW: begin
+ if IsDlgButtonChecked(Dialog,IDC_RW_CURRENT)=BST_CHECKED then
+ flags:=flags or ACF_CURRENT
+ else if IsDlgButtonChecked(Dialog,IDC_RW_RESULT)=BST_CHECKED then
+ flags:=flags or ACF_RESULT
+ else if IsDlgButtonChecked(Dialog,IDC_RW_PARAM)=BST_CHECKED then
+ flags:=flags or ACF_PARAM
+ else
+ dbcontact:=SendDlgItemMessage(Dialog,IDC_CONTACTLIST,CB_GETITEMDATA,
+ SendDlgItemMessage(Dialog,IDC_CONTACTLIST,CB_GETCURSEL,0,0),0);
+ dbmodule :=GetDlgText(Dialog,IDC_RW_MODULE ,true);
+ dbsetting:=GetDlgText(Dialog,IDC_RW_SETTING,true);
+ if IsDlgButtonChecked(Dialog,IDC_RW_MVAR)=BST_CHECKED then
+ flags2:=flags2 or ACF2_RW_MVAR;
+ if IsDlgButtonChecked(Dialog,IDC_RW_SVAR)=BST_CHECKED then
+ flags2:=flags2 or ACF2_RW_SVAR;
+
+ if IsDlgButtonChecked(Dialog,IDC_RW_WRITE)=BST_CHECKED then
+ flags:=flags or ACF_DBWRITE
+ else if IsDlgButtonChecked(Dialog,IDC_RW_DELETE)=BST_CHECKED then
+ flags:=flags or ACF_DBDELETE;
+
+ if IsDlgButtonChecked(Dialog,IDC_RW_LAST)=BST_CHECKED then
+ flags:=flags or ACF_LAST;
+
+ if IsDlgButtonChecked(Dialog,IDC_RW_TVAR)=BST_CHECKED then
+ flags2:=flags2 or ACF2_RW_TVAR;
+
+ i:=CB_GetData(GetDlgItem(Dialog,IDC_RW_DATATYPE));
+ case i of
+ 0: flags:=flags or ACF_DBBYTE;
+ 1: flags:=flags or ACF_DBWORD;
+ 2: flags:=flags or 0;
+ 3: flags:=flags or ACF_DBANSI;
+ 4: flags:=flags or ACF_DBUTEXT;
+ end;
+ if i<3 then
+ begin
+ if (flags and ACF_LAST)=0 then
+ begin
+ if GetNumValue(GetDlgItem(Dialog,IDC_RW_VALUE),
+ (flags2 and ACF2_RW_TVAR)<>0,dbvalue) then
+ flags2:=flags2 or ACF2_RW_HEX;
+ end;
+ end
+ else
+ begin
+ if (flags and ACF_LAST)=0 then
+ pWideChar(dbvalue):=GetDlgText(Dialog,IDC_RW_TEXT);
+ end;
+
+ if (IsDlgButtonChecked(Dialog,IDC_RW_LAST)=BST_CHECKED) or
+ ((flags and ACF_LAST)<>0) then
+ flags:=flags or ACF_LAST;
+ end;
+
+ ACT_MESSAGE: begin
+ pWideChar(msgtitle):=GetDlgText(Dialog,IDC_MSG_TITLE);
+ pWideChar(msgtext ):=GetDlgText(Dialog,IDC_MSG_TEXT);
+ if IsDlgButtonChecked(Dialog,IDC_MSG_KEEP)=BST_CHECKED then
+ flags:=flags or ACF_MSG_KEEP;
+ if IsDlgButtonChecked(Dialog,IDC_MSG_TTL)=BST_CHECKED then
+ flags2:=flags2 or ACF2_MSG_TTL;
+ if IsDlgButtonChecked(Dialog,IDC_MSG_TXT)=BST_CHECKED then
+ flags2:=flags2 or ACF2_MSG_TXT;
+
+ if IsDlgButtonChecked(Dialog,IDC_MSGB_OC )=BST_CHECKED then boxopts:=MB_OKCANCEL
+ else if IsDlgButtonChecked(Dialog,IDC_MSGB_ARI)=BST_CHECKED then boxopts:=MB_ABORTRETRYIGNORE
+ else if IsDlgButtonChecked(Dialog,IDC_MSGB_YNC)=BST_CHECKED then boxopts:=MB_YESNOCANCEL
+ else if IsDlgButtonChecked(Dialog,IDC_MSGB_YN )=BST_CHECKED then boxopts:=MB_YESNO
+ else if IsDlgButtonChecked(Dialog,IDC_MSGB_RC )=BST_CHECKED then boxopts:=MB_RETRYCANCEL
+ else{if IsDlgButtonChecked(Dialog,IDC_MSGB_OK )=BST_CHECKED then}boxopts:=MB_OK;
+
+ if IsDlgButtonChecked(Dialog,IDC_MSGI_ERROR)=BST_CHECKED then boxopts:=boxopts or MB_ICONHAND
+ else if IsDlgButtonChecked(Dialog,IDC_MSGI_QUEST)=BST_CHECKED then boxopts:=boxopts or MB_ICONQUESTION
+ else if IsDlgButtonChecked(Dialog,IDC_MSGI_WARN )=BST_CHECKED then boxopts:=boxopts or MB_ICONWARNING
+ else if IsDlgButtonChecked(Dialog,IDC_MSGI_INFO )=BST_CHECKED then boxopts:=boxopts or MB_ICONINFORMATION
+ ;//else if IsDlgButtonChecked(Dialog,IDC_MSGI_NONE)=BST_CHECKED then ;
+ end;
+
+ end;
+ end;
+ end;
+
+ procedure BuildActionChain(group:integer=-1);
+ var
+ i,j,item:integer;
+ wnd:HWND;
+ act:pHKAction;
+ idx:integer;
+ begin
+ if (ChMask and ACTM_ACTS)=0 then exit;
+ ChMask:=ChMask and not ACTM_ACTS;
+ SaveAction(-1,-1);
+ wnd:=GetDlgItem(Dialog,IDC_ACTION_LIST);
+ i:=SendMessageW(wnd,LVM_GETITEMCOUNT,0,0);
+ idx:=LV_GetLParam(GetDlgItem(Dialog,IDC_ACTION_GROUP),group);
+ if i>0 then
+ begin
+ j:=LV_GetLParam(wnd,0);
+ NewGroupList^[idx].firstAction:=j;
+ act:=@NewActionList^[j];
+ for item:=1 to i-1 do
+ begin
+ j:=LV_GetLParam(wnd,item);
+ act^.next:=j;
+ act:=@NewActionList^[j];
+ end;
+ act^.next:=0;
+ end
+ else
+ begin
+ if idx>=0 then
+ NewGroupList^[idx].firstAction:=0;
+ end;
+ end;
+
+ procedure CheckActionList(next:integer);
+ var
+ i:integer;
+ wnd:HWND;
+ begin
+ wnd:=GetDlgItem(Dialog,IDC_ACTION_LIST);
+ i:=SendMessage(wnd,LVM_GETITEMCOUNT,0,0);
+ if i>0 then
+ begin
+ EnableWindow(GetDlgItem(Dialog,IDC_ACTION_HELP),true);
+ if next=i then
+ dec(next);
+ ListView_SetItemState(wnd,next,
+ LVIS_FOCUSED or LVIS_SELECTED,
+ LVIS_FOCUSED or LVIS_SELECTED);
+ end
+ else
+ begin
+ SHWindows;
+ SHActButtons(SW_HIDE);
+ EnableWindow(wnd,false);
+ EnableWindow(GetDlgItem(Dialog,IDC_ACTION_HELP ),false);
+ EnableWindow(GetDlgItem(Dialog,IDC_GROUP_TEST ),false);
+ EnableWindow(GetDlgItem(Dialog,IDC_ACTION_DELETE),false);
+ next:=0;
+ end;
+ CheckActList(next);
+ end;
+
+ procedure CheckGroupList(next:integer);
+ var
+ i:integer;
+ wnd:HWND;
+ li:LV_ITEMW;
+ begin
+ wnd:=GetDlgItem(Dialog,IDC_ACTION_GROUP);
+ i:=SendMessage(wnd,LVM_GETITEMCOUNT,0,0);
+ if i>0 then
+ begin
+ if next=i then
+ dec(next);
+ ListView_SetItemState(wnd,next,LVIS_FOCUSED or LVIS_SELECTED,
+ LVIS_FOCUSED or LVIS_SELECTED);
+ li.iItem :=next;
+ li.iSubItem:=0;
+ li.mask :=LVIF_PARAM;
+ SendMessage(wnd,LVM_GETITEM,0,tlparam(@li));
+ end
+ else
+ begin
+ EnableWindow(wnd,false);
+ EnableWindow(GetDlgItem(Dialog,IDC_GROUP_DELETE),false);
+ CheckActionList(0);
+ EnableWindow(GetDlgItem(Dialog,IDC_ACTION_NEW),false);
+ end;
+ CheckGrpList(next);
+ end;
+
+ // Fill action group list and disable chain controls
+ function FillGroupList{(Dialog:hwnd)}:integer;
+ var
+ CurGroup:pHKRecord;
+ i:integer;
+ list:HWND;
+ lvi:TLVITEMW;
+ begin
+ SendDlgItemMessage(Dialog,IDC_ACTION_LIST,LVM_DELETEALLITEMS,0,0);
+ CheckActionList(-1);
+ list:=GetDlgItem(Dialog,IDC_ACTION_GROUP);
+
+ SendMessage(list,LVM_DELETEALLITEMS,0,0);
+ CurGroup:=@NewGroupList^;
+ result:=-1;
+ lvi.mask:=LVIF_TEXT+LVIF_PARAM;
+ lvi.iSubItem:=0;
+ for i:=0 to NewMaxGroups-1 do
+ begin
+ if (CurGroup^.flags and ACF_ASSIGNED)<>0 then
+ begin
+ lvi.iItem :=i;
+ lvi.lParam:=i;
+ if CurGroup^.descr=nil then
+ lvi.pszText:=NoDescription
+ else
+ lvi.pszText:=CurGroup^.descr;
+ SendMessageW(list,LVM_INSERTITEMW,0,tlparam(@lvi));
+ inc(result);
+ end;
+ inc(CurGroup);
+ end;
+
+ EnableWindow(GetDlgItem(Dialog,IDC_ACTION_GROUP ),result>=0);
+ EnableWindow(GetDlgItem(Dialog,IDC_ACTION_LIST ),result>=0);
+ EnableWindow(GetDlgItem(Dialog,IDC_ACTION_NEW ),result>=0);
+ EnableWindow(GetDlgItem(Dialog,IDC_GROUP_DELETE ),result>=0);
+ if result<0 then
+ begin
+ EnableWindow(GetDlgItem(Dialog,IDC_GROUP_TEST ),false);
+ EnableWindow(GetDlgItem(Dialog,IDC_ACTION_HELP ),false);
+ EnableWindow(GetDlgItem(Dialog,IDC_ACTION_DELETE),false);
+ EnableWindow(GetDlgItem(Dialog,IDC_ACTION_UP ),false);
+ EnableWindow(GetDlgItem(Dialog,IDC_ACTION_DOWN ),false);
+ EnableWindow(GetDlgItem(Dialog,IDC_STAT_GROUPS ),false);
+ EnableWindow(GetDlgItem(Dialog,IDC_ACTION_TYPE ),false);
+ end
+ else
+ result:=0;
+ SendMessage(list,CB_SETCURSEL,0,0);
+ SendMessage(list,LVM_SETCOLUMNWIDTH,0,LVSCW_AUTOSIZE_USEHEADER);
+
+ ListView_SetItemState(list,0,
+ LVIS_FOCUSED or LVIS_SELECTED,
+ LVIS_FOCUSED or LVIS_SELECTED);
+ end;
+
+ procedure SHMath(show:boolean);
+ var
+ wnd:HWND;
+ begin
+ EnableWindow(GetDlgItem(Dialog,IDC_ADV_ASINT),not show);
+ EnableWindow(GetDlgItem(Dialog,IDC_ADV_VARS ),not show);
+
+ wnd:=GetDlgItem(Dialog,IDC_ADV_OPER);
+ EnableWindow(wnd,show);
+ EnableWindow(GetDlgItem(Dialog,IDC_ADV_VAL1),
+ show and (CB_GetData(wnd)<>lresult(aeNot)));//(SendMessage(wnd,CB_GETCURSEL,0,0)<>0));
+ end;
+
+ procedure SetMBRadioIcon(h:THANDLE;id:dword;icon:uint_ptr);
+ begin
+ SendDlgItemMessage(Dialog,id,BM_SETIMAGE,IMAGE_ICON,
+ LoadImage(h,MAKEINTRESOURCE(icon),IMAGE_ICON,16,16,0{LR_SHARED}));
+ // SendDlgItemMessage(Dialog,id,BM_SETIMAGE,IMAGE_ICON,LoadIcon(0,icon));
+ end;
+
+ procedure SetMBRadioIcons;
+ var
+ h:THANDLE;
+ begin
+ h:=LoadLibrary('user32.dll');
+ // SetMBRadioIcon(IDC_MSGI_NONE,IDI_); //?
+ SetMBRadioIcon(h,IDC_MSGI_ERROR,103{IDI_HAND});
+ SetMBRadioIcon(h,IDC_MSGI_QUEST,102{IDI_QUESTION});
+ SetMBRadioIcon(h,IDC_MSGI_WARN ,101{IDI_EXCLAMATION});
+ SetMBRadioIcon(h,IDC_MSGI_INFO ,104{IDI_ASTERISK});
+ FreeLibrary(h);
+ end;
+
+ procedure FillFileName(idc:integer);
+ var
+ pw,ppw:pWideChar;
+ begin
+ mGetMem(pw,1024*SizeOf(WideChar));
+ ppw:=GetDlgText(Dialog,idc);
+ if ShowDlgW(pw,ppw) then
+ SetDlgItemTextW(Dialog,idc,pw);
+ mFreeMem(ppw);
+ mFreeMem(pw);
+ end;
+
+var
+ wnd,wnd1,wnd2:HWND;
+ i,j:int_ptr;
+ lvflag:integer;
+ pc:pAnsiChar;
+ li:LV_ITEMW;
+ lv:LV_COLUMNW;
+ b:boolean;
+ ico:HICON;
+begin
+ result:=0;
+ case hMessage of
+ WM_DESTROY: begin
+ ApiCard.Free;
+ SetCancel;
+ mFreeMem(wstruct);
+ mFreeMem(lstruct);
+ end;
+
+ WM_INITDIALOG: begin
+ ApiCard:=CreateServiceCard(Dialog);
+ wstruct:=nil;
+ lstruct:=nil;
+ SetStart;
+ DontReact :=true;
+ SHWindows;
+ TranslateDialogDefault(Dialog);
+ SetButtonIcons2(Dialog);
+ wnd:=GetDlgItem(Dialog,IDC_ACTION_LIST);
+ SendMessage(wnd,LVM_SETEXTENDEDLISTVIEWSTYLE,LVS_EX_CHECKBOXES,LVS_EX_CHECKBOXES);
+ SendMessage(wnd,LVM_SETUNICODEFORMAT,1,0);
+ zeromemory(@lv,sizeof(lv));
+ lv.mask:=LVCF_WIDTH;
+ lv.cx :=110;
+ SendMessageW(wnd,LVM_INSERTCOLUMNW ,0,tlparam(@lv));
+ SendMessageW(wnd,LVM_SETCOLUMNWIDTH,0,LVSCW_AUTOSIZE_USEHEADER);
+
+ MakeResultTypeList(GetDlgItem(Dialog,IDC_SRV_RESULT));
+ MakeParamTypeList (GetDlgItem(Dialog,IDC_FLAG_WPAR));
+ MakeParamTypeList (GetDlgItem(Dialog,IDC_FLAG_LPAR));
+ MakeMathOperList (GetDlgItem(Dialog,IDC_ADV_OPER));
+ MakeFileEncList (GetDlgItem(Dialog,IDC_FILE_ENC));
+ MakeDataTypeList (GetDlgItem(Dialog,IDC_RW_DATATYPE));
+
+ // service list for RunService
+ ApiCard.FillList(GetDlgItem(Dialog,IDC_EDIT_SERVICE));
+ // contact list for ContactMessage
+ FillContactList(GetDlgItem(Dialog,IDC_CONTACTLIST),fCLfilter,fCLformat);
+ // action type combobox
+ FillActTypeList(GetDlgItem(Dialog,IDC_ACTION_TYPE));
+
+ if isVarsInstalled then
+ begin
+ ico:=CallService(MS_VARS_GETSKINITEM,0,VSI_HELPICON);
+ SendDlgItemMessage(Dialog,IDC_HLP_FVARS,BM_SETIMAGE,IMAGE_ICON,ico);
+ SendDlgItemMessage(Dialog,IDC_HLP_VARS ,BM_SETIMAGE,IMAGE_ICON,ico);
+ SendDlgItemMessage(Dialog,IDC_ADV_HVARS,BM_SETIMAGE,IMAGE_ICON,ico);
+ end;
+
+ if ServiceExists(MS_SYSTEM_GET_XI)=0 then
+ begin
+ EnableWindow(GetDlgItem(Dialog,IDC_GROUP_EXPORT),false);
+ EnableWindow(GetDlgItem(Dialog,IDC_GROUP_IMPORT),false);
+ end;
+
+ OldActTableProc :=pointer(SetWindowLongPtrW(wnd,GWL_WNDPROC,long_ptr(@NewActTableProc)));
+ OldGroupTableProc:=pointer(SetWindowLongPtrW(GetDlgItem(Dialog,IDC_ACTION_GROUP),
+ GWL_WNDPROC,long_ptr(@NewGroupTableProc)));
+
+ // fill group list
+ wnd:=GetDlgItem(Dialog,IDC_ACTION_GROUP);
+ SendMessage(wnd,LVM_SETUNICODEFORMAT,1,0);
+ lv.mask:=LVCF_WIDTH;
+ lv.cx :=110;
+ SendMessageW(wnd,LVM_INSERTCOLUMNW,0,tlparam(@lv));
+ FillGroupList{(Dialog)};
+ FillChainList(Dialog);
+
+ SetMBRadioIcons;
+
+ // fill current group
+ MakeActionList(@NewGroupList^);
+ ChMask:=0;
+ CheckGrpList(-1);
+ DontReact:=false;
+ end;
+
+ WM_COMMAND: begin
+ if DontReact then exit;
+ case wParam shr 16 of
+ CBN_EDITCHANGE: begin
+ ChMask:=ChMask or ACTM_ACT or ACTM_ACTS;
+ SetChanged(Dialog,etACT);
+ end;
+ EN_CHANGE: begin
+// check for group renaming
+ if loword(wParam)<>IDC_EDIT_FORMAT then
+ begin
+ ChMask:=ChMask or ACTM_ACT or ACTM_ACTS;
+ SetChanged(Dialog,etACT);
+ end;
+ end;
+ CBN_SELCHANGE: begin
+ ChMask:=ChMask or ACTM_ACT or ACTM_ACTS;
+ SetChanged(Dialog,etACT);
+ case loword(wParam) of
+ IDC_SRV_RESULT: begin
+ i:=CB_GetData(lParam);
+ case i of
+ sresHex,sresInt,sresStruct: begin
+ SHControl(IDC_RES_FREEMEM,SW_HIDE);
+ SHControl(IDC_RES_UNICODE,SW_HIDE);
+ if i=sresInt then
+ SHControl(IDC_RES_SIGNED,SW_SHOW)
+ else
+ SHControl(IDC_RES_SIGNED,SW_HIDE);
+ end;
+ sresString: begin
+ SHControl(IDC_RES_FREEMEM,SW_SHOW);
+ SHControl(IDC_RES_UNICODE,SW_SHOW);
+ SHControl(IDC_RES_SIGNED ,SW_HIDE);
+ end;
+ end;
+ end;
+
+ IDC_ADV_OPER: begin
+ EnableWindow(GetDlgItem(Dialog,IDC_ADV_VAL1),
+ (CB_GetData(lParam)<>lresult(aeNot)));
+// SendMessage(lParam,CB_GETCURSEL,0,0)<>0);
+ end;
+
+ IDC_RW_DATATYPE: begin
+ if CB_GetData(GetDlgItem(Dialog,IDC_RW_DATATYPE))>2 then
+ begin
+ SHControl(IDC_RW_TEXT ,SW_SHOW);
+ SHControl(IDC_RW_VALUE,SW_HIDE);
+ end
+ else
+ begin
+ SHControl(IDC_RW_TEXT ,SW_HIDE);
+ SHControl(IDC_RW_VALUE,SW_SHOW);
+ end;
+ end;
+
+ IDC_ACTION_TYPE: begin
+ i:=SendMessage(lParam,CB_GETCURSEL,0,0);
+ SHWindows(ActIds[i].code);
+ ChangeActionName(-1,i+1);
+ case ActIds[i].code of
+ ACT_CONTACT: EnableWindow(GetDlgItem(Dialog,IDC_CONTACTLIST),true);
+ ACT_RW: begin
+ EnableWindow(GetDlgItem(Dialog,IDC_CONTACTLIST),
+ (IsDlgButtonChecked(Dialog,IDC_RW_MANUAL)=BST_CHECKED));
+
+ if CB_GetData(GetDlgItem(Dialog,IDC_RW_DATATYPE))>2 then
+ begin
+ SHControl(IDC_RW_TEXT ,SW_SHOW);
+ SHControl(IDC_RW_VALUE,SW_HIDE);
+ end
+ else
+ begin
+ SHControl(IDC_RW_TEXT ,SW_HIDE);
+ SHControl(IDC_RW_VALUE,SW_SHOW);
+ end;
+
+ end;
+ ACT_ADVANCE: FillSubList(Dialog);
+ end;
+ end;
+{
+ IDC_EDIT_WPAR,IDC_EDIT_LPAR: begin
+ SendMessage(lParam,CB_GETLBTEXT,
+ SendMessage(lParam,CB_GETCURSEL,0,0),
+ dword(@buf));
+ if loword(wParam)=IDC_EDIT_WPAR then
+ FixParam(buf,IDC_EDIT_WPAR,IDC_FLAG_WPAR)
+ else
+ FixParam(buf,IDC_EDIT_LPAR,IDC_FLAG_LPAR)
+ end;
+}
+ IDC_FLAG_WPAR,IDC_FLAG_LPAR: begin
+ if loword(wParam)=IDC_FLAG_WPAR then
+ begin
+ wnd :=GetDlgItem(Dialog,IDC_EDIT_WPAR);
+ wnd1:=GetDlgItem(Dialog,IDC_WSTRUCT);
+ wnd2:=GetDlgItem(Dialog,IDC_SRV_WPAR);
+ end
+ else
+ begin
+ wnd :=GetDlgItem(Dialog,IDC_EDIT_LPAR);
+ wnd1:=GetDlgItem(Dialog,IDC_LSTRUCT);
+ wnd2:=GetDlgItem(Dialog,IDC_SRV_LPAR);
+ end;
+ i:=CB_GetData(GetDlgItem(Dialog,loword(wParam)));
+
+ if i=ptStruct then
+ begin
+ ShowWindow(wnd ,SW_HIDE);
+ ShowWindow(wnd2,SW_HIDE);
+ ShowWindow(wnd1,SW_SHOW);
+ end
+ else
+ begin
+ ShowWindow(wnd ,SW_SHOW);
+ ShowWindow(wnd2,SW_SHOW);
+ ShowWindow(wnd1,SW_HIDE);
+ if i in [ptCurrent,ptResult,ptParam] then
+ EnableWindow(wnd,false)
+ else
+ begin
+ EnableWindow(wnd,true);
+{
+ flag:=GetWindowLongPtr(wnd,GWL_STYLE);
+ if i=ptNumber then
+ flag:=flag or ES_NUMBER
+ else
+ flag:=flag and not ES_NUMBER;
+ SetWindowLongPtr(wnd,GWL_STYLE,flag);
+}
+ end;
+ end;
+ end;
+ IDC_EDIT_SERVICE: ReloadService;
+ end;
+ end;
+ BN_CLICKED: begin
+ case loword(wParam) of
+ IDC_GROUP_RELOAD, // don't affect to saved (DB) datas
+ IDC_WSTRUCT, // 'Changed' on process
+ IDC_LSTRUCT, // 'Changed' on process
+ IDC_HLP_FVARS,
+ IDC_HLP_VARS,
+ IDC_ADV_HVARS,
+ IDC_ACTION_HELP,
+ IDC_GROUP_EXPORT,
+ IDC_CNT_APPLY,
+ IDC_CNT_FILTER,
+ IDC_GROUP_TEST: ;
+
+ IDC_GROUP_UP,
+ IDC_GROUP_DOWN,
+ IDC_GROUP_NEW : SetChanged(Dialog,etHK);
+
+ IDC_GROUP_DELETE, // action deleting with subactions
+ IDC_GROUP_IMPORT,
+ IDC_ACTION_NEW,
+ IDC_ACTION_DELETE,
+ IDC_ACTION_UP,
+ IDC_ACTION_DOWN: begin
+ ChMask:=ChMask or ACTM_ACT or ACTM_ACTS;
+ SetChanged(Dialog,etHK+etACT);
+ end;
+ else
+ ChMask:=ChMask or ACTM_ACT or ACTM_ACTS;
+ SetChanged(Dialog,etACT);
+ end;
+
+ case loword(wParam) of
+ IDC_SRV_WPAR,
+ IDC_SRV_LPAR,
+ IDC_SRV_SRVC,
+ IDC_PRG_PRG ,
+ IDC_PRG_ARG ,
+ IDC_TXT_FILE,
+ IDC_TXT_TEXT,
+ IDC_RW_MVAR ,
+ IDC_RW_SVAR ,
+ IDC_RW_TVAR ,
+ IDC_MSG_TTL ,
+ IDC_MSG_TXT : SetButtonIcon(lParam,checknames[IsDlgButtonChecked(Dialog,loword(wParam))]);
+ end;
+
+ case loword(wParam) of
+ IDC_CNT_FILTER,
+ IDC_CNT_APPLY: begin
+ if loword(wParam)=IDC_CNT_APPLY then
+ begin
+ mFreeMem(fCLformat);
+ fCLformat:=GetDlgText(Dialog,IDC_EDIT_FORMAT);
+ DBWriteUnicode(0,DBBranch,'CLformat',fCLformat);
+ end
+ else
+ begin
+ fCLfilter:=IsDlgButtonChecked(Dialog,IDC_CNT_FILTER)<>BST_UNCHECKED;
+ DBWriteByte(0,DBBranch,'CLfilter',ord(fCLfilter));
+ end;
+// Saving and restoring contact after list rebuild
+ wnd:=GetDlgItem(Dialog,IDC_CONTACTLIST);
+ i:=SendMessage(wnd,CB_GETITEMDATA,SendMessage(wnd,CB_GETCURSEL,0,0),0);
+
+ FillContactList(wnd,fCLfilter,fCLformat);
+
+ SendMessage(wnd,CB_SETCURSEL,FindContact(wnd,i),0);
+ end;
+ IDC_HLP_FVARS,
+ IDC_HLP_VARS : ShowHelp(hlpVariables);
+ IDC_ADV_HVARS: ShowHelp(hlpAdvVariables);
+
+ IDC_GROUP_EXPORT: begin
+ if ShowDlgW(xmlfilename,xmlfilename,inoutfilter,false) then
+ begin
+ wnd:=GetDlgItem(Dialog,IDC_ACTION_GROUP);
+ for i:=0 to ListView_GetItemCount(wnd)-1 do
+ begin
+ if ListView_GetItemState(wnd,i,LVIS_SELECTED)<>0 then
+ begin
+ with GroupList[LV_GetLParam(wnd,i)] do
+ if (flags and ACF_ASSIGNED)<>0 then // must be always true
+ flags:=flags or ACF_EXPORT;
+ end
+ else
+ with GroupList[i] do
+ if (flags and (ACF_EXPORT or ACF_ASSIGNED))=
+ (ACF_EXPORT or ACF_ASSIGNED) then
+ flags:=flags and not ACF_EXPORT;
+ end;
+ i:=ACIO_EXPORT or ACIO_SELECTED;
+ if GetFSize(xmlfilename)>0 then
+ if MessageBoxW(Dialog,TranslateW('Append data to file'),
+ PluginName,MB_YESNO+MB_ICONWARNING)=IDYES then
+ i:=i or ACIO_APPEND;
+ CallService(MS_ACT_INOUT,i,TLPARAM(@xmlfilename));
+// Export({GetLParam(GetDlgItem(Dialog,IDC_ACTION_GROUP)),}xmlfilename,i);
+ for i:=0 to MaxGroups-1 do
+ with GroupList[i] do
+ if (flags and (ACF_EXPORT or ACF_ASSIGNED))=
+ (ACF_EXPORT or ACF_ASSIGNED) then
+ flags:=flags and not ACF_EXPORT;
+ end;
+ end;
+
+ IDC_GROUP_IMPORT: begin
+ if ShowDlgW(xmlfilename,xmlfilename,inoutfilter) then
+ begin
+// if Import(xmlfilename) then
+ if CallService(MS_ACT_INOUT,0,TLPARAM(@xmlfilename))<>0 then
+ begin
+ ChMask:=ChMask or ACTM_NEW;
+ SendMessage(Dialog,WM_COMMAND,IDC_GROUP_RELOAD+(BN_CLICKED shl 16),
+ GetDlgItem(Dialog,IDC_GROUP_RELOAD));
+//(in reload) FillChainList(Dialog);
+ end;
+ end;
+ end;
+
+ IDC_WSTRUCT, IDC_LSTRUCT: begin
+ if loword(wParam)=IDC_WSTRUCT then
+ pc:=wstruct
+ else
+ pc:=lstruct;
+//!!!!
+ pAnsiChar(j):=EditStructure(pAnsiChar(pc),Dialog);
+ if j<>0 then
+ begin
+ ChMask:=ChMask or ACTM_ACT or ACTM_ACTS;
+ SetChanged(Dialog,etACT);
+ mFreeMem(pAnsiChar(pc));
+ pc:=pAnsiChar(j);
+
+ if loword(wParam)=IDC_WSTRUCT then
+ wstruct:=pc
+ else
+ lstruct:=pc;
+ end;
+ end;
+
+ IDC_PROGRAM: begin
+ FillFileName(IDC_EDIT_PRGPATH);
+ end;
+ IDC_FILE_FILEBTN: begin
+ FillFileName(IDC_FILE_PATH);
+ end;
+
+ IDC_GROUP_TEST: begin
+ wnd:=GetDlgItem(Dialog,IDC_ACTION_LIST);
+ li.mask :=LVIF_PARAM;
+ li.iSubItem:=0;
+ li.iItem :=0;
+ SendMessageW(wnd,LVM_GETITEMW,0,tlparam(@li));
+ j:=SendMessage(wnd,LVM_GETNEXTITEM,-1,LVNI_FOCUSED);
+
+ ActionStarterWait(li.lParam);
+ // doubling from "reload" button
+ wnd:=GetDlgItem(Dialog,IDC_ACTION_GROUP);
+ i:=SendMessage(wnd,LVM_GETNEXTITEM,-1,LVNI_FOCUSED);
+ NewGroupList :=GroupList;
+ NewMaxGroups :=MaxGroups;
+ NewActionList:=ActionList;
+ NewMaxActions:=MaxActions;
+ FillGroupList{(Dialog)};
+ FillChainList(Dialog);
+
+ Listview_SetItemState(wnd,0,0,LVIS_FOCUSED or LVIS_SELECTED);
+ Listview_SetItemState(wnd,i,
+ LVIS_FOCUSED or LVIS_SELECTED,
+ LVIS_FOCUSED or LVIS_SELECTED);
+ SendMessage(wnd,LVM_ENSUREVISIBLE,i,0);
+
+ wnd:=GetDlgItem(Dialog,IDC_ACTION_LIST);
+ Listview_SetItemState(wnd,0,0,LVIS_FOCUSED or LVIS_SELECTED);
+ Listview_SetItemState(wnd,j,
+ LVIS_FOCUSED or LVIS_SELECTED,
+ LVIS_FOCUSED or LVIS_SELECTED);
+ SendMessage(wnd,LVM_ENSUREVISIBLE,j,0);
+
+ end;
+ IDC_GROUP_NEW: begin
+ i:=AddGroup(Dialog,NewGroup(NewGroupList,NewMaxGroups));
+ if i>=0 then
+ begin
+ ChMask:=ChMask or ACTM_NEW or ACTM_SORT;
+ EnableWindow(GetDlgItem(Dialog,IDC_ACTION_GROUP),true);
+ EnableWindow(GetDlgItem(Dialog,IDC_GROUP_DELETE),true);
+ EnableWindow(GetDlgItem(Dialog,IDC_ACTION_NEW ),true);
+ FillChainList(Dialog);
+ CheckGrpList(i);
+ end;
+ end;
+ IDC_GROUP_DELETE: begin
+ wnd:=GetDlgItem(Dialog,IDC_ACTION_GROUP);
+ for i:=ListView_GetItemCount(wnd)-1 downto 0 do
+ begin
+ if ListView_GetItemState(wnd,i,LVIS_SELECTED)<>0 then
+ begin
+ ChMask:=ChMask or ACTM_DELETE or ACTM_SORT;
+
+ with NewGroupList^[LV_GetLParam(wnd,i)] do
+ begin
+ flags:=0;
+ mFreeMem(descr);
+ FreeActions(NewActionList,firstAction);
+ end;
+
+ SendMessage(wnd,LVM_DELETEITEM,i,0);
+ end;
+ end;
+ SendDlgItemMessage(Dialog,IDC_ACTION_LIST,LVM_DELETEALLITEMS,0,0);
+ FillChainList(Dialog);
+ Listview_SetItemState(wnd,0,LVIS_FOCUSED or LVIS_SELECTED,
+ LVIS_FOCUSED or LVIS_SELECTED);
+ CheckGroupList(-1);
+{
+ i:=SendMessageW(wnd,LVM_GETNEXTITEM,-1,LVNI_FOCUSED); //??
+ if i>=0 then
+ begin
+ ChMask:=ChMask or ACTM_DELETE;
+ j:=GetLParam(wnd,i);
+
+ with NewGroupList^[j] do
+ begin
+ flags:=0;
+ mFreeMem(descr);
+ FreeActions(NewActionList,firstAction);
+ end;
+ SendDlgItemMessage(Dialog,IDC_ACTION_LIST,LVM_DELETEALLITEMS,0,0);
+
+//?? i:=ListView_GetNextItem(wnd,-1,LVNI_FOCUSED);
+ SendMessage(wnd,LVM_DELETEITEM,i,0);
+ FillChainList(Dialog);
+ CheckGroupList(i);
+ end;
+}
+ end;
+ IDC_GROUP_RELOAD: begin
+ ChMask:=ChMask or ACTM_RELOAD;
+ SetCancel;
+ NewGroupList :=GroupList;
+ NewMaxGroups :=MaxGroups;
+ NewActionList:=ActionList;
+ NewMaxActions:=MaxActions;
+ FillGroupList{(Dialog)};
+ FillChainList(Dialog);
+ end;
+
+ IDC_ACTION_HELP: begin
+ ShowHelp(SendDlgItemMessage(Dialog,IDC_ACTION_TYPE,CB_GETCURSEL,0,0));
+ end;
+
+ IDC_ACTION_NEW: begin
+ wnd:=GetDlgItem(Dialog,IDC_ACTION_LIST);
+ li.mask :=LVIF_PARAM;
+ i :=SendMessage(wnd,LVM_GETNEXTITEM,-1,LVNI_FOCUSED);
+ li.iItem :=i+1;
+ li.iSubItem:=0;
+ li.lParam :=NewAction(NewActionList,NewMaxActions);
+ SendMessageW(wnd,LVM_INSERTITEMW,0,tlparam(@li));
+ ListView_SetCheckState(wnd,li.iItem,true);
+ if li.iItem=0 then
+ begin
+ ListView_SetItemState(wnd,0,LVIS_FOCUSED or LVIS_SELECTED,
+ LVIS_FOCUSED or LVIS_SELECTED);
+ SHActButtons(SW_SHOW);
+ end;
+ ChangeActionName(li.iItem);
+ EnableWindow(GetDlgItem(Dialog,IDC_ACTION_LIST ),true);
+ EnableWindow(GetDlgItem(Dialog,IDC_ACTION_HELP ),true);
+ EnableWindow(GetDlgItem(Dialog,IDC_GROUP_TEST ),true);
+ EnableWindow(GetDlgItem(Dialog,IDC_ACTION_DELETE),true);
+ EnableWindow(GetDlgItem(Dialog,IDC_ACTION_TYPE ),true);
+ CheckActList(i);
+
+ wnd:=GetDlgItem(Dialog,IDC_ADV_VAL2);
+ i:=SendMessage(wnd,CB_GETCURSEL,0,0);
+ FillSubList(Dialog);
+ SendMessage(wnd,CB_SETCURSEL,i,0);
+ end;
+ IDC_ACTION_DELETE: begin
+ wnd:=GetDlgItem(Dialog,IDC_ACTION_LIST);
+ for i:=ListView_GetItemCount(wnd)-1 downto 0 do
+ begin
+ if ListView_GetItemState(wnd,i,LVIS_SELECTED)<>0 then
+ begin
+ FreeAction(@NewActionList^[LV_GetLParam(wnd,i)]);
+ SendMessage(wnd,LVM_DELETEITEM,i,0);
+ end;
+ end;
+ Listview_SetItemState(wnd,0,LVIS_FOCUSED or LVIS_SELECTED,
+ LVIS_FOCUSED or LVIS_SELECTED);
+ CheckActionList(0);
+{
+ wnd:=GetDlgItem(Dialog,IDC_ACTION_LIST);
+ li.iItem:=SendMessage(wnd,LVM_GETNEXTITEM,-1,LVNI_FOCUSED); //??
+ if li.iItem>=0 then
+ begin
+ li.mask :=LVIF_PARAM;
+ li.iSubItem:=0;
+ SendMessageW(wnd,LVM_GETITEM,0,dword(@li));
+ FreeAction(@NewActionList^[li.lParam]);
+
+ SendMessage(wnd,LVM_DELETEITEM,li.iItem,0);
+ CheckActionList(li.iItem);
+ end;
+}
+ end;
+
+ IDC_GROUP_UP: begin
+ wnd:=GetDlgItem(Dialog,IDC_ACTION_GROUP);
+// i:=SendMessage(wnd,LVM_GETNEXTITEM,-1,LVNI_FOCUSED);
+// if i>0 then
+ begin
+ CheckGrpList(MoveGroup(wnd,-1,-1));
+ ChMask:=ChMask or ACTM_SORT;
+ end;
+ end;
+ IDC_GROUP_DOWN: begin
+ wnd:=GetDlgItem(Dialog,IDC_ACTION_GROUP);
+// i:=SendMessage(wnd,LVM_GETNEXTITEM,-1,LVNI_FOCUSED);
+// if i<(SendMessage(wnd,LVM_GETITEMCOUNT,0,0)-1) then
+ begin
+ CheckGrpList(MoveGroup(wnd,-1,1));
+ ChMask:=ChMask or ACTM_SORT;
+ end;
+ end;
+
+ IDC_ACTION_UP: begin
+ wnd:=GetDlgItem(Dialog,IDC_ACTION_LIST);
+// i:=SendMessage(wnd,LVM_GETNEXTITEM,-1,LVNI_FOCUSED);
+// if i>0 then
+ CheckActList(MoveGroup(wnd,-1,-1));
+ end;
+ IDC_ACTION_DOWN: begin
+ wnd:=GetDlgItem(Dialog,IDC_ACTION_LIST);
+// i:=SendMessage(wnd,LVM_GETNEXTITEM,-1,LVNI_FOCUSED);
+// if i<(SendMessage(wnd,LVM_GETITEMCOUNT,0,0)-1) then
+ CheckActList(MoveGroup(wnd,-1,1));
+ end;
+
+ IDC_FILE_WRITE, IDC_FILE_READ, IDC_FILE_APPEND:
+ EnableWindow(GetDlgItem(Dialog,IDC_EDIT_INSERT),
+ loword(wParam)<>IDC_FILE_APPEND);
+
+ IDC_RW_DELETE,
+ IDC_RW_READ,
+ IDC_RW_WRITE: begin
+ b:=loword(wParam)<>IDC_RW_DELETE;
+ EnableWindow(GetDlgItem(Dialog,IDC_RW_DATATYPE),b);
+ EnableWindow(GetDlgItem(Dialog,IDC_RW_LAST ),b);
+ EnableWindow(GetDlgItem(Dialog,IDC_RW_VALUE ),b);
+ EnableWindow(GetDlgItem(Dialog,IDC_RW_TEXT ),b);
+ end;
+
+ IDC_FLAG_CLIP,IDC_FLAG_FILE,IDC_FLAG_MESSAGE: begin
+ b:=loword(wParam)=IDC_FLAG_CLIP;
+//!! +text read = disabled
+ EnableWindow(GetDlgItem(Dialog,IDC_CLIP_COPYTO),b);
+ EnableWindow(GetDlgItem(Dialog,IDC_CLIP_PASTE ),b);
+ b:=b or ((loword(wParam)=IDC_FLAG_FILE) and
+ (IsDlgButtonChecked(Dialog,IDC_FILE_READ)<>BST_UNCHECKED));
+ EnableWindow(GetDlgItem(Dialog,IDC_EDIT_INSERT),not b);
+
+ b:=loword(wParam)=IDC_FLAG_FILE;
+ EnableWindow(GetDlgItem(Dialog,IDC_FILE_ENC ),b);
+ EnableWindow(GetDlgItem(Dialog,IDC_FILE_PATH ),b);
+ EnableWindow(GetDlgItem(Dialog,IDC_FILE_FILEBTN),b);
+ EnableWindow(GetDlgItem(Dialog,IDC_FILE_READ ),b);
+ EnableWindow(GetDlgItem(Dialog,IDC_FILE_WRITE ),b);
+ EnableWindow(GetDlgItem(Dialog,IDC_FILE_APPEND ),b);
+ end;
+
+ IDC_FLAG_JUMP: begin
+ EnableWindow(GetDlgItem(Dialog,IDC_ADV_VAL2),true);
+ end;
+
+ IDC_FLAG_BREAK,IDC_FLAG_ANOP:
+ begin
+ EnableWindow(GetDlgItem(Dialog,IDC_ADV_VAL2),false);
+ end;
+
+ IDC_FLAG_VARS: begin
+ if IsDlgButtonChecked(Dialog,IDC_FLAG_VARS)<>BST_UNCHECKED then
+ begin
+ SHMath(false);
+ CheckDlgButton(Dialog,IDC_FLAG_MATH,BST_UNCHECKED);
+ end
+ else
+ begin
+ EnableWindow(GetDlgItem(Dialog,IDC_ADV_ASINT),false);
+ EnableWindow(GetDlgItem(Dialog,IDC_ADV_VARS ),false);
+ end;
+ end;
+ IDC_FLAG_MATH: begin
+ if IsDlgButtonChecked(Dialog,IDC_FLAG_MATH)<>BST_UNCHECKED then
+ begin
+ SHMath(true);
+ CheckDlgButton(Dialog,IDC_FLAG_VARS,BST_UNCHECKED);
+ end
+ else
+ begin
+ EnableWindow(GetDlgItem(Dialog,IDC_ADV_OPER),false);
+ EnableWindow(GetDlgItem(Dialog,IDC_ADV_VAL1),false);
+ end;
+ end;
+
+ IDC_RW_CURRENT, IDC_RW_RESULT, IDC_RW_PARAM: begin
+ EnableWindow(GetDlgItem(Dialog,IDC_CONTACTLIST),false);
+ end;
+ IDC_RW_MANUAL: EnableWindow(GetDlgItem(Dialog,IDC_CONTACTLIST),true);
+
+ IDC_RW_LAST: begin
+ b :=IsDlgButtonChecked(Dialog,IDC_RW_LAST )=BST_UNCHECKED;
+ EnableWindow(GetDlgItem(Dialog,IDC_RW_VALUE), b);
+ EnableWindow(GetDlgItem(Dialog,IDC_RW_TEXT ), b);
+ end;
+ end;
+ end;
+ end;
+ end;
+
+ WM_HELP: begin
+ if (PHELPINFO(lParam)^.iContextType=HELPINFO_WINDOW) then
+ ShowHelp(SendDlgItemMessage(Dialog,IDC_ACTION_TYPE,CB_GETCURSEL,0,0));
+ end;
+
+ WM_NOTIFY: begin
+ case integer(PNMHdr(lParam)^.code) of
+ PSN_APPLY: begin
+ BuildActionChain;
+ SetSave(Dialog,LV_GetLParam(GetDlgItem(Dialog,IDC_ACTION_GROUP)));
+
+ if ActionList<>NewActionList then
+ begin
+ DestroyActions(ActionList,MaxActions);
+ ActionList:=NewActionList;
+ MaxActions:=NewMaxActions;
+ end;
+
+ SaveGroups;
+
+ if ChMask<>0 then //??
+ begin
+ NotifyEventHooks(hHookChanged,ChMask,0);
+ ChMask:=0;
+ end;
+
+ end;
+
+ NM_DBLCLK: begin
+ if PNMListView(lParam)^.iItem>=0 then
+ PostMessageW(PNMHdr(lParam)^.hWndFrom,LVM_EDITLABELW,
+ PNMListView(lParam)^.iItem,0);
+ end;
+
+ LVN_ITEMCHANGED: begin
+ if DontReact then exit; // bug when group moved avoid
+
+ if wParam=IDC_ACTION_GROUP then
+ begin
+ if PNMLISTVIEW(lParam)^.uChanged=LVIF_STATE then
+ begin
+ lvflag:=(PNMLISTVIEW(lParam)^.uOldState and LVNI_FOCUSED)-
+ (PNMLISTVIEW(lParam)^.uNewState and LVNI_FOCUSED);
+
+ if lvflag>0 then // old focus
+ BuildActionChain(PNMLISTVIEW(lParam)^.iItem)
+ else if lvflag<0 then // new focus
+ begin
+ DontReact:=true;
+
+ ClearDialogData;
+ MakeActionList(@NewGroupList^[PNMLISTVIEW(lParam)^.lParam]);
+ CheckGrpList(PNMLISTVIEW(lParam)^.iItem);
+
+ DontReact:=false;
+ end
+ else
+ begin
+ lvflag:=(PNMLISTVIEW(lParam)^.uOldState and LVNI_SELECTED)-
+ (PNMLISTVIEW(lParam)^.uNewState and LVNI_SELECTED);
+ if lvflag<>0 then
+ CheckGrpList(PNMLISTVIEW(lParam)^.iItem);
+ end;
+ end;
+ end
+ else if wParam=IDC_ACTION_LIST then
+ begin
+ lvflag:=(PNMLISTVIEW(lParam)^.uOldState and LVNI_FOCUSED)-
+ (PNMLISTVIEW(lParam)^.uNewState and LVNI_FOCUSED);
+ if lvflag>0 then // old focus
+ SaveAction(PNMLISTVIEW(lParam)^.iItem,
+ PNMLISTVIEW(lParam)^.lParam)
+ else if lvflag<0 then // new focus
+ begin
+ DontReact:=true;
+
+ ClearDialogData;
+ j:=PNMLISTVIEW(lParam)^.lParam;
+ FillAction(j);
+ CheckActList(PNMLISTVIEW(lParam)^.iItem);
+
+ DontReact:=false;
+ end
+ else
+ begin // checkboxes
+ lvflag:=(PNMLISTVIEW(lParam)^.uOldState and LVNI_SELECTED)-
+ (PNMLISTVIEW(lParam)^.uNewState and LVNI_SELECTED);
+ if lvflag<>0 then
+ CheckGrpList(PNMLISTVIEW(lParam)^.iItem);
+
+ if (PNMLISTVIEW(lParam)^.uOldState or PNMLISTVIEW(lParam)^.uNewState)=$3000 then
+ begin
+ if PNMLISTVIEW(lParam)^.uOldState=$1000 then
+ i:=0
+ else
+ i:=ACF_DISABLED;
+ j:=PNMLISTVIEW(lParam)^.lParam;
+ NewActionList^[j].flags:=(NewActionList^[j].flags and not ACF_DISABLED) or dword(i);
+ ChMask:=ChMask or ACTM_ACT or ACTM_ACTS;
+ SetChanged(Dialog,etACT);
+ end;
+ end;
+ end;
+ end;
+
+ LVN_ENDLABELEDITW: begin
+ if DontReact then exit;
+ if wParam=IDC_ACTION_GROUP then
+ begin
+ with PLVDISPINFOW(lParam)^ do
+ begin
+ if item.pszText<>nil then
+ begin
+ ChMask:=ChMask or ACTM_RENAME;
+ SetChanged(Dialog,etHK);
+ item.mask:=LVIF_TEXT;
+ if pWideChar(item.pszText)^=#0 then
+ pWideChar(item.pszText):=NoDescription;
+ SendMessageW(hdr.hWndFrom,LVM_SETITEMW,0,tlparam(@item));
+
+ with NewGroupList^[item.lParam] do
+ begin
+ mFreeMem(descr);
+ StrDupW(descr,item.pszText);
+ end;
+
+ FillChainList(Dialog);
+ result:=1;
+ end;
+ end;
+ end
+ else if wParam=IDC_ACTION_LIST then
+ begin
+ with PLVDISPINFOW(lParam)^ do
+ begin
+ if item.pszText<>nil then
+ begin
+ ChMask:=ChMask or ACTM_ACT or ACTM_ACTS;
+ SetChanged(Dialog,etACT);
+ ChangeActionName(item.iItem,0,pWideChar(item.pszText));
+ result:=1;
+ end;
+//??
+ end;
+ end;
+ end;
+
+ end;
+ end;
+ else
+// {result:=}DefWindowProc(Dialog,hMessage,wParam,lParam);
+ end;
+// {result:=}DefWindowProc(Dialog,hMessage,wParam,lParam);
+end;
diff --git a/plugins/Actman/i_options.inc b/plugins/Actman/i_options.inc
new file mode 100644
index 0000000000..64a6b856cc
--- /dev/null
+++ b/plugins/Actman/i_options.inc
@@ -0,0 +1,459 @@
+{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 NumGroups<HKListPage then
+ MaxGroups:=HKListPage
+ else
+ MaxGroups:=NumGroups;
+ GetMem (GroupList ,MaxGroups*SizeOf(tHKRecord));
+ FillChar(GroupList^,MaxGroups*SizeOf(tHKRecord),0);
+
+{ remove doubling - no need? (called just once)
+ if MaxActions<>0 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 NumActions<ActListPage then
+ MaxActions:=ActListPage
+ else
+ MaxActions:=NumActions+1;
+ GetMem (ActionList ,MaxActions*SizeOf(tHKAction));
+ FillChar(ActionList^,MaxActions*SizeOf(tHKAction),0);
+
+ HK:=@GroupList^; //??
+ i:=0;
+ p1:=StrCopyE(section,opt_group);
+ while i<NumGroups do
+ begin
+ p:=StrEnd(IntToStr(p1,i));
+ p^:='/'; inc(p);
+
+ StrCopy(p,opt_flags);
+ with HK^ do
+ begin
+ flags:=DBReadDWord(0,DBBranch,section,0{integer(ACF_ASSIGNED or ACF_DISABLED)});
+ if (flags and ACF_ASSIGNED)<>0 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;
diff --git a/plugins/Actman/i_services.inc b/plugins/Actman/i_services.inc
new file mode 100644
index 0000000000..d835c9225a
--- /dev/null
+++ b/plugins/Actman/i_services.inc
@@ -0,0 +1,131 @@
+{Basic ActMan services}
+
+function ActFreeList(wParam:WPARAM;lParam:LPARAM):int_ptr;cdecl;
+begin
+ result:=0;
+ mFreeMem(PAnsiChar(lParam));
+end;
+
+function ActGetList(wParam:WPARAM;lParam:LPARAM):int_ptr;cdecl;
+var
+ pc:^tChain;
+ p:pHKRecord;
+ i,cnt:integer;
+begin
+ p:=@GroupList[0];
+ cnt:=0;
+ for i:=0 to MaxGroups-1 do
+ begin
+ if (p^.flags and (ACF_ASSIGNED or ACF_VOLATILE))=ACF_ASSIGNED then inc(cnt);
+ inc(p);
+ end;
+ result:=cnt;
+ if lParam=0 then exit;
+ if cnt>0 then
+ 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
+ begin
+ if (p^.flags and (ACF_ASSIGNED or ACF_VOLATILE))=ACF_ASSIGNED then
+ begin
+ pc^.descr:=p^.descr;
+ pc^.id :=p^.id;
+ pc^.flags:=p^.flags;
+ inc(pc);
+ end;
+ inc(p);
+ end;
+ end
+ else
+ puint_ptr(lParam)^:=0;
+// {$IFDEF WIN64}pqword{$ELSE}pdword{$ENDIF}(lParam)^:=0;
+end;
+
+function ActRun(wParam:WPARAM;lParam:LPARAM):int_ptr;cdecl;
+var
+ i:integer;
+ p:pHKRecord;
+begin
+ result:=-1;
+ p:=@GroupList[0];
+ for i:=0 to MaxGroups-1 do
+ begin
+ if ((p^.flags and ACF_ASSIGNED)<>0) and (p^.id=dword(wParam)) then
+ begin
+ result:=p^.firstAction;
+ break;
+ end;
+ inc(p);
+ end;
+ if result>0 then
+ result:=ActionStarter(result,lParam,p);
+end;
+
+function ActRunGroup(wParam:WPARAM;lParam:LPARAM):int_ptr;cdecl;
+var
+ i:integer;
+ p:pHKRecord;
+begin
+ result:=-1;
+ p:=@GroupList[0];
+ for i:=0 to MaxGroups-1 do
+ begin
+ if ((p^.flags and ACF_ASSIGNED)<>0) and (StrCmpW(p^.descr,pWideChar(wParam))=0) then
+ begin
+ result:=p^.firstAction;
+ break;
+ end;
+ inc(p);
+ end;
+ if result>0 then
+ result:=ActionStarter(result,lParam,p);
+end;
+
+function ActRunParam(wParam:WPARAM;lParam:LPARAM):int_ptr;cdecl;
+var
+ i:integer;
+ p:pHKRecord;
+begin
+ result:=-1;
+ p:=@GroupList[0];
+
+ if (pAct_Param(lParam)^.flags and ACTP_BYNAME)=0 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;
+ end;
+ inc(p);
+ end;
+ end
+ else
+ begin
+ for i:=0 to MaxGroups-1 do
+ 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;
+
+ if result>0 then
+ begin
+ if (pAct_Param(lParam)^.flags and ACTP_WAIT)=0 then
+ result:=ActionStarter (result,pAct_Param(lParam)^.wParam,p,pAct_Param(lParam)^.lParam)
+ else
+ result:=ActionStarterWait(result,pAct_Param(lParam)^.wParam,p,pAct_Param(lParam)^.lParam);
+ end;
+end;
diff --git a/plugins/Actman/i_vars.inc b/plugins/Actman/i_vars.inc
new file mode 100644
index 0000000000..4ca6764191
--- /dev/null
+++ b/plugins/Actman/i_vars.inc
@@ -0,0 +1,31 @@
+{variables}
+type
+ pHKList = ^tHKList;
+ tHKList = array [0..1023] of tHKRecord;
+ pActList = ^tActList;
+ tActList = array [0..1023] of tHKAction;
+const
+ StructDelim = #7;
+const
+ HKListPage = 8;
+ ActListPage = 16;
+var
+ MaxGroups :cardinal=0; // current array size
+ MaxActions:cardinal=0; // current array size
+var
+ GroupList :pHKList =nil;
+ ActionList:pActList=nil;
+var
+ NoDescription:PWideChar;
+var
+ NewGroupList :pHKList = nil;
+ NewActionList:pActList = nil;
+ NewMaxGroups :cardinal;
+ NewMaxActions:cardinal;
+var
+ xmlfilename:array [0..511] of WideChar;
+var
+ fCLfilter:boolean = true;
+ fCLformat:pWideChar = nil;
+var
+ ApiCard:tmApiCard; \ No newline at end of file
diff --git a/plugins/Actman/i_visual.inc b/plugins/Actman/i_visual.inc
new file mode 100644
index 0000000000..ab32488165
--- /dev/null
+++ b/plugins/Actman/i_visual.inc
@@ -0,0 +1,1073 @@
+{Dialog visual part, depends of Dialog window}
+ procedure SHControl(ctrl,mode:dword);
+ begin
+ ShowWindow(GetDlgItem(Dialog,ctrl),mode);
+ end;
+
+ procedure SetupControls(group,mode:dword);
+ begin
+ case group of
+ ACT_CONTACT: begin
+ SHControl(IDC_STAT_CONTACT,mode);
+ SHControl(IDC_CONTACTLIST ,mode);
+ SHControl(IDC_CNT_KEEP ,mode);
+ SHControl(IDC_CNT_FILTER ,mode);
+ SHControl(IDC_STAT_FORMAT ,mode);
+ SHControl(IDC_EDIT_FORMAT ,mode);
+ SHControl(IDC_CNT_APPLY ,mode);
+ SHControl(IDC_STAT_FHELP ,mode);
+ end;
+ ACT_SERVICE: begin
+ SHControl(IDC_STAT_WPAR ,mode);
+ SHControl(IDC_STAT_LPAR ,mode);
+ SHControl(IDC_STAT_WPAR1 ,mode);
+ SHControl(IDC_STAT_LPAR1 ,mode);
+ SHControl(IDC_STAT_SERVICE,mode);
+ SHControl(IDC_EDIT_SERVICE,mode);
+ SHControl(IDC_SRV_SRVC ,mode);
+ SHControl(IDC_FLAG_WPAR ,mode);
+ SHControl(IDC_FLAG_LPAR ,mode);
+
+ SHControl(IDC_RES_GROUP ,mode);
+ SHControl(IDC_RES_POPUP ,mode);
+ SHControl(IDC_RES_MESSAGE ,mode);
+ SHControl(IDC_RES_INSERT ,mode);
+
+ SHControl(IDC_SRV_RESULT ,mode);
+ SHControl(IDC_SRV_RESSTAT ,mode);
+
+ if mode=SW_SHOW then
+ begin
+//!! Check parameter type
+ if CB_GetData(GetDlgItem(Dialog,IDC_FLAG_WPAR))=ptStruct then
+// if SendDlgItemMessage(Dialog,IDC_FLAG_WPAR,CB_GETCURSEL,0,0)=ptStruct then
+ begin
+ SHControl(IDC_WSTRUCT ,SW_SHOW);
+ SHControl(IDC_EDIT_WPAR,SW_HIDE);
+ SHControl(IDC_SRV_WPAR ,SW_HIDE);
+ end
+ else
+ begin
+ SHControl(IDC_WSTRUCT ,SW_HIDE);
+ SHControl(IDC_EDIT_WPAR,SW_SHOW);
+ SHControl(IDC_SRV_WPAR ,SW_SHOW);
+ end;
+ if CB_GetData(GetDlgItem(Dialog,IDC_FLAG_LPAR))=ptStruct then
+// if SendDlgItemMessage(Dialog,IDC_FLAG_LPAR,CB_GETCURSEL,0,0)=ptStruct then
+ begin
+ SHControl(IDC_LSTRUCT ,SW_SHOW);
+ SHControl(IDC_EDIT_LPAR,SW_HIDE);
+ SHControl(IDC_SRV_LPAR ,SW_HIDE);
+ end
+ else
+ begin
+ SHControl(IDC_LSTRUCT ,SW_HIDE);
+ SHControl(IDC_EDIT_LPAR,SW_SHOW);
+ SHControl(IDC_SRV_LPAR ,SW_SHOW);
+ end;
+
+ case CB_GetData(GetDlgItem(Dialog,IDC_SRV_RESULT)) of
+ sresHex: ;
+ sresInt: SHControl(IDC_RES_SIGNED,SW_SHOW);
+ sresString: begin
+ SHControl(IDC_RES_UNICODE,SW_SHOW);
+ SHControl(IDC_RES_FREEMEM,SW_SHOW);
+ end;
+ sresStruct: ;
+ end;
+
+ end
+ else
+ begin
+ SHControl(IDC_WSTRUCT ,SW_HIDE);
+ SHControl(IDC_LSTRUCT ,SW_HIDE);
+ SHControl(IDC_SRV_WPAR ,SW_HIDE);
+ SHControl(IDC_SRV_LPAR ,SW_HIDE);
+ SHControl(IDC_EDIT_WPAR ,SW_HIDE);
+ SHControl(IDC_EDIT_LPAR ,SW_HIDE);
+ SHControl(IDC_RES_FREEMEM,SW_HIDE);
+ SHControl(IDC_RES_UNICODE,SW_HIDE);
+ SHControl(IDC_RES_SIGNED ,SW_HIDE);
+ end;
+ end;
+ ACT_PROGRAM: begin
+ SHControl(IDC_PROCESS_GROUP,mode);
+ SHControl(IDC_PROGRAM ,mode);
+ SHControl(IDC_EDIT_PROCTIME,mode);
+ SHControl(IDC_EDIT_PRGPATH ,mode);
+ SHControl(IDC_PRG_PRG ,mode);
+ SHControl(IDC_EDIT_PRGARGS ,mode);
+ SHControl(IDC_PRG_ARG ,mode);
+ SHControl(IDC_STAT_PROCTIME,mode);
+ SHControl(IDC_STAT_PRGPATH ,mode);
+ SHControl(IDC_STAT_PRGARGS ,mode);
+
+ SHControl(IDC_PRSTART_GROUP,mode);
+ SHControl(IDC_FLAG_NORMAL ,mode);
+ SHControl(IDC_FLAG_HIDDEN ,mode);
+ SHControl(IDC_FLAG_MAXIMIZE,mode);
+ SHControl(IDC_FLAG_MINIMIZE,mode);
+
+ SHControl(IDC_FLAG_CURPATH,mode);
+ SHControl(IDC_FLAG_CONTINUE,mode);
+ SHControl(IDC_FLAG_PARALLEL,mode);
+
+ if mode=SW_SHOW then
+ begin
+ if isVarsInstalled then
+ SHControl(IDC_HLP_FVARS,SW_SHOW);
+ end
+ else
+ SHControl(IDC_HLP_FVARS,SW_HIDE);
+ end;
+ ACT_TEXT: begin
+ SHControl(IDC_FLAG_CLIP ,mode);
+ SHControl(IDC_FLAG_MESSAGE,mode);
+ SHControl(IDC_CLIP_COPYTO ,mode);
+ SHControl(IDC_CLIP_PASTE ,mode);
+ SHControl(IDC_CLIP_GROUP ,mode);
+ SHControl(IDC_FILE_ENC ,mode);
+
+ SHControl(IDC_FLAG_FILE ,mode);
+ SHControl(IDC_FILE_PATH ,mode);
+ SHControl(IDC_TXT_FILE ,mode);
+ SHControl(IDC_FILE_FILEBTN,mode);
+ SHControl(IDC_FILE_READ ,mode);
+ SHControl(IDC_FILE_WRITE ,mode);
+ SHControl(IDC_FILE_APPEND ,mode);
+ SHControl(IDC_FILE_GROUP ,mode);
+
+ SHControl(IDC_TXT_TEXT ,mode);
+ SHControl(IDC_EDIT_INSERT ,mode);
+ SHControl(IDC_STAT_INSERT ,mode);
+
+ if mode=SW_SHOW then
+ begin
+ if isVarsInstalled then
+ SHControl(IDC_HLP_VARS,SW_SHOW);
+ end
+ else
+ SHControl(IDC_HLP_VARS,SW_HIDE);
+ end;
+ ACT_ADVANCE: begin
+ SHControl(IDC_CONDITION,mode);
+ SHControl(IDC_FLAG_GT ,mode);
+ SHControl(IDC_FLAG_LT ,mode);
+ SHControl(IDC_FLAG_EQ ,mode);
+ SHControl(IDC_FLAG_NOP ,mode);
+ SHControl(IDC_FLAG_NOT ,mode);
+ SHControl(IDC_ADV_VALUE,mode);
+ SHControl(IDC_STAT_VAL ,mode);
+ SHControl(IDC_ADV_ASINT,mode);
+
+ SHControl(IDC_OPERATION ,mode);
+ SHControl(IDC_FLAG_BREAK,mode);
+ SHControl(IDC_FLAG_JUMP ,mode);
+ SHControl(IDC_FLAG_ANOP ,mode);
+
+ SHControl(IDC_FLAG_MATH,mode);
+ SHControl(IDC_ADV_OPER ,mode);
+ SHControl(IDC_ADV_VAL2 ,mode);
+ SHControl(IDC_ADV_VAL1 ,mode);
+
+ if mode=SW_SHOW then
+ begin
+ if isVarsInstalled then
+ SHControl(IDC_ADV_HVARS,SW_SHOW);
+ end
+ else
+ SHControl(IDC_ADV_HVARS,SW_HIDE);
+ SHControl(IDC_FLAG_VARS,mode);
+ SHControl(IDC_ADV_VARS ,mode);
+ end;
+ ACT_CHAIN: begin
+ SHControl(IDC_STAT_GROUPS,mode);
+ SHControl(IDC_GROUP_LIST ,mode);
+ end;
+ ACT_RW: begin
+ SHControl(IDC_STAT_CONTACT,mode);
+ SHControl(IDC_CONTACTLIST ,mode);
+
+ SHControl(IDC_RW_OPER ,mode);
+ SHControl(IDC_RW_VAL ,mode);
+ SHControl(IDC_RW_READ ,mode);
+ SHControl(IDC_RW_WRITE ,mode);
+ SHControl(IDC_RW_DELETE ,mode);
+ SHControl(IDC_RW_STATM ,mode);
+ SHControl(IDC_RW_MODULE ,mode);
+ SHControl(IDC_RW_STATS ,mode);
+ SHControl(IDC_RW_SETTING,mode);
+ SHControl(IDC_RW_TVAR ,mode);
+
+ if mode=SW_SHOW then
+ begin
+ if CB_GetData(GetDlgItem(Dialog,IDC_RW_DATATYPE))>2 then
+ begin
+ SHControl(IDC_RW_VALUE,SW_HIDE);
+ SHControl(IDC_RW_TEXT ,SW_SHOW);
+ end
+ else
+ begin
+ SHControl(IDC_RW_VALUE,SW_SHOW);
+ SHControl(IDC_RW_TEXT ,SW_HIDE);
+ end
+ end
+ else
+ begin
+ SHControl(IDC_RW_VALUE,SW_HIDE);
+ SHControl(IDC_RW_TEXT ,SW_HIDE);
+ end;
+ SHControl(IDC_RW_DATATYPE,mode);
+
+ SHControl(IDC_RW_CURRENT,mode);
+ SHControl(IDC_RW_PARAM ,mode);
+ SHControl(IDC_RW_RESULT ,mode);
+ SHControl(IDC_RW_MANUAL ,mode);
+ SHControl(IDC_RW_LAST ,mode);
+
+ SHControl(IDC_RW_MVAR ,mode);
+ SHControl(IDC_RW_SVAR ,mode);
+ end;
+ ACT_MESSAGE: begin
+ SHControl(IDC_MSG_KEEP ,mode);
+ SHControl(IDC_MSG_STAT1 ,mode);
+ SHControl(IDC_MSG_STAT2 ,mode);
+ SHControl(IDC_MSG_TITLE ,mode);
+ SHControl(IDC_MSG_TEXT ,mode);
+ SHControl(IDC_MSG_BTNS ,mode);
+ SHControl(IDC_MSGB_ARI ,mode);
+ SHControl(IDC_MSGB_OK ,mode);
+ SHControl(IDC_MSGB_OC ,mode);
+ SHControl(IDC_MSGB_RC ,mode);
+ SHControl(IDC_MSGB_YN ,mode);
+ SHControl(IDC_MSGB_YNC ,mode);
+ SHControl(IDC_MSG_ICONS ,mode);
+ SHControl(IDC_MSGI_NONE ,mode);
+ SHControl(IDC_MSGI_WARN ,mode);
+ SHControl(IDC_MSGI_INFO ,mode);
+ SHControl(IDC_MSGI_QUEST,mode);
+ SHControl(IDC_MSGI_ERROR,mode);
+
+ SHControl(IDC_MSG_TTL ,mode);
+ SHControl(IDC_MSG_TXT ,mode);
+ end;
+ end;
+ end;
+
+ procedure SetButtonOnOff(ctrl,state:dword);
+ begin
+ CheckDlgButton(Dialog,ctrl,state);
+ case ctrl of
+ IDC_SRV_WPAR,
+ IDC_SRV_LPAR,
+ IDC_SRV_SRVC,
+ IDC_PRG_PRG ,
+ IDC_PRG_ARG ,
+ IDC_TXT_FILE,
+ IDC_TXT_TEXT,
+ IDC_RW_MVAR ,
+ IDC_RW_SVAR ,
+ IDC_RW_TVAR ,
+ IDC_MSG_TTL ,
+ IDC_MSG_TXT : SetButtonIcon(GetDlgItem(Dialog,ctrl),checknames[state]);
+ end;
+ end;
+
+ procedure ButtonOff(ctrl:dword); {$IFDEF MSWINDOWS}inline;{$ENDIF}
+ begin
+ SetButtonOnOff(ctrl,BST_UNCHECKED);
+ end;
+
+ procedure ButtonOn(ctrl:dword); {$IFDEF MSWINDOWS}inline;{$ENDIF}
+ begin
+ SetButtonOnOff(ctrl,BST_CHECKED);
+ end;
+
+ procedure TextClear(ctrl:dword);
+ begin
+ SetDlgItemTextW(Dialog,ctrl,nil);
+ end;
+
+ function FixParam(buf:PAnsiChar;flag:integer):integer;
+ begin
+ if lstrcmpia(buf,Translate('hContact' ))=0 then result:=ptCurrent
+ else if lstrcmpia(buf,Translate('parameter'))=0 then result:=ptParam
+ else if lstrcmpia(buf,Translate('result' ))=0 then result:=ptResult
+ else if lstrcmpia(buf,Translate('structure'))=0 then result:=ptStruct
+ else
+ begin
+ if (buf[0] in ['0'..'9']) or ((buf[0]='-') and (buf[1] in ['0'..'9'])) or
+ ((buf[0]='$') and (buf[1] in sHexNum)) then
+ result:=ptNumber
+ else
+ result:=ptString;
+ end;
+
+ CB_SelectData(Dialog,flag,result);
+// SendDlgItemMessage(Dialog,flag,CB_SETCURSEL,result,0);
+ SendMessage(Dialog,WM_COMMAND,(CBN_SELCHANGE shl 16) or flag,GetDlgItem(Dialog,flag));
+ end;
+
+ procedure ReloadService;
+ var
+ pc:pAnsiChar;
+ buf,buf1:array [0..MaxDescrLen] of AnsiChar;
+ wnd:hwnd;
+ i:integer;
+// bufw:array [0..MaxDescrLen] of WideChar;
+ begin
+ wnd:=GetDlgItem(Dialog,IDC_EDIT_SERVICE);
+ SendMessageA(wnd,CB_GETLBTEXT,SendMessage(wnd,CB_GETCURSEL,0,0),tlparam(@buf));
+ ApiCard.Service:=@buf;
+
+ pc:=ApiCard.FillParams(GetDlgItem(Dialog,IDC_EDIT_WPAR),true);
+ if pc<>nil then
+ begin
+ if GetDlgItemTextA(Dialog,IDC_EDIT_WPAR,buf1,SizeOf(buf1))>0 then
+ case FixParam(@buf1,IDC_FLAG_WPAR) of
+ ptStruct: begin
+ mFreeMem(wstruct);
+ StrDup(wstruct,StrScan(pc,'|')+1);
+// AnsiToWide(StrScan(pc,'|')+1,wstruct,MirandaCP);
+ end;
+ end;
+ mFreeMem(pc);
+ end;
+
+ pc:=ApiCard.FillParams(GetDlgItem(Dialog,IDC_EDIT_LPAR),false);
+ if pc<>nil then
+ begin
+ if GetDlgItemTextA(Dialog,IDC_EDIT_LPAR,buf1,SizeOf(buf1))>0 then
+ case FixParam(@buf1,IDC_FLAG_LPAR) of
+ ptStruct: begin
+ mFreeMem(lstruct);
+ StrDup(lstruct,StrScan(pc,'|')+1);
+// AnsiToWide(StrScan(pc,'|')+1,lstruct,MirandaCP);
+ end;
+ end;
+ mFreeMem(pc);
+ end;
+
+ pc:=ApiCard.ResultType;
+ i:=sresInt;
+ if pc<>nil then
+ begin
+ if lstrcmpia(pc,'struct')=0 then i:=sresStruct
+ else if lstrcmpia(pc,'hex' )=0 then i:=sresHex
+ else if lstrcmpia(pc,'int')=0 then
+ begin
+ i:=sresInt;
+ ButtonOff(IDC_RES_SIGNED);
+ end
+ else if lstrcmpia(pc,'signed')=0 then
+ begin
+ i:=sresInt;
+ ButtonOn(IDC_RES_SIGNED);
+ end
+ else if lstrcmpia(pc,'str')=0 then
+ begin
+ i:=sresString;
+ ButtonOff(IDC_RES_UNICODE);
+ end
+ else if lstrcmpia(pc,'wide')=0 then
+ begin
+ i:=sresString;
+ ButtonOn(IDC_RES_UNICODE);
+ end;
+ mFreeMem(pc);
+ end;
+ CB_SelectData(Dialog,IDC_SRV_RESULT,i);
+
+// ApiCard.Show;
+ end;
+
+ procedure SelectActionType(group:dword);
+ var
+ i:integer;
+ begin
+ for i:=0 to ACT_MAXTYPE-1 do
+ if ActIds[i].code=group then break;
+ SendDlgItemMessage(Dialog,IDC_ACTION_TYPE,CB_SETCURSEL,i,0);
+ end;
+
+ procedure ClearControls(group:dword);
+ begin
+//! SelectActionType(group);
+ case group of
+ ACT_CONTACT: begin
+ EnableWindow(GetDlgItem(Dialog,IDC_CONTACTLIST),true);
+ SendDlgItemMessage(Dialog,IDC_CONTACTLIST,CB_SETCURSEL,0,0);
+ ButtonOff(IDC_CNT_KEEP);
+ ButtonOff(IDC_CNT_FILTER);
+ TextClear(IDC_EDIT_FORMAT);
+ end;
+ ACT_SERVICE: begin
+ TextClear(IDC_EDIT_SERVICE);
+ TextClear(IDC_EDIT_WPAR);
+ TextClear(IDC_EDIT_LPAR);
+ EnableWindow(GetDlgItem(Dialog,IDC_EDIT_WPAR),true);
+ EnableWindow(GetDlgItem(Dialog,IDC_EDIT_LPAR),true);
+// SendDlgItemMessage(Dialog,IDC_FLAG_WPAR,CB_SETCURSEL,0,0);
+// SendDlgItemMessage(Dialog,IDC_FLAG_LPAR,CB_SETCURSEL,0,0);
+ CB_SelectData(GetDlgItem(Dialog,IDC_FLAG_WPAR),ptNumber);
+ CB_SelectData(GetDlgItem(Dialog,IDC_FLAG_LPAR),ptNumber);
+
+ CB_SelectData(GetDlgItem(Dialog,IDC_SRV_RESULT),sresInt);
+
+ SendMessage(GetDlgItem(Dialog,IDC_EDIT_WPAR),CB_RESETCONTENT,0,0);
+ SendMessage(GetDlgItem(Dialog,IDC_EDIT_LPAR),CB_RESETCONTENT,0,0);
+
+ ButtonOff(IDC_RES_POPUP);
+ ButtonOff(IDC_RES_MESSAGE);
+ ButtonOff(IDC_RES_INSERT);
+
+ ButtonOff(IDC_RES_FREEMEM);
+ ButtonOff(IDC_RES_UNICODE);
+ ButtonOff(IDC_RES_SIGNED);
+
+ ButtonOff(IDC_SRV_WPAR);
+ ButtonOff(IDC_SRV_LPAR);
+ ButtonOff(IDC_SRV_SRVC);
+ end;
+ ACT_PROGRAM: begin
+ TextClear(IDC_EDIT_PROCTIME);
+ TextClear(IDC_EDIT_PRGPATH);
+ TextClear(IDC_EDIT_PRGARGS);
+
+ ButtonOff(IDC_FLAG_NORMAL);
+ ButtonOff(IDC_FLAG_HIDDEN);
+ ButtonOff(IDC_FLAG_MINIMIZE);
+ ButtonOff(IDC_FLAG_MAXIMIZE);
+
+ ButtonOff(IDC_FLAG_CURPATH);
+ ButtonOff(IDC_FLAG_CONTINUE);
+ ButtonOff(IDC_FLAG_PARALLEL);
+
+ ButtonOff(IDC_PRG_PRG);
+ ButtonOff(IDC_PRG_ARG);
+ end;
+ ACT_TEXT: begin
+ ButtonOff(IDC_FLAG_CLIP);
+ ButtonOff(IDC_FLAG_MESSAGE);
+ ButtonOff(IDC_CLIP_COPYTO);
+ ButtonOff(IDC_CLIP_PASTE);
+
+ ButtonOff(IDC_FLAG_FILE);
+ TextClear(IDC_FILE_PATH);
+ ButtonOff(IDC_FILE_READ);
+ ButtonOff(IDC_FILE_WRITE);
+ ButtonOff(IDC_FILE_APPEND);
+
+ EnableWindow(GetDlgItem(Dialog,IDC_EDIT_INSERT ),false);
+ EnableWindow(GetDlgItem(Dialog,IDC_CLIP_COPYTO ),false);
+ EnableWindow(GetDlgItem(Dialog,IDC_CLIP_PASTE ),false);
+
+ EnableWindow(GetDlgItem(Dialog,IDC_FILE_ENC ),false);
+ EnableWindow(GetDlgItem(Dialog,IDC_FILE_PATH ),false);
+ EnableWindow(GetDlgItem(Dialog,IDC_FILE_FILEBTN),false);
+ EnableWindow(GetDlgItem(Dialog,IDC_FILE_READ ),false);
+ EnableWindow(GetDlgItem(Dialog,IDC_FILE_WRITE ),false);
+ EnableWindow(GetDlgItem(Dialog,IDC_FILE_APPEND ),false);
+
+ TextClear(IDC_EDIT_INSERT);
+
+ ButtonOff(IDC_TXT_FILE);
+ ButtonOff(IDC_TXT_TEXT);
+ end;
+ ACT_ADVANCE: begin
+ ButtonOff(IDC_FLAG_GT);
+ ButtonOff(IDC_FLAG_LT);
+ ButtonOff(IDC_FLAG_EQ);
+ ButtonOff(IDC_FLAG_NOP);
+ ButtonOff(IDC_FLAG_NOT);
+ TextClear(IDC_ADV_VALUE);
+
+ ButtonOff(IDC_FLAG_BREAK);
+ ButtonOff(IDC_FLAG_JUMP);
+ ButtonOff(IDC_FLAG_ANOP);
+ EnableWindow(GetDlgItem(Dialog,IDC_ADV_VAL2),false);
+
+ ButtonOff(IDC_FLAG_MATH);
+ SendDlgItemMessage(Dialog,IDC_ADV_OPER,CB_SETCURSEL,0,0);
+ TextClear(IDC_ADV_VAL1);
+ ButtonOff(IDC_ADV_ASINT);
+
+ EnableWindow(GetDlgItem(Dialog,IDC_ADV_OPER),false);
+ EnableWindow(GetDlgItem(Dialog,IDC_ADV_VAL1),false);
+ EnableWindow(GetDlgItem(Dialog,IDC_ADV_VARS),false);
+
+ ButtonOff(IDC_FLAG_VARS);
+ TextClear(IDC_ADV_VARS);
+ end;
+ ACT_CHAIN: begin
+// FillChainList(Dialog);
+ SendDlgItemMessage(Dialog,IDC_GROUP_LIST,CB_SETCURSEL,0,0);
+ end;
+ ACT_RW: begin
+ ButtonOff(IDC_RW_READ);
+ ButtonOff(IDC_RW_WRITE);
+ ButtonOff(IDC_RW_DELETE);
+ SendDlgItemMessage(Dialog,IDC_CONTACTLIST,CB_SETCURSEL,0,0);
+ EnableWindow(GetDlgItem(Dialog,IDC_CONTACTLIST),true);
+ TextClear(IDC_CONTACTLIST);
+ TextClear(IDC_RW_MODULE);
+ TextClear(IDC_RW_SETTING);
+ TextClear(IDC_RW_VALUE);
+ TextClear(IDC_RW_TEXT);
+
+ ButtonOff(IDC_RW_CURRENT);
+ ButtonOff(IDC_RW_PARAM);
+ ButtonOff(IDC_RW_RESULT);
+ ButtonOff(IDC_RW_MANUAL);
+ ButtonOff(IDC_RW_LAST);
+
+ ButtonOff(IDC_RW_MVAR);
+ ButtonOff(IDC_RW_SVAR);
+ ButtonOff(IDC_RW_TVAR);
+ end;
+ ACT_MESSAGE: begin
+ TextClear(IDC_MSG_TITLE);
+ TextClear(IDC_MSG_TEXT);
+ ButtonOff(IDC_MSG_KEEP);
+ ButtonOff(IDC_MSGB_OK);
+ ButtonOff(IDC_MSGB_OC);
+ ButtonOff(IDC_MSGB_ARI);
+ ButtonOff(IDC_MSGB_YNC);
+ ButtonOff(IDC_MSGB_YN);
+ ButtonOff(IDC_MSGB_RC);
+ ButtonOff(IDC_MSGI_NONE);
+ ButtonOff(IDC_MSGI_ERROR);
+ ButtonOff(IDC_MSGI_QUEST);
+ ButtonOff(IDC_MSGI_WARN);
+ ButtonOff(IDC_MSGI_INFO);
+
+ ButtonOff(IDC_MSG_TTL);
+ ButtonOff(IDC_MSG_TXT);
+ end;
+ end;
+ end;
+
+ procedure ClearDialogData;
+ begin
+ ClearControls(ACT_CONTACT);
+ ClearControls(ACT_SERVICE);
+ ClearControls(ACT_PROGRAM);
+ ClearControls(ACT_TEXT);
+ ClearControls(ACT_ADVANCE);
+ ClearControls(ACT_CHAIN);
+ ClearControls(ACT_RW);
+ ClearControls(ACT_MESSAGE);
+ mFreeMem(wstruct);
+ mFreeMem(lstruct);
+ end;
+
+ procedure SHWindows(exclude:dword=0);
+ begin
+ SetupControls(ACT_CONTACT,SW_HIDE);
+ SetupControls(ACT_SERVICE,SW_HIDE);
+ SetupControls(ACT_PROGRAM,SW_HIDE);
+ SetupControls(ACT_TEXT ,SW_HIDE);
+ SetupControls(ACT_ADVANCE,SW_HIDE);
+ SetupControls(ACT_CHAIN ,SW_HIDE);
+ SetupControls(ACT_RW ,SW_HIDE);
+ SetupControls(ACT_MESSAGE,SW_HIDE);
+{
+ if exclude<>ACT_CONTACT then SetupControls(ACT_CONTACT,SW_HIDE);
+ if exclude<>ACT_SERVICE then SetupControls(ACT_SERVICE,SW_HIDE);
+ if exclude<>ACT_PROGRAM then SetupControls(ACT_PROGRAM,SW_HIDE);
+ if exclude<>ACT_TEXT then SetupControls(ACT_TEXT ,SW_HIDE);
+ if exclude<>ACT_ADVANCE then SetupControls(ACT_ADVANCE,SW_HIDE);
+ if exclude<>ACT_CHAIN then SetupControls(ACT_CHAIN ,SW_HIDE);
+ if exclude<>ACT_RW then SetupControls(ACT_RW ,SW_HIDE);
+}
+ case exclude of
+ ACT_CONTACT,
+ ACT_SERVICE,
+ ACT_PROGRAM,
+ ACT_TEXT ,
+ ACT_ADVANCE,
+ ACT_CHAIN ,
+ ACT_RW ,
+ ACT_MESSAGE: begin
+ SetupControls(exclude,SW_SHOW);
+ end;
+ end;
+ end;
+
+ procedure SHActButtons(mode:integer);
+ begin
+ ShowWindow(GetDlgItem(Dialog,IDC_STAT_ACTION),mode);
+ ShowWindow(GetDlgItem(Dialog,IDC_ACTION_TYPE),mode);
+ end;
+
+ procedure InitDef(exclude:dword=0);
+ begin
+ if exclude<>ACT_CONTACT then
+ begin
+ ButtonOn(IDC_CNT_FILTER);
+ // do nothing
+ end;
+ if exclude<>ACT_SERVICE then
+ begin
+ CB_SelectData(Dialog,IDC_SRV_RESULT,sresInt);
+ end;
+ if exclude<>ACT_PROGRAM then
+ begin
+ ButtonOn(IDC_FLAG_PARALLEL);
+ ButtonOn(IDC_FLAG_NORMAL);
+ SetDlgItemInt(Dialog,IDC_EDIT_PROCTIME,0,false);
+ end;
+ if exclude<>ACT_TEXT then
+ begin
+ ButtonOn(IDC_FLAG_CLIP);
+ EnableWindow(GetDlgItem(Dialog,IDC_CLIP_COPYTO),true);
+ EnableWindow(GetDlgItem(Dialog,IDC_CLIP_PASTE ),true);
+ ButtonOn(IDC_CLIP_COPYTO);
+
+ ButtonOn(IDC_FILE_READ);
+ // do nothing
+ end;
+ if exclude<>ACT_ADVANCE then
+ begin
+ ButtonOn(IDC_FLAG_NOP);
+ ButtonOn(IDC_FLAG_ANOP);
+ SetDlgItemInt(Dialog,IDC_ADV_VALUE,0,false);
+ SetDlgItemInt(Dialog,IDC_ADV_VAL1 ,0,false);
+ EnableWindow(GetDlgItem(Dialog,IDC_ADV_VAL1),false);
+ EnableWindow(GetDlgItem(Dialog,IDC_ADV_VAL2),false);
+ EnableWindow(GetDlgItem(Dialog,IDC_ADV_OPER),false);
+// SendDlgItemMessage(Dialog,IDC_ADV_OPER,CB_SETCURSEL,0,0);
+ CB_SelectData(Dialog,IDC_ADV_OPER,ORD(aeNot));
+ end;
+ if exclude<>ACT_CHAIN then
+ begin
+// FillChainList(Dialog);
+ SendDlgItemMessage(Dialog,IDC_GROUP_LIST,CB_SETCURSEL,0,0);
+ end;
+ if exclude<>ACT_RW then
+ begin
+ ButtonOn(IDC_RW_READ);
+ SetDlgItemInt(Dialog,IDC_RW_VALUE,0,false);
+ ButtonOn(IDC_RW_MANUAL);
+ EnableWindow(GetDlgItem(Dialog,IDC_RW_VALUE),true);
+ EnableWindow(GetDlgItem(Dialog,IDC_RW_TEXT ),true);
+ end;
+ if exclude<>ACT_MESSAGE then
+ begin
+ ButtonOn(IDC_MSGB_OK);
+ ButtonOn(IDC_MSGI_NONE);
+ end;
+ end;
+
+ // set buttons by options
+ procedure FillAction(CurAction:integer);
+ var
+ i:integer;
+ bb:boolean;
+ wnd:HWND;
+ begin
+ with NewActionList^[CurAction] do
+ begin
+ if (flags and ACF_ASSIGNED)=0 then
+ exit;
+ if actionType=0 then
+ actionType:=ACT_CONTACT;
+
+ InitDef(actionType);
+ SelectActionType(actionType);
+ case actionType of
+
+ ACT_CONTACT: begin
+ if (flags and ACF_KEEPONLY)<>0 then
+ ButtonOn(IDC_CNT_KEEP);
+ if fCLfilter then
+ ButtonOn(IDC_CNT_FILTER);
+ SetDlgItemTextW(Dialog,IDC_EDIT_FORMAT,fCLformat);
+
+ SendDlgItemMessage(Dialog,IDC_CONTACTLIST,CB_SETCURSEL,
+ FindContact(GetDlgItem(Dialog,IDC_CONTACTLIST),contact),0);
+ end;
+
+ ACT_SERVICE: begin
+ if SendDlgItemMessageA(Dialog,IDC_EDIT_SERVICE,CB_SELECTSTRING,twparam(-1),tlparam(service))<>CB_ERR then
+ ReloadService
+ else
+ SetDlgItemTextA(Dialog,IDC_EDIT_SERVICE,service);
+
+ if (flags2 and ACF2_SRV_WPAR)<>0 then ButtonOn(IDC_SRV_WPAR);
+ if (flags2 and ACF2_SRV_LPAR)<>0 then ButtonOn(IDC_SRV_LPAR);
+ if (flags2 and ACF2_SRV_SRVC)<>0 then ButtonOn(IDC_SRV_SRVC);
+
+ if (flags and ACF_MESSAGE)<>0 then ButtonOn(IDC_RES_MESSAGE);
+ if (flags and ACF_POPUP )<>0 then ButtonOn(IDC_RES_POPUP);
+ if (flags and ACF_INSERT )<>0 then ButtonOn(IDC_RES_INSERT);
+
+ if (flags and ACF_HEX)<>0 then
+ i:=sresHex
+ else if (flags and ACF_STRUCT)<>0 then
+ i:=sresStruct
+ else if (flags and ACF_STRING)<>0 then
+ begin
+ i:=sresString;
+ if (flags and ACF_UNICODE )<>0 then ButtonOn(IDC_RES_UNICODE);
+ if (flags2 and ACF2_FREEMEM)<>0 then ButtonOn(IDC_RES_FREEMEM);
+ end
+ else
+ begin
+ i:=sresInt;
+ if (flags and ACF_SIGNED)<>0 then
+ ButtonOn(IDC_RES_SIGNED);
+ end;
+ CB_SelectData(Dialog,IDC_SRV_RESULT,i);
+
+ if (flags and ACF_WPARAM)<>0 then
+ begin
+ EnableWindow(GetDlgItem(Dialog,IDC_EDIT_WPAR),false);
+ i:=ptParam;
+ end
+ else if (flags and ACF_WRESULT)<>0 then
+ begin
+ EnableWindow(GetDlgItem(Dialog,IDC_EDIT_WPAR),false);
+ i:=ptResult;
+ end
+ else if (flags and ACF_WPARNUM)<>0 then
+ begin
+ if (flags and ACF_WCURRENT)<>0 then
+ begin
+ EnableWindow(GetDlgItem(Dialog,IDC_EDIT_WPAR),false);
+ i:=ptCurrent
+ end
+ else
+ begin
+ i:=ptNumber;
+ SetNumValue(GetDlgItem(Dialog,IDC_EDIT_WPAR),wparam,
+ (flags2 and ACF2_SRV_WPAR)<>0,
+ (flags2 and ACF2_SRV_WHEX)<>0);
+// SetDlgItemInt(Dialog,IDC_EDIT_WPAR,wparam,true)
+ end;
+ end
+ else if (flags and ACF_WSTRUCT)<>0 then
+ begin
+ i:=ptStruct;
+ SHControl(IDC_EDIT_WPAR,SW_HIDE);
+ SHControl(IDC_WSTRUCT ,SW_SHOW);
+ mFreeMem(wstruct);
+ StrDup(wstruct,PAnsiChar(wparam));
+ end
+ else if (flags and ACF_WUNICODE)<>0 then
+ begin
+ i:=ptUnicode;
+ SetDlgItemTextW(Dialog,IDC_EDIT_WPAR,pWideChar(wparam));
+ end
+ else
+ begin
+ i:=ptString;
+ SetDlgItemTextA(Dialog,IDC_EDIT_WPAR,PAnsiChar(wparam));
+ end;
+ CB_SelectData(GetDlgItem(Dialog,IDC_FLAG_WPAR),i);
+ SendDlgItemMessage(Dialog,IDC_FLAG_WPAR,CB_SETCURSEL,i,0);
+
+ if (flags and ACF_LPARAM)<>0 then
+ begin
+ EnableWindow(GetDlgItem(Dialog,IDC_EDIT_LPAR),false);
+ i:=ptParam;
+ end
+ else if (flags and ACF_LRESULT)<>0 then
+ begin
+ EnableWindow(GetDlgItem(Dialog,IDC_EDIT_LPAR),false);
+ i:=ptResult;
+ end
+ else if (flags and ACF_LPARNUM)<>0 then
+ begin
+ if (flags and ACF_LCURRENT)<>0 then
+ begin
+ EnableWindow(GetDlgItem(Dialog,IDC_EDIT_LPAR),false);
+ i:=ptCurrent;
+ end
+ else
+ begin
+ i:=ptNumber;
+ SetNumValue(GetDlgItem(Dialog,IDC_EDIT_LPAR),lparam,
+ (flags2 and ACF2_SRV_LPAR)<>0,
+ (flags2 and ACF2_SRV_LHEX)<>0);
+// SetDlgItemInt(Dialog,IDC_EDIT_LPAR,lparam,true)
+ end;
+ end
+ else if (flags and ACF_LSTRUCT)<>0 then
+ begin
+ i:=ptStruct;
+ SHControl(IDC_EDIT_LPAR,SW_HIDE);
+ SHControl(IDC_LSTRUCT ,SW_SHOW);
+ mFreeMem(lstruct);
+ StrDup(lstruct,PAnsiChar(lparam));
+ end
+ else if (flags and ACF_LUNICODE)<>0 then
+ begin
+ i:=ptUnicode;
+ SetDlgItemTextW(Dialog,IDC_EDIT_LPAR,pWideChar(lparam));
+ end
+ else
+ begin
+ i:=ptString;
+ SetDlgItemTextA(Dialog,IDC_EDIT_LPAR,PAnsiChar(lparam));
+ end;
+ CB_SelectData(GetDlgItem(Dialog,IDC_FLAG_LPAR),i);
+
+ end;
+
+ ACT_PROGRAM: begin
+ if (flags2 and ACF2_PRG_PRG)<>0 then
+ ButtonOn(IDC_PRG_PRG);
+ if (flags2 and ACF2_PRG_ARG)<>0 then
+ ButtonOn(IDC_PRG_ARG);
+
+ SetDlgItemTextW(Dialog,IDC_EDIT_PRGPATH ,prgname);
+ SetDlgItemTextW(Dialog,IDC_EDIT_PRGARGS ,args);
+ SetDlgItemInt (Dialog,IDC_EDIT_PROCTIME,time,false);
+ case show of
+ SW_HIDE : ButtonOn(IDC_FLAG_HIDDEN);
+ SW_SHOWMINIMIZED: ButtonOn(IDC_FLAG_MINIMIZE);
+ SW_SHOWMAXIMIZED: ButtonOn(IDC_FLAG_MAXIMIZE);
+ else
+ {SW_SHOWNORMAL :} ButtonOn(IDC_FLAG_NORMAL);
+ end;
+ if (flags and ACF_CURPATH)<>0 then
+ ButtonOn(IDC_FLAG_CURPATH);
+ if (flags and ACF_PRTHREAD)<>0 then
+ ButtonOn(IDC_FLAG_PARALLEL)
+ else
+ ButtonOn(IDC_FLAG_CONTINUE);
+
+ end;
+
+ ACT_TEXT: begin
+ if (flags and ACF_CLIPBRD)<>0 then
+ begin
+ ButtonOn(IDC_FLAG_CLIP);
+ EnableWindow(GetDlgItem(Dialog,IDC_CLIP_COPYTO),true);
+ EnableWindow(GetDlgItem(Dialog,IDC_CLIP_PASTE ),true);
+ if (flags and ACF_COPYTO)<>0 then
+ ButtonOn(IDC_CLIP_COPYTO)
+ else
+ ButtonOn(IDC_CLIP_PASTE);
+// for switches
+ ButtonOn(IDC_FILE_READ);
+ end
+
+ else
+ begin
+ if (flags and (ACF_FILE or ACF_FAPPEND or ACF_FWRITE))<>ACF_FILE then
+ EnableWindow(GetDlgItem(Dialog,IDC_EDIT_INSERT),true);
+ SetDlgItemTextW(Dialog,IDC_EDIT_INSERT,text);
+// for switches
+ ButtonOn(IDC_CLIP_COPYTO);
+
+ if (flags2 and ACF2_TXT_TEXT)<>0 then
+ ButtonOn(IDC_TXT_TEXT);
+
+ if (flags and ACF_FILE)<>0 then
+ begin
+ if (flags2 and ACF2_TXT_FILE)<>0 then
+ ButtonOn(IDC_TXT_FILE);
+ ButtonOn(IDC_FLAG_FILE);
+ EnableWindow(GetDlgItem(Dialog,IDC_FILE_PATH ),true);
+ EnableWindow(GetDlgItem(Dialog,IDC_FILE_FILEBTN),true);
+ EnableWindow(GetDlgItem(Dialog,IDC_FILE_READ ),true);
+ EnableWindow(GetDlgItem(Dialog,IDC_FILE_WRITE ),true);
+ EnableWindow(GetDlgItem(Dialog,IDC_FILE_APPEND ),true);
+
+ wnd:=GetDlgItem(Dialog,IDC_FILE_ENC);
+ EnableWindow(wnd,true);
+ if (flags and ACF_ANSI)<>0 then
+ CB_SelectData(wnd,0)
+ else if (flags and ACF_UTF8)<>0 then
+ begin
+ if (flags and ACF_SIGN)<>0 then
+ CB_SelectData(wnd,2)
+ else
+ CB_SelectData(wnd,1);
+ end
+ else if (flags and ACF_SIGN)<>0 then
+ CB_SelectData(wnd,4)
+ else
+ CB_SelectData(wnd,3);
+
+ if (flags and ACF_FAPPEND)<>0 then ButtonOn(IDC_FILE_APPEND)
+ else if (flags and ACF_FWRITE )<>0 then ButtonOn(IDC_FILE_WRITE)
+ else ButtonOn(IDC_FILE_READ);
+ SetDlgItemTextW(Dialog,IDC_FILE_PATH,tfile);
+ end
+ else
+ begin
+ ButtonOn(IDC_FLAG_MESSAGE);
+// for switches
+ ButtonOn(IDC_FILE_READ);
+ end;
+ end;
+
+ end;
+
+ ACT_ADVANCE: begin
+ FillSubList(Dialog);
+// SendDlgItemMessage(Dialog,IDC_ADV_VAL2,CB_SETCURSEL,0,0);
+
+ case condition and not ADV_COND_NOT of
+ ADV_COND_GT: ButtonOn(IDC_FLAG_GT);
+ ADV_COND_LT: ButtonOn(IDC_FLAG_LT);
+ ADV_COND_EQ: ButtonOn(IDC_FLAG_EQ);
+ else // ADV_COND_NOP
+ ButtonOn(IDC_FLAG_NOP);
+ end;
+ SetDlgItemInt(Dialog,IDC_ADV_VALUE,value,false);
+ if (condition and ADV_COND_NOT)<>0 then
+ ButtonOn(IDC_FLAG_NOT);
+
+ SetDlgItemInt(Dialog,IDC_ADV_VAL1,mathval,true);
+ case action and ADV_ACTION of
+ ADV_ACT_MATH: begin
+ ButtonOn(IDC_FLAG_MATH);
+ CB_SelectData(GetDlgItem(Dialog,IDC_ADV_OPER),oper);
+// SendDlgItemMessage(Dialog,IDC_ADV_OPER,CB_SETCURSEL,oper,0);
+ EnableWindow(GetDlgItem(Dialog,IDC_ADV_VAL1),true);
+ EnableWindow(GetDlgItem(Dialog,IDC_ADV_OPER),true);
+ end;
+ ADV_ACT_VARS: begin
+ ButtonOn(IDC_FLAG_VARS);
+ if (flags and ACF_VARASINT)<>0 then
+ ButtonOn(IDC_ADV_ASINT);
+ EnableWindow(GetDlgItem(Dialog,IDC_ADV_VARS),true);
+ SetDlgItemTextW(Dialog,IDC_ADV_VARS,varval);
+ end;
+ end;
+ bb:=false;
+ case action and ADV_ACT_POST of
+ ADV_ACT_BREAK: ButtonOn(IDC_FLAG_BREAK);
+ ADV_ACT_JUMP : begin
+ SendDlgItemMessageW(Dialog,IDC_ADV_VAL2,CB_SELECTSTRING,twparam(-1),tlparam(operval));
+ ButtonOn(IDC_FLAG_JUMP);
+ bb:=true;
+ end;
+ else // ADV_ACT_NOP
+ ButtonOn(IDC_FLAG_ANOP);
+ end;
+ EnableWindow(GetDlgItem(Dialog,IDC_ADV_VAL2),bb);
+ end;
+
+ ACT_CHAIN: begin
+// FillChainList(Dialog);
+ if (flags and ACF_BYNAME)<>0 then
+ SendDlgItemMessageW(Dialog,IDC_GROUP_LIST,CB_SELECTSTRING,twparam(-1),tlparam(actname))
+ else
+ SendDlgItemMessageW(Dialog,IDC_GROUP_LIST,CB_SELECTSTRING,twparam(-1),tlparam(GetGroupName(id)));
+ end;
+
+ ACT_RW: begin
+ if (flags and ACF_DBDELETE)<>0 then ButtonOn(IDC_RW_DELETE)
+ else if (flags and ACF_DBWRITE )= 0 then ButtonOn(IDC_RW_READ)
+ else ButtonOn(IDC_RW_WRITE);
+
+ bb:=false;
+ if (flags and ACF_CURRENT)<>0 then
+ begin
+ ButtonOn(IDC_RW_CURRENT);
+ EnableWindow(GetDlgItem(Dialog,IDC_CONTACTLIST),false);
+ end
+ else if (flags and ACF_PARAM)<>0 then
+ begin
+ ButtonOn(IDC_RW_PARAM);
+ EnableWindow(GetDlgItem(Dialog,IDC_CONTACTLIST),false);
+ end
+ else if (flags and ACF_RESULT)<>0 then
+ begin
+ ButtonOn(IDC_RW_RESULT);
+ EnableWindow(GetDlgItem(Dialog,IDC_CONTACTLIST),false);
+ end
+ else
+ begin
+ ButtonOn(IDC_RW_MANUAL);
+ bb:=true;
+ EnableWindow(GetDlgItem(Dialog,IDC_CONTACTLIST),true);
+ SendDlgItemMessage(Dialog,IDC_CONTACTLIST,CB_SETCURSEL,
+ FindContact(GetDlgItem(Dialog,IDC_CONTACTLIST),dbcontact),0);
+ end;
+ EnableWindow(GetDlgItem(Dialog,IDC_CONTACTLIST),bb);
+
+ if (flags and ACF_LAST)<>0 then
+ begin
+ ButtonOn(IDC_RW_LAST);
+ bb:=false;
+ end
+ else
+ bb:=true;
+ if (flags and ACF_DBDELETE)<>0 then
+ bb:=false;
+
+ EnableWindow(GetDlgItem(Dialog,IDC_RW_VALUE),bb);
+ EnableWindow(GetDlgItem(Dialog,IDC_RW_TEXT ),bb);
+
+ SetDlgItemTextA(Dialog,IDC_RW_MODULE ,dbmodule);
+ SetDlgItemTextA(Dialog,IDC_RW_SETTING,dbsetting);
+ if (flags2 and ACF2_RW_MVAR)<>0 then ButtonOn(IDC_RW_MVAR);
+ if (flags2 and ACF2_RW_SVAR)<>0 then ButtonOn(IDC_RW_SVAR);
+ if (flags2 and ACF2_RW_TVAR)<>0 then ButtonOn(IDC_RW_TVAR);
+
+
+ wnd:=GetDlgItem(Dialog,IDC_RW_DATATYPE);
+ if ((flags and ACF_DBANSI )=ACF_DBANSI) or
+ ((flags and ACF_DBUTEXT)=ACF_DBUTEXT) then
+ begin
+ SHControl(IDC_RW_TEXT ,SW_SHOW);
+ SHControl(IDC_RW_VALUE,SW_HIDE);
+ if (flags and ACF_DBANSI)=ACF_DBANSI then
+ CB_SelectData(wnd,3)
+ else
+ CB_SelectData(wnd,4);
+ SetDlgItemTextW(Dialog,IDC_RW_TEXT,pWideChar(dbvalue));
+ end
+ else
+ begin
+ if (flags and ACF_DBBYTE)=ACF_DBBYTE then
+ CB_SelectData(wnd,0)
+ else if (flags and ACF_DBWORD)=ACF_DBWORD then
+ CB_SelectData(wnd,1)
+ else
+ CB_SelectData(wnd,2);
+ SHControl(IDC_RW_TEXT ,SW_HIDE);
+ SHControl(IDC_RW_VALUE,SW_SHOW);
+
+ SetNumValue(GetDlgItem(Dialog,IDC_RW_VALUE),dbvalue,
+ (flags2 and ACF2_RW_TVAR)<>0,
+ (flags2 and ACF2_RW_HEX )<>0);
+ end;
+
+ end;
+
+ ACT_MESSAGE: begin
+ SetDlgItemTextW(Dialog,IDC_MSG_TITLE,msgtitle);
+ SetDlgItemTextW(Dialog,IDC_MSG_TEXT ,msgtext);
+ if (flags2 and ACF2_MSG_TTL)<>0 then ButtonOn(IDC_MSG_TTL);
+ if (flags2 and ACF2_MSG_TXT)<>0 then ButtonOn(IDC_MSG_TXT);
+ if (flags and ACF_MSG_KEEP)<>0 then ButtonOn(IDC_MSG_KEEP);
+
+ case boxopts and $0F of
+ 1: ButtonOn(IDC_MSGB_OC);
+ 2: ButtonOn(IDC_MSGB_ARI);
+ 3: ButtonOn(IDC_MSGB_YNC);
+ 4: ButtonOn(IDC_MSGB_YN);
+ 5: ButtonOn(IDC_MSGB_RC);
+ else
+ ButtonOn(IDC_MSGB_OK);
+ end;
+ case boxopts and $F0 of
+ $10: ButtonOn(IDC_MSGI_ERROR);
+ $20: ButtonOn(IDC_MSGI_QUEST);
+ $30: ButtonOn(IDC_MSGI_WARN);
+ $40: ButtonOn(IDC_MSGI_INFO);
+ else
+ ButtonOn(IDC_MSGI_NONE);
+ end;
+ end;
+ end;
+ SHWindows(actionType);
+ end;
+ end;
diff --git a/plugins/Actman/ico/advance.ico b/plugins/Actman/ico/advance.ico
new file mode 100644
index 0000000000..fa6c604542
--- /dev/null
+++ b/plugins/Actman/ico/advance.ico
Binary files differ
diff --git a/plugins/Actman/ico/apply.ico b/plugins/Actman/ico/apply.ico
new file mode 100644
index 0000000000..80c3802c09
--- /dev/null
+++ b/plugins/Actman/ico/apply.ico
Binary files differ
diff --git a/plugins/Actman/ico/chain.ico b/plugins/Actman/ico/chain.ico
new file mode 100644
index 0000000000..3a98b8ac30
--- /dev/null
+++ b/plugins/Actman/ico/chain.ico
Binary files differ
diff --git a/plugins/Actman/ico/contact.ico b/plugins/Actman/ico/contact.ico
new file mode 100644
index 0000000000..8174fa221a
--- /dev/null
+++ b/plugins/Actman/ico/contact.ico
Binary files differ
diff --git a/plugins/Actman/ico/delete.ico b/plugins/Actman/ico/delete.ico
new file mode 100644
index 0000000000..eea851da19
--- /dev/null
+++ b/plugins/Actman/ico/delete.ico
Binary files differ
diff --git a/plugins/Actman/ico/down.ico b/plugins/Actman/ico/down.ico
new file mode 100644
index 0000000000..d4fdb83bbf
--- /dev/null
+++ b/plugins/Actman/ico/down.ico
Binary files differ
diff --git a/plugins/Actman/ico/export.ico b/plugins/Actman/ico/export.ico
new file mode 100644
index 0000000000..ddddb59074
--- /dev/null
+++ b/plugins/Actman/ico/export.ico
Binary files differ
diff --git a/plugins/Actman/ico/format.ico b/plugins/Actman/ico/format.ico
new file mode 100644
index 0000000000..ddddb59074
--- /dev/null
+++ b/plugins/Actman/ico/format.ico
Binary files differ
diff --git a/plugins/Actman/ico/import.ico b/plugins/Actman/ico/import.ico
new file mode 100644
index 0000000000..481da4dbaf
--- /dev/null
+++ b/plugins/Actman/ico/import.ico
Binary files differ
diff --git a/plugins/Actman/ico/insert.ico b/plugins/Actman/ico/insert.ico
new file mode 100644
index 0000000000..481da4dbaf
--- /dev/null
+++ b/plugins/Actman/ico/insert.ico
Binary files differ
diff --git a/plugins/Actman/ico/message.ico b/plugins/Actman/ico/message.ico
new file mode 100644
index 0000000000..fa6c604542
--- /dev/null
+++ b/plugins/Actman/ico/message.ico
Binary files differ
diff --git a/plugins/Actman/ico/new.ico b/plugins/Actman/ico/new.ico
new file mode 100644
index 0000000000..73937210e0
--- /dev/null
+++ b/plugins/Actman/ico/new.ico
Binary files differ
diff --git a/plugins/Actman/ico/program.ico b/plugins/Actman/ico/program.ico
new file mode 100644
index 0000000000..30c7df1875
--- /dev/null
+++ b/plugins/Actman/ico/program.ico
Binary files differ
diff --git a/plugins/Actman/ico/reload.ico b/plugins/Actman/ico/reload.ico
new file mode 100644
index 0000000000..dc070c5083
--- /dev/null
+++ b/plugins/Actman/ico/reload.ico
Binary files differ
diff --git a/plugins/Actman/ico/rw.ico b/plugins/Actman/ico/rw.ico
new file mode 100644
index 0000000000..d5927ebb08
--- /dev/null
+++ b/plugins/Actman/ico/rw.ico
Binary files differ
diff --git a/plugins/Actman/ico/service.ico b/plugins/Actman/ico/service.ico
new file mode 100644
index 0000000000..ddddb59074
--- /dev/null
+++ b/plugins/Actman/ico/service.ico
Binary files differ
diff --git a/plugins/Actman/ico/test.ico b/plugins/Actman/ico/test.ico
new file mode 100644
index 0000000000..345530ba76
--- /dev/null
+++ b/plugins/Actman/ico/test.ico
Binary files differ
diff --git a/plugins/Actman/ico/up.ico b/plugins/Actman/ico/up.ico
new file mode 100644
index 0000000000..56fde31eda
--- /dev/null
+++ b/plugins/Actman/ico/up.ico
Binary files differ
diff --git a/plugins/Actman/ico/vcheck.ico b/plugins/Actman/ico/vcheck.ico
new file mode 100644
index 0000000000..3f4afbbb01
--- /dev/null
+++ b/plugins/Actman/ico/vcheck.ico
Binary files differ
diff --git a/plugins/Actman/ico/vuncheck.ico b/plugins/Actman/ico/vuncheck.ico
new file mode 100644
index 0000000000..9587919f5b
--- /dev/null
+++ b/plugins/Actman/ico/vuncheck.ico
Binary files differ
diff --git a/plugins/Actman/m_actions.inc b/plugins/Actman/m_actions.inc
new file mode 100644
index 0000000000..7600d0dcdf
--- /dev/null
+++ b/plugins/Actman/m_actions.inc
@@ -0,0 +1,193 @@
+// defined in interfaces.inc
+//const MIID_ACTMANAGER:MUUID='{9584DA04-FB4F-40c1-9325-E4F9CAAFCB5D}';
+
+// hotkey and action (common) flags
+const
+ ACF_DISABLED = $10000000; // action disabled
+ ACF_USEDNOW = $20000000; // action in use (reserved)
+ ACF_DOBREAK = $40000000; // special, make break;
+ ACF_ASSIGNED = $80000000; // action assigned
+ ACF_EXPORT = $08000000; // action to export
+ ACF_IMPORT = ACF_EXPORT; // imported
+ ACF_VOLATILE = $04000000; // don't save in DB
+ ACF_PARALLEL = $02000000; // parallel action work (no wait thread)
+ ACF_OVERLOAD = $01000000; // imported action overwrite old
+
+// action flags
+const
+ // ACT_CONTACT
+ ACF_KEEPONLY = $00000001; // keep contact handle in Last, don't show window
+
+ // ACT_SERVICE
+ ACF_WPARNUM = $00000001; // wParam is number
+ ACF_LPARNUM = $00000002; // lParam is number
+ ACF_WUNICODE = $00000004; // wParam is Unicode string
+ ACF_LUNICODE = $00000008; // lParam is Unicode string
+ ACF_WCURRENT = $00000010; // wParam is ignored, used current user handle
+ // from current message window
+ ACF_LCURRENT = $00000020; // lParam is ignored, used current user handle
+ // from current message window
+ ACF_WPARHEX = $00000040; //!! Show as hex
+ ACF_LPARHEX = $00000080; //!! Show as hex
+
+ ACF_WRESULT = $00010000; // wParam is previous action result
+ ACF_LRESULT = $00020000; // lParam is previous action result
+ ACF_WPARAM = $00040000; // wParam is Call parameter
+ ACF_LPARAM = $00080000; // lParam is Call parameter
+ ACF_WSTRUCT = $00100000;
+ ACF_LSTRUCT = $00200000;
+ ACF_WPARTYPE = ACF_WPARNUM or ACF_WUNICODE or ACF_WCURRENT or ACF_WPARAM or ACF_WSTRUCT;
+ ACF_LPARTYPE = ACF_LPARNUM or ACF_LUNICODE or ACF_LCURRENT or ACF_LPARAM or ACF_LSTRUCT;
+
+ ACF_INSERT = $00000100; // Insert result in message
+ ACF_MESSAGE = $00000200; // Show service result as message
+ ACF_POPUP = $00000400; // Show service result as popup
+ ACF_STRING = $00000800; // Service result is string
+ ACF_UNICODE = $00001000; // Service result is Widestring
+ ACF_HEX = $00002000; // Result as Hex
+ ACF_SIGNED = $00004000; // Result as signed value
+//!!
+ ACF_STRUCT = $00008000; // Service result in structure
+
+ // ACT_TEXT
+ ACF_CLIPBRD = $00000002; // Clipboard operations, not window
+ ACF_ANSI = $00000004; // File: ANSI or Unicode (UTF8/UTF16) text
+ ACF_COPYTO = $00000008; // Clipboard operations: 'copy to' or 'paste from'
+
+ ACF_FILE = $00000010; // File operations
+ ACF_FWRITE = $00000020; // read/write file
+ ACF_FAPPEND = $00000040; // append file
+
+ ACF_UTF8 = $00000080; // File: UTF8 or UTF16
+ ACF_SIGN = $00000100; // File: with signature or not
+
+ // ACT_PROGRAM
+ ACF_CURPATH = $00000002; // Current (not program) path
+ ACF_PRTHREAD = $00000004; // parallel Program
+
+ // ACT_ADVANCED
+ ACF_VARASINT = $00000001; // if variables script, translate to int
+
+ // ACT_DBRW
+ ACF_DBWRITE = $00000001; // write to (not read from) DB
+ ACF_DBBYTE = $00000002; // read/write byte (def. dword)
+ ACF_DBWORD = $00000004; // read/write word (def. dword)
+ ACF_PARAM = $00000008; // hContact from parameter
+ ACF_CURRENT = $00000010; // hContact is 0 (user settings)
+ ACF_RESULT = $00000020; // hContact is last result value
+ ACF_LAST = $00000040; // use last result for DB writing
+ ACF_DBUTEXT = $00000080; // read/write Unicode string
+ ACF_DBANSI = $00000082; // read/write ANSI string
+ ACF_DBDELETE = $00000100; // delete setting
+ ACF_NOCNTCT = ACF_PARAM or ACF_CURRENT or ACF_RESULT;
+
+ // ACT_CHAIN
+ ACF_BYNAME = $00000001; // Address action link by name, not Id
+
+ // ACT_MESSAGE
+ ACF_MSG_KEEP = $00000001; // Keep past 'last result'
+
+const
+ // Variables use
+ ACF2_SRV_WPAR = $00000001;
+ ACF2_SRV_LPAR = $00000002;
+ ACF2_SRV_SRVC = $00000004;
+ ACF2_SRV_WHEX = $00000008;
+ ACF2_SRV_LHEX = $00000010;
+ ACF2_PRG_PRG = $00000001;
+ ACF2_PRG_ARG = $00000002;
+ ACF2_TXT_FILE = $00000001;
+ ACF2_TXT_TEXT = $00000002;
+ ACF2_RW_MVAR = $00000001;
+ ACF2_RW_SVAR = $00000002;
+ ACF2_RW_TVAR = $00000004;
+ ACF2_RW_HEX = $00000008;
+ ACF2_MSG_TTL = $00000001;
+ ACF2_MSG_TXT = $00000002;
+
+ ACF2_FREEMEM = $00000100;
+
+const
+ ADV_COND_NOP = 0;
+ ADV_COND_GT = 1;
+ ADV_COND_LT = 2;
+ ADV_COND_EQ = 3;
+ ADV_COND_NOT = $80;
+
+ ADV_ACT_NOP = 0; // two lower bits $03 mask
+ ADV_ACT_BREAK = 1;
+ ADV_ACT_JUMP = 2;
+
+ ADV_ACT_POST = $0F;
+
+ ADV_ACT_MATH = $10; // bit masks
+ ADV_ACT_VARS = $20;
+
+ ADV_ACTION = $F0;
+
+const
+ ACT_UNKNOWN = 0;
+ ACT_CONTACT = 1;
+ ACT_SERVICE = 2;
+ ACT_PROGRAM = 3;
+ ACT_TEXT = 4;
+ ACT_ADVANCE = 5;
+ ACT_CHAIN = 6;
+ ACT_RW = 7;
+ ACT_MESSAGE = 8;
+ ACT_MAXTYPE = 8;
+ ACT_SPECIAL = ACT_MAXTYPE+1;
+ ACT_FINISH = ACT_SPECIAL+1;
+
+type
+ pHKRecord = ^tHKRecord;
+ tHKRecord = record
+ descr :pWideChar; // like name
+ id :dword;
+ flags :dword; // Assigned or not
+ firstAction:dword; // array [0..0] of dword
+ active :pointer;
+ end;
+
+ pHKAction = ^tHKAction;
+ tHKAction = record
+ flags :dword; // See ACF_* constants
+ flags2:dword; // See ACF2_* constants (Variables use etc.)
+ next :dword;
+ descr :PWideChar;
+ case actionType:dword of
+ ACT_CONTACT:
+ (contact:THANDLE);
+ ACT_SERVICE:
+ (service:PAnsiChar;
+ wparam :WPARAM;
+ lparam :LPARAM);
+ ACT_PROGRAM:
+ (prgname:pWideChar;
+ args :pWideChar;
+ show :dword;
+ time :dword);
+ ACT_TEXT:
+ (text :pWideChar;
+ tfile :pWideChar);
+ ACT_ADVANCE:
+ (condition:dword;
+ value :uint_ptr;
+ action :dword;
+ operval :pWideChar;
+ oper :dword;
+ mathval :dword;
+ varval :pWideChar);
+ ACT_CHAIN:
+ (id :dword;
+ actname:pWideChar);
+ ACT_RW:
+ (dbcontact:THANDLE;
+ dbmodule :PAnsiChar;
+ dbsetting :PAnsiChar;
+ dbvalue :uint_ptr);
+ ACT_MESSAGE:
+ (boxopts:dword;
+ msgtitle:pWideChar;
+ msgtext :pWideChar);
+ end;
diff --git a/plugins/Actman/m_actman.h b/plugins/Actman/m_actman.h
new file mode 100644
index 0000000000..c900ba9c6c
--- /dev/null
+++ b/plugins/Actman/m_actman.h
@@ -0,0 +1,96 @@
+#ifndef M_ACTMAN
+#define M_ACTMAN
+
+#define ACCF_DISABLED 0x10000000 // action disabled
+#define ACCF_EXPORT 0x08000000 // action to export
+#define ACCF_VOLATILE 0x04000000 // don't save in DB
+#define ACCF_IMPORTED ACF_EXPORT
+#define ACCF_FLAGS (ACCF_DISABLED | ACCF_EXPORT | ACCF_IMPORTED | ACCF_VOLATILE)
+#define ACCF_ID 0x02000000 // for MS_ACT_SELECT, lParam is ID (else name)
+#define ACCF_CLEAR 0x01000000 // clear other flags, else - set
+
+
+typedef struct{
+ WCHAR* Descr;
+ DWORD ID;
+ DWORD flags; // ACCF_* flags
+ } TChain, *PChain;
+
+// Service to get list of all configured actions;
+// wParam : 0
+// lParam : address of destination list variable (address of pointer to TChain)
+// Notes: first 4 bytes of list = size of TChain structure (to add new fields in future)
+// Return value: count of elements;
+#define MS_ACT_GETLIST "Actions/GetList"
+
+// Service to free list of all configured actions got with MS_ACT_GETLIST service call;
+// wParam : 0
+// lParam : list address (pointer to ACTION returned by MS_ACT_GETLIST)
+#define MS_ACT_FREELIST "Actions/FreeList"
+
+// Service to call action defined in wParam;
+// wParam: ID of an action (see ACTION.ActID) when calling MS_ACT_RUN
+// or description of an action (see ACTION.ActDescr) when calling MS_ACT_RUNGROUP
+// lParam: parameter (will be passed to action called)
+#define MS_ACT_RUNBYID "Actions/RunById"
+#define MS_ACT_RUNBYNAME "Actions/RunByName"
+
+// Event: action group list was changed: something was added or deleted
+// wParam: set of ACTM_* flags
+// lParam : 0
+#define ME_ACT_CHANGED "Actions/Changed"
+
+// Starts action with 2 parameters
+// wParam: 0
+// lParam: pointer to TAct_Param
+
+#define MS_ACT_RUNPARAMS "Actions/RunWithParams"
+typedef struct TAct_Param
+ {
+ DWORD flags; // 0 - ID, 1 - Name
+ DWORD ID; // Id or name
+ WPARAM wParam;
+ LPARAM lParam;
+ } TAct_Param, *PAct_Param;
+
+#define ACTM_NEW 0x00000001
+#define ACTM_DELETE 0x00000002
+#define ACTM_RELOAD 0x00000004
+#define ACTM_RENAME 0x00000008
+#define ACTM_SORT 0x00000010
+#define ACTM_ACT 0x10000000 // do not check, internal
+#define ACTM_ACTS 0x20000000 // do not check, internal
+#define ACTM_LOADED 0x80000000
+
+
+#define ACIO_EXPORT 0x00000001 // export, else - import
+#define ACIO_APPEND 0x00000002 // append file on export
+#define ACIO_ASKEXIST 0x00000004 // ask, if action exists on import
+#define ACIO_SELECTED 0x00000008 // export selected actions only
+
+// wParam: ACIO_* flags
+// lParam: Unicode file name
+// Return - true, if totally succesful
+#define MS_ACT_INOUT "Actions/ImpExp"
+
+
+//Event: Export actions
+// wParam - ACIO_* flags
+// lParam - unicode filename
+#define ME_ACT_INOUT "Actions/InOut"
+
+
+// Select/unselect specified action
+// wParam: set of ACCF_* consts
+// lParam: unicode action name / number
+// Return - -1 if unsuccesful
+#define MS_ACT_SELECT "Actions/Select"
+
+
+// Event: Action started/finished
+// wParam - Action status: 0 - started, 1 - finished
+// lParam - action id
+
+#define ME_ACT_ACTION "Actions/Action"
+
+#endif
diff --git a/plugins/Actman/m_actman.inc b/plugins/Actman/m_actman.inc
new file mode 100644
index 0000000000..53344e2990
--- /dev/null
+++ b/plugins/Actman/m_actman.inc
@@ -0,0 +1,158 @@
+{$IFNDEF M_ACTMAN}
+{$DEFINE M_ACTMAN}
+
+// defined in interfaces.inc
+//const MIID_ACTMANAGER:MUUID='{9584DA04-FB4F-40c1-9325-E4F9CAAFCB5D}';
+
+const
+ AutoStartName:PWideChar = '#Autostart';
+const
+ DBBranch = 'ActMan';
+const
+ ACCF_DISABLED = $10000000; // action disabled
+ ACCF_EXPORT = $08000000; // action to export
+ ACCF_VOLATILE = $04000000; // don't save in DB
+ ACCF_IMPORTED = ACCF_EXPORT;
+ ACCF_FLAGS = ACCF_DISABLED or ACCF_EXPORT or ACCF_IMPORTED or ACCF_VOLATILE;
+ ACCF_OVERLOAD = $01000000; // imported action overwrite old
+
+ ACCF_ID = $02000000; // for MS_ACT_SELECT, lParam is ID (else name)
+ ACCF_CLEAR = $01000000; // clear other flags, else - set
+type
+ pChain = ^tChain;
+ tChain = record
+ descr:pWideChar;
+ id :dword;
+ flags:dword; // ACCF_* flags
+ order:dword;
+ end;
+
+const
+ {
+ wParam - 0
+ lParam - address of destination list variable (address of pointer to tChain)
+ if lParam=0, return just count of elements
+ Return - count of elements
+ Notes: first 4 bytes = size of TChain structure (to add new fields in future)
+ }
+ MS_ACT_GETLIST:PAnsiChar = 'Actions/GetList';
+ {
+ wParam - 0
+ lParam - list address (pointer to data returned by MS_ACT_GETLIST)
+ }
+ MS_ACT_FREELIST:PAnsiChar = 'Actions/FreeList';
+ {
+ wParam - id: dword
+ lParam - parameter
+ }
+ MS_ACT_RUNBYID :PAnsiChar = 'Actions/RunById';
+ {
+ wParam - unicode action name
+ lParam - parameter
+ }
+ MS_ACT_RUNBYNAME:PAnsiChar = 'Actions/RunByName';
+
+{ Starts action with 2 parameters
+ wParam: 0
+ lParam: pointer to TAct_Param
+}
+ MS_ACT_RUNPARAMS:PAnsiChar = 'Actions/RunWithParams';
+const
+ ACTP_BYNAME = 1;
+ ACTP_WAIT = 2;
+type
+ pAct_Param = ^tAct_Param;
+ tAct_Param = record
+ flags :dword; // ACTP_*
+ Id :uint_ptr; // Id or name
+ wParam:WPARAM;
+ lParam:LPARAM;
+ end;
+
+const
+ ACTM_NEW = $00000001;
+ ACTM_DELETE = $00000002;
+ ACTM_RELOAD = $00000004;
+ ACTM_RENAME = $00000008;
+ ACTM_SORT = $00000010;
+ ACTM_ACT = $10000000; // do not check, internal
+ ACTM_ACTS = $20000000; // do not check, internal
+ ACTM_LOADED = $80000000;
+
+ {
+ Event: action group list was changed: some was added or deleted
+ wParam - set of ACTM_* flags
+ lParam - 0
+ }
+ ME_ACT_CHANGED:PAnsiChar = 'Actions/Changed';
+
+ ACIO_EXPORT = $00000001; // export, else - import
+ ACIO_APPEND = $00000002; // append file on export
+ ACIO_ASKEXIST = $00000004; // ask, if action exists on import
+ ACIO_SELECTED = $00000008; // export selected actions only
+
+ {
+ wParam - ACIO_* flags
+ lParam - Unicode file name
+ Return - true, if totally succesful
+ }
+ MS_ACT_INOUT:PAnsiChar = 'Actions/ImpExp';
+
+ {
+ Event: Export actions
+ wParam - ACIO_* flags
+ lParam - unicode filename
+ }
+ ME_ACT_INOUT:PAnsiChar = 'Actions/InOut';
+
+ {
+ Select/unselect specified action
+ wParam - set of ACCF_* consts
+ lParam - unicode action name / number
+ Return - -1 if unsuccesful
+ }
+ MS_ACT_SELECT:PAnsiChar = 'Actions/Select';
+
+ {
+ Event: Action started/finished
+ wParam - Action status: 0 - started, 1 - finished
+ lParam - action id
+ }
+ ME_ACT_ACTION:PAnsiChar = 'Actions/Action';
+
+//----- Scheduling part services -----
+
+const
+ {
+ Enable or disable tasks
+ wParam - 1/0 (enable/disable)
+ lParam - unicode task name
+ Note - works for all tasks with same started name
+ }
+ MS_ACT_TASKENABLE:PAnsiChar = 'Actions/TaskEnable';
+
+ {
+ Delete task
+ wParam - 0
+ lParam - unicode task name
+ Note - works for all tasks with same started name
+ }
+ MS_ACT_TASKDELETE:PAnsiChar = 'Actions/TaskDelete';
+
+ {
+ Set task repeat count
+ wParam - repeat count
+ lParam - unicode task name
+ Return - old repeat count value
+ Note - works for all tasks with same started name
+ }
+ MS_ACT_TASKCOUNT:PAnsiChar = 'Actions/TaskCount';
+
+ {
+ Event for task start
+ wParam - counter of call (from 0 to repeat count)
+ lParam - unicode task name
+ }
+ ME_ACT_BELL:PAnsiChar = 'Actions/Bell';
+
+{$ENDIF}
diff --git a/plugins/Actman/make.bat b/plugins/Actman/make.bat
new file mode 100644
index 0000000000..3e448f046c
--- /dev/null
+++ b/plugins/Actman/make.bat
@@ -0,0 +1,20 @@
+@echo off
+set myopts=-dMiranda
+set dprname=actman.dpr
+
+..\delphi\brcc32.exe %myopts% options.rc -fooptions.res
+..\delphi\brcc32.exe %myopts% hooks\hooks.rc -fohooks\hooks.res
+..\delphi\brcc32.exe %myopts% tasks\tasks.rc -fotasks\tasks.res
+..\delphi\brcc32.exe %myopts% ua\ua.rc -foua\ua.res
+
+if /i '%1' == 'fpc' (
+ ..\FPC\bin\fpc.exe %myopts% %dprname% %2 %3 %4 %5 %6 %7 %8 %9
+) else if /i '%1' == 'fpc64' (
+ ..\FPC\bin64\ppcrossx64.exe %myopts% %dprname% %2 %3 %4 %5 %6 %7 %8 %9
+) else if /i '%1' == 'xe2' (
+ ..\XE2\BIN\dcc32.exe %myopts% %dprname% %2 %3 %4 %5 %6 %7 %8 %9
+) else if /i '%1' == 'xe64' (
+ ..\XE2\BIN\dcc64.exe %myopts% %dprname% %2 %3 %4 %5 %6 %7 %8 %9
+) else (
+ ..\delphi\dcc32 %myopts% %dprname% %1 %2 %3 %4 %5 %6 %7 %8 %9
+)
diff --git a/plugins/Actman/options.rc b/plugins/Actman/options.rc
new file mode 100644
index 0000000000..cc7558f392
--- /dev/null
+++ b/plugins/Actman/options.rc
@@ -0,0 +1,328 @@
+#include "i_const.inc"
+
+LANGUAGE 0,0
+/*
+IDD_STRUCTURE DIALOGEX 0, 0, 332,184, 0
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_VISIBLE | WS_THICKFRAME
+CAPTION "Structure Editor"
+//EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0
+{
+ CONTROL "" , IDC_DATA_FULL, "SysListView32",
+ WS_BORDER | WS_TABSTOP |
+ LVS_NOCOLUMNHEADER | LVS_SHOWSELALWAYS |
+ LVS_SINGLESEL | LVS_REPORT,
+ 2, 2, 160, 180, WS_EX_CONTROLPARENT
+
+ CONTROL "New" ,IDC_DATA_NEW ,"MButtonClass",WS_TABSTOP,166, 2,16,16,$18000000// | WS_GROUP
+ CONTROL "Up" ,IDC_DATA_UP ,"MButtonClass",WS_TABSTOP,166,22,16,16,$18000000
+ CONTROL "Down" ,IDC_DATA_DOWN ,"MButtonClass",WS_TABSTOP,166,40,16,16,$18000000
+ CONTROL "Delete",IDC_DATA_DELETE,"MButtonClass",WS_TABSTOP,166,60,16,16,$18000000
+
+ COMBOBOX IDC_DATA_TYPE , 186, 2, 142, 96, CBS_DROPDOWNLIST | WS_VSCROLL
+ EDITTEXT IDC_DATA_LEN , 186, 18, 32, 11
+ LTEXT "Data length" ,-1 , 222, 18, 106, 11, SS_CENTERIMAGE
+ EDITTEXT IDC_DATA_EDIT, 186, 32, 142, 11, ES_AUTOHSCROLL
+ AUTOCHECKBOX "Use Variables", IDC_DATA_VARS, 186, 45, 142, 14
+
+ DEFPUSHBUTTON "&Change", IDC_DATA_CHANGE, 186, 62, 46, 14//, WS_GROUP
+ PUSHBUTTON "&OK" , IDOK , 234, 62, 46, 14
+ PUSHBUTTON "C&ancel", IDCANCEL , 282, 62, 46, 14
+
+ AUTOCHECKBOX "Packed structure", IDC_DATA_PACKED, 166, 78, 162, 14
+
+ CTEXT "Use Byte array/pointer for ANSI strings\n"\
+ "Use Word array/pointer for Unicode strings\n\n"\
+ "$## replaces by byte with hex value ##\n"\
+ "$#### replaces by word with hex value #### (for Unicode strings only)\n\n"\
+ "All data length calculating in bytes",
+ IDC_DATA_HELP,166,94,162,88
+
+}
+*/
+IDD_ACTION DIALOGEX 0, 0, 304, 226, 0
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_VISIBLE
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0
+{
+ CONTROL "New" ,IDC_GROUP_NEW ,"MButtonClass",WS_TABSTOP,114, 1,16,16,$18000000 | WS_GROUP
+ CONTROL "Up" ,IDC_GROUP_UP ,"MButtonClass",WS_TABSTOP,114, 18,16,16,$18000000
+ CONTROL "Down" ,IDC_GROUP_DOWN ,"MButtonClass",WS_TABSTOP,114, 34,16,16,$18000000
+ CONTROL "Reload",IDC_GROUP_RELOAD,"MButtonClass",WS_TABSTOP,114, 51,16,16,$18000000
+ CONTROL "Delete",IDC_GROUP_DELETE,"MButtonClass",WS_TABSTOP,114, 68,16,16,$18000000
+ CONTROL "Test" ,IDC_GROUP_TEST ,"MButtonClass",WS_TABSTOP,114, 85,16,16,$18000000
+ CONTROL "Export",IDC_GROUP_EXPORT,"MButtonClass",WS_TABSTOP,114,102,16,16,$18000000
+ CONTROL "Import",IDC_GROUP_IMPORT,"MButtonClass",WS_TABSTOP,114,119,16,16,$18000000
+
+ CONTROL "", IDC_ACTION_GROUP, "SysListView32",
+ WS_BORDER | WS_TABSTOP |
+ LVS_NOCOLUMNHEADER | LVS_SHOWSELALWAYS | LVS_REPORT | LVS_EDITLABELS,// | LVS_SINGLESEL,
+ 0, 2, 110, 132, WS_EX_CONTROLPARENT
+
+ CONTROL "", IDC_ACTION_LIST, "SysListView32",
+ WS_BORDER | WS_TABSTOP |
+ LVS_NOCOLUMNHEADER | LVS_SHOWSELALWAYS| LVS_REPORT | LVS_EDITLABELS,// | LVS_SINGLESEL
+ 0, 138, 110, 86, WS_EX_CONTROLPARENT
+
+ CONTROL "Help" ,IDC_ACTION_HELP ,"MButtonClass",WS_TABSTOP,114,138,16,16,$18000000 | WS_GROUP
+ CONTROL "New" ,IDC_ACTION_NEW ,"MButtonClass",WS_TABSTOP,114,156,16,16,$18000000
+ CONTROL "Up" ,IDC_ACTION_UP ,"MButtonClass",WS_TABSTOP,114,174,16,16,$18000000
+ CONTROL "Down" ,IDC_ACTION_DOWN ,"MButtonClass",WS_TABSTOP,114,190,16,16,$18000000
+ CONTROL "Delete",IDC_ACTION_DELETE,"MButtonClass",WS_TABSTOP,114,208,16,16,$18000000
+
+// PUSHBUTTON "Reset", IDC_RESET, 264, 2, 40, 12
+ GROUPBOX "" , -1, 132, 0, 172, 226
+
+ RTEXT "Action",IDC_STAT_ACTION, 135, 6, 63, 12, SS_CENTERIMAGE
+ CONTROL "", IDC_ACTION_TYPE, "ComboBoxEx32",
+ WS_TABSTOP | WS_VSCROLL | CBS_AUTOHSCROLL | CBS_DROPDOWNLIST, 200, 6, 101, 96
+
+// Contact
+ RTEXT "Choose Contact", IDC_STAT_CONTACT , 135, 24, 160, 10
+ COMBOBOX IDC_CONTACTLIST, 135, 35, 166, 128, CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL
+ AUTOCHECKBOX "Keep handle only" , IDC_CNT_KEEP , 135, 53, 160, 11
+ AUTOCHECKBOX "Active accounts only",IDC_CNT_FILTER, 135, 65, 160, 11
+ RTEXT "Dropdown list format",IDC_STAT_FORMAT, 135, 78, 160, 11
+ EDITTEXT IDC_EDIT_FORMAT , 153, 92, 142, 12, ES_AUTOHSCROLL
+ CONTROL "Apply",IDC_CNT_APPLY,"MButtonClass",WS_TABSTOP,135,90,16,16,$18000000
+ CTEXT "You can use %name%, %uid%, %account% and %group% macros",IDC_STAT_FHELP, 135, 107, 160, 24
+
+// Service
+ RTEXT "wParam type", IDC_STAT_WPAR1, 135, 125, 63, 14, SS_CENTERIMAGE
+ COMBOBOX IDC_FLAG_WPAR , 200, 125, 102, 56, CBS_DROPDOWNLIST | WS_VSCROLL
+ RTEXT "lParam type", IDC_STAT_LPAR1, 135, 140, 63, 14, SS_CENTERIMAGE
+ COMBOBOX IDC_FLAG_LPAR , 200, 140, 102, 56, CBS_DROPDOWNLIST | WS_VSCROLL
+
+ RTEXT "Service name", IDC_STAT_SERVICE, 135, 153, 160, 8
+ AUTOCHECKBOX "", IDC_SRV_SRVC,135,162,8,8,BS_ICON | BS_PUSHLIKE
+ COMBOBOX IDC_EDIT_SERVICE, 144, 162, 157, 96, CBS_DROPDOWN | WS_VSCROLL | CBS_AUTOHSCROLL | CBS_SORT
+ RTEXT "wParam" , IDC_STAT_WPAR , 135, 177, 160, 8
+ AUTOCHECKBOX "", IDC_SRV_WPAR,135,186,8,8,BS_ICON | BS_PUSHLIKE
+ COMBOBOX IDC_EDIT_WPAR , 144, 186, 157, 76, CBS_DROPDOWN | WS_VSCROLL | CBS_AUTOHSCROLL
+ RTEXT "lParam" , IDC_STAT_LPAR , 135, 201, 160, 8
+ AUTOCHECKBOX "", IDC_SRV_LPAR,135,210,8,8,BS_ICON | BS_PUSHLIKE
+ COMBOBOX IDC_EDIT_LPAR , 144, 210, 157, 76, CBS_DROPDOWN | WS_VSCROLL | CBS_AUTOHSCROLL
+ PUSHBUTTON "Structure" , IDC_WSTRUCT , 135, 186, 166, 14
+ PUSHBUTTON "Structure" , IDC_LSTRUCT , 135, 210, 166, 14
+
+ GROUPBOX "Result action" , IDC_RES_GROUP , 135, 24, 166, 99, WS_GROUP
+ AUTOCHECKBOX "Show in popup" , IDC_RES_POPUP , 138, 34, 159, 11
+ AUTOCHECKBOX "Show in messagebox" , IDC_RES_MESSAGE, 138, 45, 159, 11
+ AUTOCHECKBOX "Insert into message", IDC_RES_INSERT , 138, 56, 159, 11
+
+ LTEXT "Service result" , IDC_SRV_RESSTAT, 138, 72, 159, 11
+ COMBOBOX IDC_SRV_RESULT , 138, 83, 159, 76, CBS_DROPDOWN | WS_VSCROLL | CBS_AUTOHSCROLL
+ AUTOCHECKBOX "Free memory" , IDC_RES_FREEMEM, 138, 99, 159, 11
+ AUTOCHECKBOX "Unicode string" , IDC_RES_UNICODE, 138, 110, 159, 11
+ AUTOCHECKBOX "Signed value" , IDC_RES_SIGNED , 138, 99, 159, 11
+
+// Program
+ GROUPBOX "Process options" , IDC_PROCESS_GROUP, 135, 24, 166, 46, WS_GROUP
+ AUTORADIOBUTTON "Parallel" , IDC_FLAG_PARALLEL, 138, 33, 161, 11
+ AUTORADIOBUTTON "Continued" , IDC_FLAG_CONTINUE, 138, 44, 161, 11
+ EDITTEXT IDC_EDIT_PROCTIME, 138, 56, 31, 11, ES_RIGHT | ES_NUMBER
+ LTEXT "Process time, ms", IDC_STAT_PROCTIME, 171, 56, 128, 11, SS_CENTERIMAGE
+
+ AUTOCHECKBOX "Current path" , IDC_FLAG_CURPATH, 138, 72, 161, 11
+
+ GROUPBOX "Window option" , IDC_PRSTART_GROUP, 135, 83, 166, 55, WS_GROUP
+ AUTORADIOBUTTON "Start normal" , IDC_FLAG_NORMAL , 138, 92, 162, 11
+ AUTORADIOBUTTON "Start hidden" , IDC_FLAG_HIDDEN , 138, 103, 162, 11
+ AUTORADIOBUTTON "Start minimized", IDC_FLAG_MINIMIZE, 138, 114, 162, 11
+ AUTORADIOBUTTON "Start maximized", IDC_FLAG_MAXIMIZE, 138, 125, 162, 11
+
+ CONTROL "V", IDC_HLP_FVARS, "MButtonClass",WS_TABSTOP, 285,139,16,16,$18000000
+ RTEXT "Program path", IDC_STAT_PRGPATH, 135, 155, 160, 8
+ AUTOCHECKBOX "", IDC_PRG_PRG,135,164,8,8,BS_ICON | BS_PUSHLIKE
+ EDITTEXT IDC_EDIT_PRGPATH, 144, 164, 139, 12, ES_AUTOHSCROLL
+ PUSHBUTTON "..." , IDC_PROGRAM , 285, 164, 16, 12
+ RTEXT "Program args", IDC_STAT_PRGARGS, 135, 179, 160, 8
+ AUTOCHECKBOX "", IDC_PRG_ARG,135,186,8,8,BS_ICON | BS_PUSHLIKE
+ EDITTEXT IDC_EDIT_PRGARGS, 144, 188, 157, 12, ES_AUTOHSCROLL
+
+// Text
+ AUTORADIOBUTTON "Clipboard" , IDC_FLAG_CLIP , 135, 20, 166, 11, WS_GROUP
+ AUTORADIOBUTTON "File" , IDC_FLAG_FILE , 135, 66, 166, 11
+ AUTORADIOBUTTON "Message window", IDC_FLAG_MESSAGE, 135, 128, 166, 11
+
+ GROUPBOX "" , IDC_CLIP_GROUP , 135, 30, 166, 33
+ AUTORADIOBUTTON "Copy to" , IDC_CLIP_COPYTO, 140, 36, 160, 11, WS_GROUP
+ AUTORADIOBUTTON "Paste from", IDC_CLIP_PASTE , 140, 47, 160, 11
+
+ GROUPBOX "" , IDC_FILE_GROUP , 135, 75, 166, 52
+ AUTORADIOBUTTON "Read" , IDC_FILE_READ , 138, 83, 52, 11, WS_GROUP
+ AUTORADIOBUTTON "Write" , IDC_FILE_WRITE , 191, 83, 52, 11
+ AUTORADIOBUTTON "Append" , IDC_FILE_APPEND , 244, 83, 52, 11
+ AUTOCHECKBOX "", IDC_TXT_FILE,138,96,8,8,BS_ICON | BS_PUSHLIKE
+ EDITTEXT IDC_FILE_PATH , 147, 96, 131, 12, ES_AUTOHSCROLL
+ PUSHBUTTON "..." , IDC_FILE_FILEBTN, 281, 96, 16, 12
+ COMBOBOX IDC_FILE_ENC , 138, 111, 160, 76, CBS_DROPDOWNLIST | WS_VSCROLL
+
+ CONTROL "V", IDC_HLP_VARS, "MButtonClass",WS_TABSTOP, 285,139,16,16,$18000000
+// PUSHBUTTON "vars" , IDC_HLP_VARS , 264, 140, 37, 14
+ RTEXT "Text to insert", IDC_STAT_INSERT , 135, 155, 160, 9
+ AUTOCHECKBOX "", IDC_TXT_TEXT,135,164,8,8,BS_ICON | BS_PUSHLIKE
+ EDITTEXT IDC_EDIT_INSERT , 144, 164, 157, 59,
+ ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN
+
+// Advanced
+ GROUPBOX "Condition" , IDC_CONDITION , 135, 24, 166, 34, WS_GROUP
+ AUTORADIOBUTTON ">" , IDC_FLAG_GT , 138, 33, 32, 11
+ AUTORADIOBUTTON "<" , IDC_FLAG_LT , 170, 33, 32, 11
+ AUTORADIOBUTTON "=" , IDC_FLAG_EQ , 202, 33, 32, 11
+ AUTORADIOBUTTON "NOP" , IDC_FLAG_NOP , 234, 33, 32, 11
+ AUTOCHECKBOX "NOT" , IDC_FLAG_NOT , 138, 44, 32, 11
+ RTEXT "Value" , IDC_STAT_VAL , 170, 44, 78, 11, SS_CENTERIMAGE
+ EDITTEXT IDC_ADV_VALUE , 250, 44, 48, 11, ES_RIGHT //| ES_NUMBER
+
+ AUTOCHECKBOX "Math" , IDC_FLAG_MATH , 138, 61, 64, 13, WS_GROUP
+ COMBOBOX IDC_ADV_OPER , 204, 61, 44, 96,
+ CBS_DROPDOWNLIST | WS_VSCROLL
+ EDITTEXT IDC_ADV_VAL1 , 250, 61, 48, 13, ES_RIGHT //| ES_NUMBER
+
+ AUTOCHECKBOX "Variables" , IDC_FLAG_VARS , 138, 78, 124, 12
+ CONTROL "V", IDC_ADV_HVARS, "MButtonClass",WS_TABSTOP, 285,75,16,16,$18000000
+// PUSHBUTTON "vars" , IDC_ADV_HVARS , 264, 78, 37, 12
+ EDITTEXT IDC_ADV_VARS , 144, 92, 157, 68,
+ ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN
+ AUTOCHECKBOX "Result as integer", IDC_ADV_ASINT , 135, 161, 164, 13, BS_RIGHT | BS_LEFTTEXT
+
+ GROUPBOX "Operation" , IDC_OPERATION , 135, 174, 166, 49, WS_GROUP
+ AUTORADIOBUTTON "JUMP" , IDC_FLAG_JUMP , 138, 183, 62, 12
+ AUTORADIOBUTTON "BREAK" , IDC_FLAG_BREAK, 138, 196, 62, 12
+ AUTORADIOBUTTON "NOP" , IDC_FLAG_ANOP , 138, 209, 62, 12
+ COMBOBOX IDC_ADV_VAL2 , 200, 183, 99, 96, CBS_DROPDOWNLIST | WS_VSCROLL | CBS_AUTOHSCROLL
+
+// Chain
+ RTEXT "Other Action groups",IDC_STAT_GROUPS,135, 24, 160, 10
+ COMBOBOX IDC_GROUP_LIST, 135, 35, 166, 128,
+ CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL
+
+// Read / write setting
+
+ AUTORADIOBUTTON "Own settings", IDC_RW_CURRENT, 135, 50, 80, 11, BS_RIGHT | BS_LEFTTEXT | WS_GROUP
+ AUTORADIOBUTTON "Manual" , IDC_RW_MANUAL , 135, 62, 80, 11, BS_RIGHT | BS_LEFTTEXT
+ AUTORADIOBUTTON "Parameter" , IDC_RW_PARAM , 217, 50, 80, 11
+ AUTORADIOBUTTON "Last result" , IDC_RW_RESULT , 217, 62, 80, 11
+
+ RTEXT "Module" , IDC_RW_STATM , 135, 75, 160, 8, SS_CENTERIMAGE
+ AUTOCHECKBOX "", IDC_RW_MVAR,135,84,8,8,BS_ICON | BS_PUSHLIKE
+ EDITTEXT IDC_RW_MODULE , 144, 84, 157, 12, ES_AUTOHSCROLL
+ RTEXT "Setting" , IDC_RW_STATS , 135, 99, 160, 8, SS_CENTERIMAGE
+ AUTOCHECKBOX "", IDC_RW_SVAR,135,108,8,8,BS_ICON | BS_PUSHLIKE
+ EDITTEXT IDC_RW_SETTING, 144, 108, 157, 12, ES_AUTOHSCROLL
+
+ GROUPBOX "Operation" , IDC_RW_OPER , 135, 124, 166, 21, WS_GROUP
+ AUTORADIOBUTTON "Read" , IDC_RW_READ , 138, 133, 52, 11
+ AUTORADIOBUTTON "Write" , IDC_RW_WRITE , 191, 133, 52, 11
+ AUTORADIOBUTTON "Delete" , IDC_RW_DELETE , 244, 133, 52, 11
+
+ GROUPBOX "Value" , IDC_RW_VAL , 135, 146, 166, 76, WS_GROUP
+
+ COMBOBOX IDC_RW_DATATYPE, 220, 155, 79, 96,
+ CBS_DROPDOWNLIST | WS_VSCROLL
+
+ AUTOCHECKBOX "Last result" , IDC_RW_LAST , 140, 179, 156, 11, BS_RIGHT | BS_LEFTTEXT
+ EDITTEXT IDC_RW_VALUE , 149, 191, 147, 11, ES_AUTOHSCROLL | ES_RIGHT// | ES_NUMBER
+ AUTOCHECKBOX "", IDC_RW_TVAR,140,191,8,8,BS_ICON | BS_PUSHLIKE
+ EDITTEXT IDC_RW_TEXT , 149, 191, 147, 29,
+ ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN
+
+// MessageBox
+
+ AUTOCHECKBOX "", IDC_MSG_TTL,135,32,8,8,BS_ICON | BS_PUSHLIKE
+ EDITTEXT IDC_MSG_TITLE, 144, 32, 157, 12,
+ ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN
+ RTEXT "Message text" ,IDC_MSG_STAT2, 137, 46, 164, 11, SS_CENTERIMAGE
+ AUTOCHECKBOX "", IDC_MSG_TXT,135,58,8,8,BS_ICON | BS_PUSHLIKE
+ EDITTEXT IDC_MSG_TEXT , 144, 58, 157, 49,
+ ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN
+ AUTOCHECKBOX "Keep Last Result" , IDC_MSG_KEEP, 138, 109, 163, 11, BS_RIGHT | BS_LEFTTEXT
+
+ GROUPBOX "Icons" , IDC_MSG_ICONS , 135, 123, 166, 28, WS_GROUP
+ AUTORADIOBUTTON "Error" , IDC_MSGI_ERROR, 140, 130, 24, 20, BS_ICON
+ AUTORADIOBUTTON "Question", IDC_MSGI_QUEST, 166, 130, 24, 20, BS_ICON
+ AUTORADIOBUTTON "Warning" , IDC_MSGI_WARN , 192, 130, 24, 20, BS_ICON
+ AUTORADIOBUTTON "Info" , IDC_MSGI_INFO , 218, 130, 24, 20, BS_ICON
+ AUTORADIOBUTTON "None" , IDC_MSGI_NONE , 246, 130, 53, 20//, BS_ICON
+
+ GROUPBOX "Buttons" , IDC_MSG_BTNS, 135, 152, 166, 71, WS_GROUP
+ AUTORADIOBUTTON "OK" , IDC_MSGB_OK , 140, 161, 156, 10
+ AUTORADIOBUTTON "OK, Cancel" , IDC_MSGB_OC , 140, 171, 156, 10
+ AUTORADIOBUTTON "Abort, Retry, Ignore", IDC_MSGB_ARI, 140, 181, 156, 10
+ AUTORADIOBUTTON "Yes, No, Cancel" , IDC_MSGB_YNC, 140, 191, 156, 10
+ AUTORADIOBUTTON "Yes, No" , IDC_MSGB_YN , 140, 201, 156, 10
+ AUTORADIOBUTTON "Retry, Cancel" , IDC_MSGB_RC , 140, 211, 156, 10
+
+ RTEXT "Message title",IDC_MSG_STAT1, 137, 20, 164, 11, SS_CENTERIMAGE
+}
+
+IDD_ASK DIALOGEX 0, 0, 276, 72, 0
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+EXSTYLE WS_EX_CONTROLPARENT
+CAPTION "Choose action"
+FONT 8, "MS Shell Dlg", 0, 0
+{
+ CTEXT "", IDC_ASK,4,4,268,42,SS_CENTERIMAGE
+
+ CONTROL "", -1, "STATIC", SS_ETCHEDHORZ, 2, 50, 272, 2
+
+ DEFPUSHBUTTON "&Yes" , IDOK , 4, 54, 40, 16
+ PUSHBUTTON "&No" , IDCANCEL , 52, 54, 40, 16
+ PUSHBUTTON "A&ppend" , IDC_APPEND, 100, 54, 52, 16
+ PUSHBUTTON "Yes to &All", IDC_YESALL, 160, 54, 52, 16
+ PUSHBUTTON "N&o to All" , IDC_NOALL , 220, 54, 52, 16
+}
+
+IDI_NEW ICON "ico\new.ico"
+IDI_UP ICON "ico\up.ico"
+IDI_DOWN ICON "ico\down.ico"
+IDI_DELETE ICON "ico\delete.ico"
+IDI_RELOAD ICON "ico\reload.ico"
+IDI_TEST ICON "ico\test.ico"
+IDI_EXPORT ICON "ico\export.ico"
+IDI_IMPORT ICON "ico\import.ico"
+
+IDI_CONTACT ICON "ico\contact.ico"
+IDI_SERVICE ICON "ico\service.ico"
+IDI_PROGRAM ICON "ico\program.ico"
+IDI_INSERT ICON "ico\insert.ico"
+IDI_ADVANCE ICON "ico\advance.ico"
+IDI_CHAIN ICON "ico\chain.ico"
+IDI_RW ICON "ico\rw.ico"
+IDI_MESSAGE ICON "ico\message.ico"
+IDI_FORMAT ICON "ico\format.ico"
+
+IDI_APPLY ICON "ico\apply.ico"
+
+IDI_VAR_CHECKED ICON "ico\vcheck.ico"
+IDI_VAR_UNCHECKED ICON "ico\vuncheck.ico"
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 0,2,0,1
+ PRODUCTVERSION 0,9,0,0
+ FILEFLAGSMASK $3F
+ FILEOS 4
+ FILETYPE 2
+ FILESUBTYPE 0
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "000004b0"
+ BEGIN
+ VALUE "CompanyName",""
+ VALUE "Comments", "Plugin for managing different Miranda actions "0
+ VALUE "FileDescription", "Action manager for Miranda NG"0
+ VALUE "FileVersion", "0, 2, 0, 1 "0
+ VALUE "InternalName", "ActManager"0
+ VALUE "OriginalFilename", "actman.dll"0
+ VALUE "ProductName", "Action Manager Dynamic Link Library (DLL)"0
+ VALUE "ProductVersion", "0, 9, 0, 0 "0
+ VALUE "SpecialBuild", "18.08.2011 "0
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation",0,1200
+ END
+END
diff --git a/plugins/Actman/options.res b/plugins/Actman/options.res
new file mode 100644
index 0000000000..5c280b96d4
--- /dev/null
+++ b/plugins/Actman/options.res
Binary files differ
diff --git a/plugins/Actman/question.pas b/plugins/Actman/question.pas
new file mode 100644
index 0000000000..84bbd60604
--- /dev/null
+++ b/plugins/Actman/question.pas
@@ -0,0 +1,51 @@
+unit question;
+
+interface
+uses windows,messages;
+
+function QuestionDlg(Dialog:HWnd;hMessage:UINT;wParam:WPARAM;lParam:LPARAM):LRESULT; stdcall;
+
+implementation
+
+uses m_api;
+
+{$include i_const.inc}
+
+const
+ imp_yes = 1;
+ imp_yesall = 2;
+ imp_no = 3;
+ imp_noall = 4;
+ imp_append = 5;
+
+function QuestionDlg(Dialog:HWnd;hMessage:UINT;wParam:WPARAM;lParam:LPARAM):LRESULT; stdcall;
+var
+ i:integer;
+begin
+ result:=0;
+ case hMessage of
+ WM_INITDIALOG: begin
+ TranslateDialogDefault(Dialog);
+ SetDlgItemTextW(Dialog, IDC_ASK,pWideChar(lParam));
+ result:=1;
+ end;
+ WM_COMMAND: begin
+ case loword(wParam) of
+ IDOK : i:=imp_yes;
+ IDCANCEL : i:=imp_no;
+ IDC_YESALL: i:=imp_yesall;
+ IDC_NOALL : i:=imp_noall;
+ IDC_APPEND: i:=imp_append;
+ else
+ i:=0;
+ end;
+ if i<>0 then
+ begin
+ EndDialog(Dialog,i);
+ result:=1;
+ end;
+ end;
+ end;
+end;
+
+end.
diff --git a/plugins/Actman/readme.txt b/plugins/Actman/readme.txt
new file mode 100644
index 0000000000..0d1c6108b4
--- /dev/null
+++ b/plugins/Actman/readme.txt
@@ -0,0 +1,126 @@
+Note
+----
+'Actions' is action groups wich can be executed through services
+'Subactions' is single simple action like 'Call service', ' rum program' etc.
+
+Description
+-----------
+This service plugin can be used for defining, management and executing some
+actions.
+Action can be executed later through miranda service.
+
+Settings
+--------
+Main window consist of two parts. Left part is for action list and subaction list
+for selected action. Navigation buttons for action list and subaction list positioned near
+these lists.
+'New' - to add new list item
+'Delete' - to delete selected item
+'Reload' - to reload settings from DB
+'Test' - executes currently selected action
+'Up','Down' - for place selected subaction upper or lower current position
+With DblClick on ag list item you can rename this item
+
+When action list is not empty, in right side you can see combobox for subaction type selecting.
+At this moment only next types supported:
+ Open contact window
+ Call service
+ Execute program
+ Insert text
+ Advanced
+ Link to action
+ Profile
+ MessageBox
+
+-- Open contact window
+Just select needed contact from combobox.
+
+-- Call service
+This is one of hard to understand action type.
+wParam and lParam comboboxes in upper part are for parameter type.
+ 'number' - just integer number (decimal or hex started from $ sign)
+ 'ANSI string' - single-byte character string
+ 'Unicode string' - double-byte character string
+ 'Current contact' - mean what parameter is current user handle.
+ Current user is active window owner
+ 'Last result' - result from previous action or calling parameter
+ 'Parameter' - parameter from calling service
+ 'Structure' - parameter is structure which can be edited in options dialog
+ but will not saving changes in runtime.
+
+wParam and lParam in lower part are for values, passed to service.
+If service.ini file presents in plugins directory, you can press F1 to see short help
+notes for selected from combobox service name.
+Most upper part, 'result action' is for action, what we must to do with result:
+show in popup, in message window or paste into text.
+Option to translate result are: integer decimal value (signed or not), hex value or
+string value (Unicode or ANSI)
+'<proto>' in service name will be replaced by protocol name for contact handle in paremeter
+
+-- Execute program
+More hard for undestand are upper settings.
+Process settings: 'parallel' means executing next subaction or return from executing action
+immediately, 'continued' mean what next subaction will be only after finishing this program.
+Process time option is for waiting time after that runned process will be shutdowned.
+'Current path' mean what program will run with current directory as start directory.
+Window options are for starting window view: minimized, normal, maximized etc.
+Severl macros can be used in program name:
+<param> - parameter
+<last> - last result
+
+-- Insert text
+You can work with Clipboard or file/mesage window here.
+In field below action type combobox you can write some text which will be inserted
+into text field of miranda and other program.
+Or, that text can be writed to file or some text can be readed.
+If you want help for text formatting, you can press F1.
+You can use Variables plugin. If you want it, just mark checkbox. help button can
+get help notes for available variables and functions.
+
+-- Advanced
+Most ununderstable block. Upper group is conditions for operation executing.
+'Value' is value for comparing last subaction result with it.
+Next actions will be if condition is true:
+'Math' - mathematic operations with last result and presented in 'value' field value.
+After math calculations (or w/o it) can be used next operations:
+'Operation' block consist of several operations:
+ 'BREAK' - break action executing (and return for 'parent' action executing - if exist)
+ 'JUMP' - jump to subaction with selected name
+ 'NOP' - not operation
+
+As 'Math' alternative, you can use Variables plugin scripts.
+Script can be writed in text field below and checked by pressing 'Vars' button.
+Variables %subject% and %extratext% can be used in the script.
+
+-- Call chain
+Select action from combobox below. This action will be executed. After that next subaction
+will be executed.
+
+-- Database
+This subaction is for database reading/writing (see Operation block).
+Value and value type is for type of data, reading or writing from/to database.
+'Last result' mean that value is result of previous action.
+Group of radioboxes is for contact type.
+ 'Own settings' - all settings only for our contact (our profle settings)
+ 'Parameter' - settings for contact with handle, passed from start parameter
+ 'Last result' - contact handle is result of last action
+ 'Manual' - contact handle selected from combobox
+'<proto>' in module name will be replaced with contact protocol name
+
+-- MessageBox
+ Subaction uses for standard windows MessageBox showing. text <last> will be replaced
+by last result value.
+
+Using
+-----
+Executing action from option dialog is possible but not recommended.
+First way is assign action to button for toolbar (maybe through modern clist skin engine)
+Second way is assign action to hotkey (miranda core not so good for this now)
+Third way is to insert action into menu by other plugin.
+Pluginmaker Vasilich wrote his plugin (UserActions) which works with ActMan and gives
+access to ability to assign actions to some controls (menu, toolbar, hotkey).
+
+Byte/Word/DWord - numeric integer data
+byte/word pointers - pointers to some data (really, like ANSI/Unicode strings)
+byte/word array - array of mixed data (really, like ANSI/Unicode strings)
+last result/param - current working data = dword
diff --git a/plugins/Actman/services.ini b/plugins/Actman/services.ini
new file mode 100644
index 0000000000..1de3148fdd
--- /dev/null
+++ b/plugins/Actman/services.ini
@@ -0,0 +1,497 @@
+;Small Service list
+;if wparam or lparam consists of list, "|" is separator
+;in list: if translation not needed, just add space before help
+;numeric parameter format: number<space>help
+;hContact will setup "Current contact" feature
+;structure will setup "structure" feature
+;if "return" starts from int/hex/str/struct then separator, result type will set
+
+
+;[Event:Event (name or constant]
+;alias=constant name
+;descr=text
+;plugin=placement (including "core" and empty = "unknown"
+;wparam=
+;lparam=
+
+;full: full structure, with aliases
+;short: smallest needed structure
+;descr: structure description
+;plugin: where defined
+
+[Service:CListFrames/HideALLFramesTB]
+alias=MS_CLIST_FRAMES_HIDEALLFRAMESTB
+wparam=0
+lparam=0
+return=int 0, if successful
+descr=Hide All Titlebars
+
+[Service:CListFrames/ShowALLFrames]
+alias=MS_CLIST_FRAMES_SHOWALLFRAMES
+wparam=0
+lparam=0
+return=int 0, if successful
+descr=Show All Frames
+
+[Service:CListFrames/ShowALLFramesTB]
+alias=MS_CLIST_FRAMES_SHOWALLFRAMESTB
+wparam=0
+lparam=0
+return=int 0, if successful
+descr=Show All Titlebars
+
+[Service:CList/MenuBuildContact]
+alias=MS_CLIST_MENUBUILDCONTACT
+wparam=hContact
+lparam=0
+return=int hMenu handle
+descr=Built the context menu for a specific contact. Menu should be DestroyMenu()ed after done
+
+[Service:CList/SetHideOffline]
+alias=MS_CLIST_SETHIDEOFFLINE
+wparam=0 Show All Users|1 Show only Online Users|-1 Toggle status
+lparam=0
+return=int 0, if successful
+descr=Change 'hide offline contacts' option value
+
+[Service:CList/SetStatusMode]
+alias=MS_CLIST_SETSTATUSMODE
+wparam=40071 Offline|40072 Online|40073 Away|40074 DND|40075 NA|40076 Occupied|40077 Free for Chat|40078 Invisible|40079 On the Phone|40080 Out to Lunch
+lparam=0
+return=int 0, if successful
+descr=Set global status
+
+[Service:CList/ShowHide]
+alias=MS_CLIST_SHOWHIDE
+wparam=0
+lparam=0
+return=int 0, if successful
+descr=Switch contactlist status
+
+[Service:CloseAction]
+wparam=0
+lparam=0
+descr=Closes Miranda
+
+[Service:Console/Show/Hide]
+wparam=0
+lparam=0
+plugin=Console (console.dll)
+Show or hide netlog console window
+
+[Service:DB/Contact/GetCount]
+alias=MS_DB_CONTACT_GETCOUNT
+wparam=0
+lparam=0
+return=int Value
+descr=Returns contact amount, excluding user account
+
+[Service:DB/Module/Delete]
+alias=MS_DB_MODULE_DELETE
+wparam=0
+lparam=Ansi Text
+descr=Removes all settings for the specified module
+
+[Service:DBEditorpp/Import]
+alias=MS_DBEDIT_IMPORT
+wparam=hContact
+lparam=Ansi Text
+return=int 0
+descr=Import settings\contacts from file
+plugin=Database Editor++ (dbeditorpp.dll)
+
+[Service:DBEditorpp/MenuCommand]
+alias=MS_DBEDIT_MENUCOMMAND
+wparam=0
+lparam=0
+return=int 0
+plugin=Database Editor++ (dbeditorpp.dll)
+descr=Opens or activate database editor
+
+[Service:FindAdd/FindAddCommand]
+alias=MS_FINDADDFINDADD
+wparam=0
+lparam=0
+return=int 0
+descr=Opens or activate user search dialog
+
+[Service:FtMgr/Show]
+wparam=0
+lparam=0
+return=int 0
+descr=displays File Transfer window
+
+[Service:Help/AboutCommand]
+wparam=0 on Desktop|parent window handle
+lparam=0
+descr=Show window "About..."
+
+[Service:Help/IndexCommand]
+wparam=0
+lparam=0
+descr=Open support (originaly - Miranda wiki) page
+
+[Service:Help/WebsiteCommand]
+wparam=0
+lparam=0
+descr=Go to Miranda IM Homepage
+
+[Service:Help/BugCommand]
+wparam=0
+lparam=0
+descr=Open bug report page
+
+[Service:History/ShowContactHistory]
+alias=MS_HISTORY_SHOWCONTACTHISTORY
+wparam=0 System|hContact
+lparam=0
+descr=Shows contact history or (wParam=0) system history
+
+[Service:History++/EmptyHistory]
+alias=MS_HPP_EMPTYHISTORY
+wparam=hContact
+lparam=0
+plugin=History++ (historypp.dll)
+descr=Erases contact's history. hContact can be NULL(0) to empty system history
+
+[Service:History++/ShowGlobalSearch]
+alias=MS_HPP_SHOWGLOBALSEARCH
+wparam=0
+lparam=0
+plugin=History++ (historypp.dll)
+descr=Show Global history search window. If already opened, bring it to front.
+
+[Service:Ignore/Ignore]
+alias=MS_IGNORE_IGNORE
+wparam=hContact
+lparam=-1 Ignore all|1 Ignore messages|2 Ignore URLs|3 Ignore files|4 Ignore User Online|5 Ignore requests|6 Ignore 'You were added'
+return=int 0, if successful
+descr=Ignore Contact
+
+[Service:Ignore/Unignore]
+alias=MS_IGNORE_UNIGNORE
+wparam=hContact
+lparam=-1 Ignore all|1 Ignore messages|2 Ignore URLs|3 Ignore files|4 Ignore User Online|5 Ignore requests|6 Ignore 'You were added'
+return=int 0, if successful
+descr=Unignore Contact
+
+[Service:mDynDNS/GetIP]
+wparam=0 auto|1 mDynDNS-checkip|2 DNS querry
+lparam=structure|*b.arr 16|
+return=struct
+descr=Returns the IP (emty string on failure)
+
+[Service:MIMLocker/Lock]
+wparam=0
+wparam=0
+plugin=MIMLocker (MIMLocker.dll)
+descr=Locks & hides Miranda's contact list and message sessions until password is entered
+
+[Service:Miranda/System/Restart]
+alias=MS_SYSTEM_RESTART
+wparam=0
+lparam=0
+descr=Restarts Miranda (try to use together with CloseAction service) ver.0.8+
+
+[Service:mRadio/PlayStop]
+alias=MS_RADIO_PLAYSTOP
+wparam=hContact|Station name
+lparam=0 wParam is Handle|1 wParam is Ansi station name|2 wParam is Unicode station name
+descr=Starting or stopping radio station
+
+[Service:MyDetails/CicleThroughtProtocols]
+alias=MS_MYDETAILS_CICLE_THROUGHT_PROTOCOLS
+wparam=0 Stop cycle|1 Start cycle
+lparam=0
+return=int 0, if successful
+plugin=My Details (mydetails.dll)
+descr=Start/stops the cycling throught protocols
+
+[Service:MyDetails/SetMyAvatarUI]
+alias=MS_MYDETAILS_SETMYAVATARUI
+wparam=0
+lparam=0 All protocols|Protocol
+return=signed -2 if proto can't set this, -1 on protocol not found, else 0
+plugin=My Details (mydetails.dll)
+descr=Shows a dialog to set the avatar for all possible protocols
+
+[Service:MyDetails/ShowNextProtocol]
+alias=MS_MYDETAILS_SHOWNEXTPROTOCOL
+wparam=0
+lparam=0
+return=int 0, if successful
+plugin=My Details (mydetails.dll)
+descr=Shows the next protocol in the frame
+
+[Service:MyDetails/ShowPreviousProtocol]
+alias=MS_MYDETAILS_SHOWPREVIOUSPROTOCOL
+wparam=0
+lparam=0
+return=int 0, if successful
+plugin=My Details (mydetails.dll)
+descr=Shows the previous protocol in the frame
+
+[Service:Options/OptionsCommand]
+wparam=0
+lparam=0
+descr=Open Options dialog
+
+[Service:Opt/OpenOptions]
+alias=MS_OPT_OPENOPTIONS
+wparam=0
+lparam=structure|0|native|bptr|bptr|bptr|
+return=int 0, if successful
+descr=Opens the options dialog, optionally at the specified page
+
+[Service:PopUp/EnableDisableMenuCommand]
+wparam=0
+lparam=0
+plugin=Popup Plus (popup.dll)
+descr=Enables or disables PopUp windows
+
+[Service:PopUp/ShowMessage]
+alias=MS_POPUP_SHOWMESSAGE
+wparam=Ansi Text
+lparam=1 Warning|2 Notify|3 Error
+return=int 0, if successful
+plugin=YAPP or PopUp
+descr=Popup window
+
+[Service:PopUp/ShowMessageW]
+alias=MS_POPUP_SHOWMESSAGEW
+wparam=Unicode Text
+lparam=1 Warning|2 Notify|3 Error
+return=int 0, if successful
+plugin=YAPP only
+descr=Popup window
+
+[Service:PopUp/ToggleEnabled]
+wparam=0
+lparam=0
+plugin=YAPP (yapp.dll)
+descr=Enables or disables PopUp windows
+
+[Service:Proto/CallContactService]
+alias=MS_PROTO_CALLCONTACTSERVICE
+wparam=0
+lparam=structure|0|native|b.ptr|native|native|
+return=result of protocol service call
+descr=send a general request through the protocol chain for a contact
+
+[Service:Protos/ShowAccountManager]
+alias=MS_PROTO_SHOWACCMGR
+wparam=0
+lparam=0
+descr=displays the Account Manager
+
+[Service:QuickContacts/ShowDialog]
+alias=MS_QC_SHOW_DIALOG
+wparam=0
+lparam=0
+plugin=Quick Contacts (quickcontacts.dll)
+descr=Show the dialog to select the contact
+
+[Service:QuickSearch_PLUGIN/Show]
+wparam=0|filter text
+lparam=0 wparam is unicode|1 wparam is Ansi|2 reserved
+plugin=Quick Search (Mod) (quicksearch.dll)
+descr=
+
+[Service:Skin/Sounds/Play]
+alias=MS_SKIN_PLAYSOUND
+wparam=0
+lparam=Name
+descr=Plays sound added through Skin/Sounds/AddNew. If sound not found, standard Windows sound plays
+
+[Service:SREMail/SendCommand]
+alias=MS_EMAIL_SENDEMAIL
+wparam=hContact
+lparam=0
+return=int 0, if successful
+descr=Send Email to contact
+
+[Service:SRFile/GetReceivedFilesFolder]
+alias=MS_FILE_GETRECEIVEDFILESFOLDER
+wparam=hContact
+lparam=structure|*b.arr 300|
+return=struct
+descr=Returns the received files folder for a contact
+
+[Service:SRFile/OpenContRecDir]
+wparam=hContact
+lparam=0
+descr=Open contact received file directory
+
+[Service:SRFile/SendCommand]
+alias=MS_FILE_SENDFILE
+wparam=hContact
+lparam=0
+return=int 0, if successful
+descr=Send file to contact.
+
+[Service:SRMsg/SendCommand]
+alias=MS_MSG_SENDMESSAGE
+wparam=hContact;parameter
+lparam=0
+descr=Opens message window for contact with handle in wparam
+
+[Service:StopSpam/RemoveTempContacts]
+alias=MS_STOPSPAM_REMTEMPCONTACTS
+wparam=0
+lparam=0
+return=int 0
+plugin=StopSpam (stopspam.dll)
+descr=remove all temporary contacts from db
+
+[Service:SV_Avatars/ContactOptions]
+alias=MS_AV_CONTACTOPTIONS
+wparam=hContact
+lparam=0
+plugin=Avatar service (loadavatars.dll)
+descr=Call avatar option dialog for contact
+
+[Service:SV_Avatars/SetAvatar]
+alias=MS_AV_SETAVATAR
+wparam=hContact
+lparam=0|Filename
+plugin=Avatar service (loadavatars.dll)
+descr=Set (and optionally protect) a local contact picture for the given hContact. If lParam = NIL, the service will open a file selection dialog.
+
+[Service:Update/CheckForUpdates]
+wparam=0
+lparam=0
+return=int 0
+plugin=Updater (updater.dll)
+descr=Check for plugin updates
+
+[Service:UserInfo/ShowDialog]
+alias=MS_USERINFO_SHOWDIALOG
+wparam=0 System|hContact
+lparam=0
+plugin=Extended UserInfo (uinfoex.dll)
+descr=Shows contact property window.
+
+[Service:Utils/OpenURL]
+alias=MS_UTILS_OPENURL
+wparam=0 Open URL in current window
+lparam=URL
+return=int 0
+descr=Open URL in default browser
+
+[Service:Versioninfo/GetInfo]
+alias=MS_VERSIONINFO_GETINFO
+wparam=0 With formating|1 Don't use formating
+lparam=structure|*b.ptr 0|
+plugin=VersionInfo
+return=int 0, if succesful
+descr=Returns a string containing the versioninfo post
+
+[Service:VersionInfo/MenuCommand]
+alias=MS_VERSIONINFO_MENU_COMMAND
+wparam=0
+lparam=0
+plugin=VersionInfo
+descr=Show or save (call default action) Modules version Info
+
+[Service:WATrack/ShowMusicInfo]
+alias=MS_WAT_SHOWMUSICINFO
+wparam=0
+lparam=0
+plugin=Winamp Track (watrack.dll)
+descr=Show popup or Info window with current music information.
+
+[Service:WATrack/MakeReport]
+alias=MS_WAT_MAKEREPORT
+wparam=log filename|
+lparam=report filename|
+return=int 0, if unsuccessful
+plugin=Winamp Track (watrack.dll)
+descr=Create report from log and run it (if option is set). If wParam or lParam is empty then file names from options are used.
+
+[Service:WhenWasIt/List/Show]
+alias=MS_WWI_LIST_SHOW
+wparam=0
+lparam=0
+plugin=WhenWasIt Birthday Reminder (whenwasit.dll)
+descr=display birthdays window
+
+[Service:<proto>/Bookmarks]
+wparam=0
+lparam=0
+plugin=Jabber
+descr=Manage Jabber Bookmarks
+
+[Service:<proto>/SetAwayMsg]
+alias=PS_SETAWAYMSG
+wparam=40071 Offline|40072 Online|40073 Away|40074 DND|40075 NA|40076 Occupied|40077 Free for Chat|40078 Invisible|40079 On the Phone|40080 Out to Lunch
+lparam=text
+return=int 0, if successful
+descr=Set status message
+
+[Service:<proto>/SetStatus]
+alias=PS_SETSTATUS
+wparam=40071 Offline|40072 Online|40073 Away|40074 DND|40075 NA|40076 Occupied|40077 Free for Chat|40078 Invisible|40079 On the Phone|40080 Out to Lunch
+lparam=0
+return=int 0, if successful
+descr=Set protocol status
+
+[Service:<proto>/SetXStatus]
+alias=PS_ICQ_SETCUSTOMSTATUS
+;alias=JS_SETXSTATUSEX
+wparam=0 None|1 Angry|2 Taking a bath|3 Tired|4 Party|5 Drinking beer|6 Thinking|7 Eating|8 Watching TV|9 Meeting|10 Coffee|11 Listening to music|12 Business|13 Shooting|14 Having fun|15 On the phone|16 Gaming|17 Studying|18 Shopping|19 Feeling sick|20 Sleeping|21 Surfing|22 Browsing|23 Working|24 Typing|25 Picnic|26 Cooking|27 Smoking|28 I'm high|29 On WC|30 To be or not to be|31 Watching pro7 on TV|32 Love
+lparam=0
+plugin=ICQ
+descr=Sets owner current custom status
+
+[Service:<proto>/ShowXStatusDetails]
+alias=MS_XSTATUS_SHOWDETAILS
+wparam=0|hContact
+lparam=0
+plugin=ICQ
+descr=Display XStatus detail
+
+[Event:Actions/Changed]
+alias=ME_ACT_CHANGED
+plugin=ActMan
+descr='action group list was changed: some was added or deleted'
+wparam=ACTM_NEW|ACTM_DELETE|ACTM_RELOAD|ACTM_RENAME|ACTM_SORT|ACTM_LOADED
+lparam=0
+
+[Event:CList/PreBuildContactMenu]
+alias=ME_CLIST_PREBUILDCONTACTMENU
+plugin=contact list
+descr='the context menu for a contact is about to be built'
+wparam=hContact
+lparam=0
+
+[Event:CList/DoubleClicked]
+alias=ME_CLIST_DOUBLECLICKED
+plugin=contact list
+descr='double click on the CList'
+wparam=hContact
+lparam=0
+
+[Event:DB/Contact/Added]
+alias=ME_DB_CONTACT_ADDED
+plugin=database driver
+descr='New contact added to database'
+wparam=hContact
+lparam=0
+
+[Event:DB/Contact/Deleted]
+alias=ME_DB_CONTACT_DELETED
+plugin=database driver
+descr='Contact deleting'
+wparam=hContact
+lparam=0
+
+[Structure:CCSDATA]
+; variant: Handle -> param
+full=0| \
+param (HANDLE) hContact| \
+b.ptr (const char *) szProtoService| \
+native (WPARAM) wParam| \
+native (LPARAM) lParam|
+short=0|param|b.ptr|native|native|
+descr=
+plugin=
diff --git a/plugins/Actman/tasks/i_opt_dlg.inc b/plugins/Actman/tasks/i_opt_dlg.inc
new file mode 100644
index 0000000000..c8025c278d
--- /dev/null
+++ b/plugins/Actman/tasks/i_opt_dlg.inc
@@ -0,0 +1,536 @@
+{}
+const
+ settings:HWND = 0;
+
+var
+ OldTableProc:pointer;
+ onactchanged:THANDLE;
+
+const
+ ACI_NEW :PAnsiChar = 'ACI_New';
+ ACI_DELETE :PAnsiChar = 'ACI_Delete';
+
+procedure CheckTaskList(Dialog:HWND;enable:boolean);
+begin
+ if not enable then
+ enable:=SendMessage(GetDlgItem(Dialog,IDC_TASK_NAME),LVM_GETITEMCOUNT,0,0)>0;
+
+ EnableWindow(GetDlgItem(Dialog,IDC_TASK_ABSOLUTE ),enable);
+ EnableWindow(GetDlgItem(Dialog,IDC_TASK_DATEV ),enable);
+ EnableWindow(GetDlgItem(Dialog,IDC_TASK_DAYSV ),enable);
+ EnableWindow(GetDlgItem(Dialog,IDC_TASK_TIMEV ),enable);
+ EnableWindow(GetDlgItem(Dialog,IDC_TASK_REPEAT ),enable);
+ EnableWindow(GetDlgItem(Dialog,IDC_TASK_INTERVAL ),enable);
+ EnableWindow(GetDlgItem(Dialog,IDC_TASK_BREAK ),enable);
+ EnableWindow(GetDlgItem(Dialog,IDC_TASK_EVENT ),enable);
+ EnableWindow(GetDlgItem(Dialog,IDC_TASK_ONCE ),enable);
+ if not enable then
+ begin
+ ShowWindow(GetDlgItem(Dialog,IDC_TASK_DAYST),SW_HIDE);
+ ShowWindow(GetDlgItem(Dialog,IDC_TASK_DAYSV),SW_HIDE);
+ end;
+end;
+
+procedure FillTaskList(wnd:HWND);
+var
+ i:integer;
+ li:LV_ITEMW;
+begin
+ SendMessage(wnd,LVM_DELETEALLITEMS,0,0);
+ for i:=0 to MaxTasks-1 do
+ begin
+ with TaskList[i] do
+ begin
+ if (flags and ACF_ASSIGNED)<>0 then
+ begin
+ li.mask :=LVIF_TEXT+LVIF_PARAM;
+ li.iSubItem:=0;
+ li.iItem :=i;
+ li.lParam :=i;
+ li.pszText :=name;
+ li.iItem :=SendMessageW(wnd,LVM_INSERTITEMW,0,LPARAM(@li));
+ ListView_SetCheckState(wnd,li.iItem,(flags and ACF_DISABLED)=0);
+ end;
+ end;
+ end;
+ ListView_SetItemState(wnd,0,
+ LVIS_FOCUSED or LVIS_SELECTED,
+ LVIS_FOCUSED or LVIS_SELECTED);
+end;
+
+procedure ClearTaskData(Dialog:HWND);
+var
+ st:TSystemTime;
+begin
+ SendMessage(GetDlgItem(Dialog,IDC_TASK_ABSOLUTE),CB_SETCURSEL,0,0);
+ CheckDlgButton(Dialog,IDC_TASK_BREAK ,BST_UNCHECKED);
+ CheckDlgButton(Dialog,IDC_TASK_EVENT ,BST_UNCHECKED);
+ CheckDlgButton(Dialog,IDC_TASK_ONCE ,BST_UNCHECKED);
+ EnableWindow(GetDlgItem(Dialog,IDC_TASK_ONCE),false);
+
+ SetDlgItemInt(Dialog,IDC_TASK_DAYSV ,1,false);
+ SetDlgItemInt(Dialog,IDC_TASK_REPEAT,0,false);
+
+ FillChar(st,SizeOf(st),0);
+ SendDlgItemMessage(Dialog,IDC_TASK_TIMEV ,DTM_SETSYSTEMTIME,GDT_VALID,lParam(@st));
+ SendDlgItemMessage(Dialog,IDC_TASK_INTERVAL,DTM_SETSYSTEMTIME,GDT_VALID,lParam(@st));
+{
+ ShowWindow(GetDlgItem(Dialog,IDC_TASK_DATET),SW_SHOW);
+ ShowWindow(GetDlgItem(Dialog,IDC_TASK_DATEV),SW_SHOW);
+ ShowWindow(GetDlgItem(Dialog,IDC_TASK_DAYST),SW_HIDE);
+ ShowWindow(GetDlgItem(Dialog,IDC_TASK_DAYSV),SW_HIDE);
+}
+end;
+
+procedure ShowDateType(Dialog:HWND;start:integer);
+var
+ sh1,sh2,sh3:integer;
+begin
+ case start of
+ 1: begin // start after
+ sh1:=SW_HIDE;
+ sh2:=SW_SHOW;
+ sh3:=SW_SHOW;
+ end;
+ 2: begin // start from
+ sh1:=SW_SHOW;
+ sh2:=SW_HIDE;
+ sh3:=SW_SHOW;
+ end;
+ else
+ begin
+// 3: begin // start immediately
+ sh1:=SW_HIDE;
+ sh2:=SW_HIDE;
+ sh3:=SW_HIDE;
+ end;
+ end;
+
+ ShowWindow(GetDlgItem(Dialog,IDC_TASK_DATET),sh1);
+ ShowWindow(GetDlgItem(Dialog,IDC_TASK_DATEV),sh1);
+ ShowWindow(GetDlgItem(Dialog,IDC_TASK_DAYST),sh2);
+ ShowWindow(GetDlgItem(Dialog,IDC_TASK_DAYSV),sh2);
+ ShowWindow(GetDlgItem(Dialog,IDC_TASK_TIMET),sh3);
+ ShowWindow(GetDlgItem(Dialog,IDC_TASK_TIMEV),sh3);
+end;
+
+procedure ShowTaskData(Dialog:HWND; item:integer=-1);
+var
+ st:TSystemTime;
+ lwnd:HWND;
+ start:integer;
+begin
+ lwnd:=settings;
+ settings:=0;
+
+ ClearTaskData(Dialog);
+
+ with TaskList[LV_GetLParam(GetDlgItem(Dialog,IDC_TASK_NAME),item)] do
+ begin
+ // flags
+
+ if (flags and TCF_NONZEROBREAK)<>0 then
+ CheckDlgButton(Dialog,IDC_TASK_BREAK,BST_CHECKED);
+ if (flags and TCF_MAKEEVENT)<>0 then
+ CheckDlgButton(Dialog,IDC_TASK_EVENT,BST_CHECKED);
+ if (flags and TCF_EVENTONCE)<>0 then
+ CheckDlgButton(Dialog,IDC_TASK_ONCE,BST_CHECKED);
+
+ EnableWindow(GetDlgItem(Dialog,IDC_TASK_ONCE),
+ IsDlgButtonChecked(Dialog,IDC_TASK_EVENT)<>BST_UNCHECKED);
+
+ // action
+ CB_SelectData(GetDlgItem(Dialog,IDC_TASK_ACTION),action);
+ // times
+ FileTimeToSystemTime(starttime,st);
+
+ if (flags and TCF_IMMEDIATELY)<>0 then
+ begin
+ start:=3;
+ end
+ else if (flags and TCF_ABSOLUTE)<>0 then
+ begin
+ start:=2;
+ SendDlgItemMessage(Dialog,IDC_TASK_DATEV,DTM_SETSYSTEMTIME,GDT_VALID,lParam(@st))
+ end
+ else
+ begin
+ start:=1;
+ SetDlgItemInt(Dialog,IDC_TASK_DAYSV,dayoffset,false);
+ end;
+ CB_SelectData(GetDlgItem(Dialog,IDC_TASK_ABSOLUTE),start);
+
+ SendDlgItemMessage(Dialog,IDC_TASK_TIMEV,DTM_SETSYSTEMTIME,GDT_VALID,lParam(@st));
+
+ SetDlgItemInt(Dialog,IDC_TASK_REPEAT,count,true);
+
+ FileTimeToSystemTime(interval,st);
+ SendDlgItemMessage(Dialog,IDC_TASK_INTERVAL,DTM_SETSYSTEMTIME,GDT_VALID,lParam(@st));
+ SetDlgItemInt(Dialog,IDC_TASK_INTDAYS,intdays,false);
+ end;
+
+ ShowDateType(Dialog,start);
+
+ settings:=lwnd;
+end;
+
+procedure SaveTaskData(Dialog:HWND; item:integer=-1);
+var
+ wnd:HWND;
+ li:LV_ITEM;
+ st,st1:TSystemTime;
+ tmp:longbool;
+begin
+ wnd:=GetDlgItem(Dialog,IDC_TASK_NAME);
+
+ if item<0 then
+ li.iItem:=SendMessage(wnd,LVM_GETNEXTITEM,-1,LVNI_FOCUSED) // LVNI_SELECTED
+ else
+ li.iItem:=item;
+
+ if li.iItem>=0 then
+ begin
+ li.mask :=LVIF_PARAM;
+ li.iSubItem :=0;
+ SendMessageW(wnd,LVM_GETITEMW,0,LPARAM(@li));
+
+ with TaskList[li.lParam] do
+ begin
+ if (flags and ACF_ASSIGNED)<>0 then
+ begin
+ flags:=ACF_ASSIGNED;
+ // flags
+ if ListView_GetCheckState(wnd,li.iItem)=0 then
+ flags:=flags or ACF_DISABLED;
+
+ if IsDlgButtonChecked(Dialog,IDC_TASK_BREAK)<>BST_UNCHECKED then
+ flags:=flags or TCF_NONZEROBREAK;
+ if IsDlgButtonChecked(Dialog,IDC_TASK_EVENT)<>BST_UNCHECKED then
+ begin
+ flags:=flags or TCF_MAKEEVENT;
+ if IsDlgButtonChecked(Dialog,IDC_TASK_ONCE )<>BST_UNCHECKED then
+ flags:=flags or TCF_EVENTONCE;
+ end;
+ // action
+ action:=CB_GetData(GetDlgItem(Dialog,IDC_TASK_ACTION));
+ // times
+ SendDlgItemMessage(Dialog,IDC_TASK_TIMEV,DTM_GETSYSTEMTIME,0,lParam(@st));
+
+ case CB_GetData(GetDlgItem(Dialog,IDC_TASK_ABSOLUTE)) of
+ 1: begin
+ dayoffset:=GetDlgItemInt(Dialog,IDC_TASK_DAYSV,tmp,false);
+ end;
+ 2: begin
+ flags:=flags or TCF_ABSOLUTE;
+ SendDlgItemMessage(Dialog,IDC_TASK_DATEV,DTM_GETSYSTEMTIME,0,lParam(@st1));
+ st.wYear :=st1.wYear;
+ st.wMonth :=st1.wMonth;
+ st.wDayOfWeek:=st1.wDayOfWeek;
+ st.wDay :=st1.wDay;
+ end;
+ 3: begin
+ flags:=flags or TCF_IMMEDIATELY;
+ end;
+ end;
+ SystemTimeToFileTime(st,starttime);
+
+ count:=GetDlgItemInt(Dialog,IDC_TASK_REPEAT,tmp,true);
+
+ SendDlgItemMessage(Dialog,IDC_TASK_INTERVAL,DTM_GETSYSTEMTIME,0,lParam(@st));
+ SystemTimeToFileTime(st,interval);
+ intdays:=GetDlgItemInt(Dialog,IDC_TASK_INTDAYS,tmp,false);
+ end;
+ end;
+ end;
+end;
+
+function NewTask(Dialog:HWND;item:integer=-1):integer;
+var
+ wnd:HWND;
+ li:LV_ITEMW;
+begin
+ wnd:=GetDlgItem(Dialog,IDC_TASK_NAME);
+ if item<0 then
+ li.iItem :=SendMessage(wnd,LVM_GETNEXTITEM,-1,LVNI_FOCUSED)+1
+ else
+ li.iItem :=item;
+ li.iSubItem:=0;
+ li.mask :=LVIF_TEXT + LVIF_PARAM;
+ li.lParam :=CreateNewTask;
+ li.pszText :=TranslateW('Task sample');
+ result:=SendMessageW(wnd,LVM_INSERTITEMW,0,LPARAM(@li));
+
+ ListView_SetCheckState(wnd,li.iItem,
+ (TaskList[li.lParam].flags and ACF_DISABLED)=0);
+ StrDupW(TaskList[li.lParam].name,li.pszText);
+
+ CheckTaskList(Dialog,true);
+
+ if li.iItem=0 then
+ Listview_SetItemState(wnd,0,LVIS_FOCUSED or LVIS_SELECTED,
+ LVIS_FOCUSED or LVIS_SELECTED);
+end;
+
+function DeleteTask(Dialog:HWND):integer;
+var
+ li:LV_ITEM;
+ wnd:HWND;
+ i:integer;
+begin
+ result:=0;
+ wnd:=GetDlgItem(Dialog,IDC_TASK_NAME);
+ for i:=ListView_GetItemCount(wnd)-1 downto 0 do
+ begin
+ if ListView_GetItemState(wnd,i,LVIS_SELECTED)<>0 then
+ begin
+ li.iItem :=i;
+ li.mask :=LVIF_PARAM;
+ li.iSubItem :=0;
+ SendMessageW(wnd,LVM_GETITEMW,0,LPARAM(@li));
+
+ TaskList[li.lParam].flags:=TaskList[li.lParam].flags and not ACF_ASSIGNED;
+
+ SendMessage(wnd,LVM_DELETEITEM,i,0);
+ end;
+ end;
+ Listview_SetItemState(wnd,0,LVIS_FOCUSED or LVIS_SELECTED,
+ LVIS_FOCUSED or LVIS_SELECTED);
+
+ CheckTaskList(Dialog,false);
+end;
+
+function NewHKTableProc(Dialog:HWnd;hMessage:UINT;wParam:WPARAM;lParam:LPARAM):lresult; stdcall;
+var
+ i:integer;
+begin
+ result:=0;
+ case hMessage of
+ WM_KEYDOWN: begin
+ if (lParam and (1 shl 30))=0 then
+ begin
+ case wParam of
+ VK_F2: begin
+ i:=SendMessage(Dialog,LVM_GETNEXTITEM,-1,LVNI_FOCUSED);
+ if i>=0 then
+ PostMessageW(Dialog,LVM_EDITLABELW,i,0);
+ exit;
+ end;
+
+ VK_INSERT: begin
+ PostMessage(GetParent(Dialog),WM_COMMAND,(BN_CLICKED shl 16)+IDC_TASK_NEW,0);
+ exit;
+ end;
+
+ VK_DELETE: begin
+ PostMessage(GetParent(Dialog),WM_COMMAND,(BN_CLICKED shl 16)+IDC_TASK_DELETE,0);
+ exit;
+ end;
+ end;
+ end;
+ end;
+ end;
+ result:=CallWindowProc(OldTableProc,Dialog,hMessage,wParam,lParam);
+end;
+
+procedure FillStartTimeList(wnd:HWND);
+begin
+ SendMessage(wnd,CB_RESETCONTENT,0,0);
+ CB_AddStrDataW(wnd,TranslateW('Starting after' ),1);
+ CB_AddStrDataW(wnd,TranslateW('Starting from' ),2);
+ CB_AddStrDataW(wnd,TranslateW('Start immediately'),3);
+ SendMessage(wnd,CB_SETCURSEL,0,0);
+end;
+
+procedure FillActionList(wnd:HWND);
+var
+ ptr,ptr1:pChain;
+ i,cnt:integer;
+begin
+ cnt:=CallService(MS_ACT_GETLIST,0,LPARAM(@ptr));
+ SendMessage(wnd,CB_RESETCONTENT,0,0);
+ if cnt>0 then
+ begin
+ ptr1:=ptr;
+ inc(pbyte(ptr),4);
+ for i:=0 to cnt-1 do
+ begin
+ CB_AddStrDataW(wnd,ptr^.descr,ptr^.id);
+ inc(ptr);
+ end;
+
+ CallService(MS_ACT_FREELIST,0,LPARAM(ptr1));
+ SendMessage(wnd,CB_SETCURSEL,0,0);
+ end;
+end;
+
+function ActListChange(wParam:WPARAM;lParam:LPARAM):integer; cdecl;
+begin
+ result:=0;
+ if settings<>0 then
+ FillActionList(GetDlgItem(settings,IDC_TASK_ACTION));
+end;
+
+procedure SetIcons(Dialog:HWND);
+var
+ ti:TTOOLINFOW;
+ hwndTooltip:HWND;
+begin
+ hwndTooltip:=CreateWindowW(TOOLTIPS_CLASS,nil,TTS_ALWAYSTIP,
+ integer(CW_USEDEFAULT),integer(CW_USEDEFAULT),
+ integer(CW_USEDEFAULT),integer(CW_USEDEFAULT),
+ Dialog,0,hInstance,nil);
+
+ FillChar(ti,SizeOf(ti),0);
+ ti.cbSize :=sizeof(TOOLINFO);
+ ti.uFlags :=TTF_IDISHWND or TTF_SUBCLASS;
+ ti.hwnd :=dialog;
+ ti.hinst :=hInstance;
+{
+ ti.uId :=GetDlgItem(Dialog,IDC_EVENT_HELP);
+ ti.lpszText:=TranslateW('Help');
+ SendMessage(ti.uId,BM_SETIMAGE,IMAGE_ICON,
+ CallService(MS_SKIN_LOADICON,SKINICON_OTHER_HELP,0));
+ SendMessageW(hwndTooltip,TTM_ADDTOOLW,0,LPARAM(@ti));
+}
+ ti.uId :=GetDlgItem(Dialog,IDC_TASK_NEW);
+ ti.lpszText:=TranslateW('New');
+ SetButtonIcon(ti.uId,ACI_NEW);
+ SendMessageW(hwndTooltip,TTM_ADDTOOLW,0,LPARAM(@ti));
+
+ ti.uId :=GetDlgItem(Dialog,IDC_TASK_DELETE);
+ ti.lpszText:=TranslateW('Delete');
+ SetButtonIcon(ti.uId,ACI_DELETE);
+ SendMessageW(hwndTooltip,TTM_ADDTOOLW,0,LPARAM(@ti));
+end;
+
+function DlgProcOpt(Dialog:HWnd;hMessage:UINT;wParam:WPARAM;lParam:LPARAM):lresult; stdcall;
+var
+ wnd:HWND;
+ lv:LV_COLUMNW;
+ li:LV_ITEMW;
+ i:integer;
+begin
+ result:=0;
+ case hMessage of
+ WM_CLOSE: begin
+ UnhookEvent(onactchanged);
+ settings:=0;
+ end;
+
+ WM_INITDIALOG: begin
+ settings:=0;
+ wnd:=GetDlgItem(Dialog,IDC_TASK_NAME);
+ SendMessage(wnd,LVM_SETEXTENDEDLISTVIEWSTYLE,LVS_EX_CHECKBOXES,LVS_EX_CHECKBOXES);
+ SendMessage(wnd,LVM_SETUNICODEFORMAT,1,0);
+ zeromemory(@lv,sizeof(lv));
+ lv.mask:=LVCF_WIDTH;
+ lv.cx :=110;
+ SendMessageW(wnd,LVM_INSERTCOLUMNW ,0,tlparam(@lv));
+ SendMessageW(wnd,LVM_SETCOLUMNWIDTH,0,LVSCW_AUTOSIZE_USEHEADER);
+
+ CreateUpDownControl(
+ WS_CHILD+WS_BORDER+WS_VISIBLE+UDS_ARROWKEYS+UDS_SETBUDDYINT+UDS_ALIGNRIGHT,
+ 190,112,14,18,
+ Dialog, IDC_TASK_UPDOWN, hInstance, GetDlgItem(Dialog,IDC_TASK_REPEAT),
+ 10000, -1, 0);
+
+ OldTableProc:=pointer(SetWindowLongPtrW(wnd,GWL_WNDPROC,LONG_PTR(@NewHKTableProc)));
+ TranslateDialogDefault(Dialog);
+
+ SetIcons(Dialog);
+
+ FillActionList(GetDlgItem(Dialog,IDC_TASK_ACTION));
+ FillStartTimeList(GetDlgItem(Dialog,IDC_TASK_ABSOLUTE));
+ FillTaskList(wnd);
+ CheckTaskList(Dialog,false);
+ onactchanged:=HookEvent(ME_ACT_CHANGED,@ActListChange);
+ settings:=Dialog;
+ end;
+
+ WM_COMMAND: begin
+ case wParam shr 16 of
+ CBN_SELCHANGE: begin
+ ShowDateType(Dialog,CB_GetData(lParam));
+ end;
+
+ EN_CHANGE: begin
+ end;
+
+ BN_CLICKED: begin
+ case loword(wParam) of
+ IDC_TASK_NEW : NewTask(Dialog);
+ IDC_TASK_DELETE: DeleteTask(Dialog);
+
+ IDC_TASK_EVENT: begin
+ EnableWindow(GetDlgItem(Dialog,IDC_TASK_ONCE),
+ IsDlgButtonChecked(Dialog,IDC_TASK_EVENT)<>BST_UNCHECKED);
+ end;
+ end;
+ end;
+ end;
+ if settings<>0 then
+ SendMessage(GetParent(Dialog),PSM_CHANGED,0,0);
+ end;
+
+ WM_NOTIFY: begin
+ case integer(PNMHdr(lParam)^.code) of
+ PSN_APPLY: begin
+ SaveTaskData(Dialog);
+ SaveTasks;
+ SetAllTasks;
+ end;
+
+ DTN_DATETIMECHANGE: begin
+ if settings<>0 then
+ SendMessage(GetParent(Dialog),PSM_CHANGED,0,0);
+ end;
+
+ NM_DBLCLK: begin
+ if PNMListView(lParam)^.iItem>=0 then
+ PostMessageW(PNMHdr(lParam)^.hWndFrom,LVM_EDITLABELW,
+ PNMListView(lParam)^.iItem,0);
+ end;
+
+ LVN_ITEMCHANGED: begin
+ if PNMLISTVIEW(lParam)^.uChanged=LVIF_STATE then
+ begin
+ i:=(PNMLISTVIEW(lParam)^.uOldState and LVNI_FOCUSED)-
+ (PNMLISTVIEW(lParam)^.uNewState and LVNI_FOCUSED);
+
+ if i>0 then // old focus
+ SaveTaskData(Dialog,PNMLISTVIEW(lParam)^.iItem)
+ else if i<0 then // new focus
+ begin
+ ShowTaskData(Dialog,PNMLISTVIEW(lParam)^.iItem);
+ end
+ else if (settings<>0) and
+ ((PNMLISTVIEW(lParam)^.uOldState or PNMLISTVIEW(lParam)^.uNewState)=$3000) then
+ SendMessage(GetParent(Dialog),PSM_CHANGED,0,0);
+ end;
+ end;
+
+ LVN_ENDLABELEDITW: begin
+ with PLVDISPINFOW(lParam)^ do
+ begin
+ if item.pszText<>nil then
+ begin
+ item.mask:=LVIF_TEXT;
+ SendMessageW(hdr.hWndFrom,LVM_SETITEMW,0,TLPARAM(@item));
+
+ li.iItem :=item.iItem;
+ li.mask :=LVIF_PARAM;
+ li.iSubItem :=0;
+ SendMessageW(hdr.hWndFrom,LVM_GETITEMW,0,TLPARAM(@li));
+ with TaskList[li.lParam] do
+ begin
+ mFreeMem(name);
+ StrDupW (name,item.pszText);
+ end;
+ end;
+ end;
+ result:=1;
+ end;
+ end;
+ end;
+ end;
+end;
diff --git a/plugins/Actman/tasks/i_options.inc b/plugins/Actman/tasks/i_options.inc
new file mode 100644
index 0000000000..527e8d0c88
--- /dev/null
+++ b/plugins/Actman/tasks/i_options.inc
@@ -0,0 +1,99 @@
+{}
+const
+ opt_task :PAnsiChar = 'Task';
+ opt_tasks :PAnsiChar = 'Tasks';
+ opt_count :PAnsiChar = 'numtasks';
+
+ opt_name :PAnsiChar = 'name';
+ opt_flags :PAnsiChar = 'flags';
+ opt_action :PAnsiChar = 'action';
+ opt_repeat :PAnsiChar = 'repeat';
+ opt_days :PAnsiChar = 'dayoffset';
+ opt_intdays :PAnsiChar = 'intdays';
+
+ opt_time_lo :PAnsiChar = 'starttime_lo';
+ opt_time_hi :PAnsiChar = 'starttime_hi';
+ opt_interval_lo:PAnsiChar = 'interval_lo';
+ opt_interval_hi:PAnsiChar = 'interval_hi';
+ opt_lastcall_lo:PAnsiChar = 'lastcall_lo';
+ opt_lastcall_hi:PAnsiChar = 'lastcall_hi';
+
+procedure SaveTasks;
+var
+ section:array [0..63] of AnsiChar;
+ p,p1:PAnsiChar;
+ i,amount:integer;
+begin
+ DBDeleteGroup(0,DBBranch,opt_tasks);
+ amount:=0;
+ p1:=StrCopyE(section,opt_tasks);
+ p1^:='/'; inc(p1);
+ p1:=StrCopyE(p1,opt_task);
+ for i:=0 to MaxTasks-1 do
+ begin
+ if (TaskList[i].flags and ACF_ASSIGNED)=0 then
+ continue;
+
+ p:=StrEnd(IntToStr(p1,amount));
+ p^:='/'; inc(p);
+ with TaskList[i] do
+ begin
+ StrCopy(p,opt_flags ); DBWriteDWord (0,DBBranch,section,flags);
+ StrCopy(p,opt_name ); DBWriteUnicode(0,DBBranch,section,name);
+ StrCopy(p,opt_action); DBWriteDWord (0,DBBranch,section,action);
+ StrCopy(p,opt_repeat); DBWriteWord (0,DBBranch,section,count);
+ StrCopy(p,opt_days ); DBWriteByte (0,DBBranch,section,dayoffset);
+ //systemtime to filetime if needs
+ StrCopy(p,opt_time_lo ); DBWriteDWord(0,DBBranch,section,starttime.dwLowDateTime);
+ StrCopy(p,opt_time_hi ); DBWriteDWord(0,DBBranch,section,starttime.dwHighDateTime);
+ StrCopy(p,opt_interval_lo); DBWriteDWord(0,DBBranch,section,interval .dwLowDateTime);
+ StrCopy(p,opt_interval_hi); DBWriteDWord(0,DBBranch,section,interval .dwHighDateTime);
+ StrCopy(p,opt_intdays ); DBWriteByte (0,DBBranch,section,intdays);
+ StrCopy(p,opt_lastcall_lo); DBWriteDWord(0,DBBranch,section,lastcall .dwLowDateTime);
+ StrCopy(p,opt_lastcall_hi); DBWriteDWord(0,DBBranch,section,lastcall .dwHighDateTime);
+ end;
+ inc(amount);
+ end;
+ DBWriteByte(0,DBBranch,opt_count,amount);
+end;
+
+function LoadTasks:integer;
+var
+ section:array [0..63] of AnsiChar;
+ p,p1:PAnsiChar;
+ i:integer;
+begin
+ MaxTasks:=DBReadByte(0,DBBranch,opt_count);
+ result:=MaxTasks;
+ if MaxTasks>0 then
+ begin
+ GetMem (TaskList ,MaxTasks*SizeOf(tTaskRec));
+ FillChar(TaskList^,MaxTasks*SizeOf(tTaskRec),0);
+ p1:=StrCopyE(section,opt_tasks);
+ p1^:='/'; inc(p1);
+ p1:=StrCopyE(p1,opt_task);
+ for i:=0 to MaxTasks-1 do
+ begin
+ p:=StrEnd(IntToStr(p1,i));
+ p^:='/'; inc(p);
+
+ with TaskList[i] do
+ begin
+ StrCopy(p,opt_flags ); flags :=DBReadDWord (0,DBBranch,section);
+ StrCopy(p,opt_name ); name :=DBReadUnicode(0,DBBranch,section);
+ StrCopy(p,opt_action); action :=DBReadDWord (0,DBBranch,section);
+ StrCopy(p,opt_days ); dayoffset:=DBReadByte (0,DBBranch,section);
+ StrCopy(p,opt_repeat); count :=Shortint(DBReadWord(0,DBBranch,section));
+
+ StrCopy(p,opt_time_lo ); starttime.dwLowDateTime :=DBReadDWord(0,DBBranch,section);
+ StrCopy(p,opt_time_hi ); starttime.dwHighDateTime:=DBReadDWord(0,DBBranch,section);
+ StrCopy(p,opt_interval_lo); interval .dwLowDateTime :=DBReadDWord(0,DBBranch,section);
+ StrCopy(p,opt_interval_hi); interval .dwHighDateTime:=DBReadDWord(0,DBBranch,section);
+ StrCopy(p,opt_intdays ); intdays:=DBReadByte(0,DBBranch,section);
+ StrCopy(p,opt_lastcall_lo); lastcall .dwLowDateTime :=DBReadDWord(0,DBBranch,section);
+ StrCopy(p,opt_lastcall_hi); lastcall .dwHighDateTime:=DBReadDWord(0,DBBranch,section);
+ // filetime to systemtime if needs
+ end;
+ end;
+ end;
+end;
diff --git a/plugins/Actman/tasks/i_service.inc b/plugins/Actman/tasks/i_service.inc
new file mode 100644
index 0000000000..376e75cba0
--- /dev/null
+++ b/plugins/Actman/tasks/i_service.inc
@@ -0,0 +1,87 @@
+{}
+// wParam: 1/0 (enable/disable), lParam = task name
+// works for all tasks with same started name
+function TaskEnable(wParam:WPARAM;lParam:LPARAM):int_ptr;cdecl;
+var
+ i,j:integer;
+begin
+ result:=0;
+ if lParam=0 then exit;
+ j:=StrLenW(pWideChar(lParam));
+
+ for i:=0 to MaxTasks-1 do
+ begin
+ if (TaskList[i].flags and ACF_ASSIGNED)<>0 then
+ begin
+ if StrCmpW(TaskList[i].name,pWideChar(lParam),j)=0 then
+ begin
+ if wParam=0 then // disable
+ begin
+ if (TaskList[i].flags and ACF_DISABLED)=0 then
+ begin
+ inc(result);
+ TaskList[i].flags:=TaskList[i].flags or ACF_DISABLED;
+ if TaskList[i].timer<>0 then
+ begin
+ KillTimer(0,TaskList[i].timer);
+ TaskList[i].timer:=0;
+ end;
+ end;
+ end
+ else
+ begin
+ if (TaskList[i].flags and ACF_DISABLED)<>0 then
+ begin
+ inc(result);
+ TaskList[i].flags:=TaskList[i].flags and not ACF_DISABLED;
+ SetTask(TaskList[i]);
+ end;
+ end;
+ end;
+ end;
+ end;
+end;
+
+function TaskDelete(wParam:WPARAM;lParam:LPARAM):int_ptr;cdecl;
+var
+ i,j:integer;
+begin
+ result:=0;
+ if lParam=0 then exit;
+ j:=StrLenW(pWideChar(lParam));
+
+ for i:=0 to MaxTasks-1 do
+ begin
+ if (TaskList[i].flags and ACF_ASSIGNED)<>0 then
+ begin
+ if StrCmpW(TaskList[i].name,pWideChar(lParam),j)=0 then
+ begin
+ TaskList[i].flags:=TaskList[i].flags and not ACF_ASSIGNED;
+ end;
+ end;
+ end;
+end;
+
+function TaskCount(wParam:WPARAM;lParam:LPARAM):int_ptr;cdecl;
+var
+ i,j:integer;
+begin
+ result:=0;
+ if lParam=0 then exit;
+ j:=StrLenW(pWideChar(lParam));
+
+ for i:=0 to MaxTasks-1 do
+ begin
+ with TaskList[i] do
+ begin
+ if (flags and ACF_ASSIGNED)<>0 then
+ begin
+ if StrCmpW(name,pWideChar(lParam),j)=0 then
+ begin
+ result:=count;
+ count:=wParam;
+ end;
+ end;
+ end;
+ end;
+end;
diff --git a/plugins/Actman/tasks/i_task.inc b/plugins/Actman/tasks/i_task.inc
new file mode 100644
index 0000000000..2c860db85f
--- /dev/null
+++ b/plugins/Actman/tasks/i_task.inc
@@ -0,0 +1,242 @@
+{}
+const
+ ACF_ASSIGNED = $80000000; // Task assigned
+ ACF_DISABLED = $10000000; // Task disabled
+
+ TCF_ABSOLUTE = $00000001;
+ TCF_IMMEDIATELY = $00000002;
+ TCF_NONZEROBREAK = $00000004;
+ TCF_MAKEEVENT = $00000008;
+ TCF_EVENTONCE = $00000010;
+
+const
+ WM_RESETTASKS = WM_USER+1312;
+ WM_FIRSTTASK = WM_USER+1313;
+ WM_LASTTASK = WM_FIRSTTASK+1000;
+
+type
+ pTaskRec = ^tTaskRec;
+ tTaskRec = record
+ // option values
+ flags :dword;
+ name :PWideChar; // name for task
+ action :dword; // assigned action
+ intdays, // interval,days
+ dayoffset :integer; //!! offset, days
+ starttime, // task starttime
+ interval :TFileTime; // interval for repeat
+ count :integer; // repeat count
+ // support values
+ lastcall :TFileTime; // last timer event time
+ nextcall :TFileTime; // ?? next start time?
+ // runtime values
+ timer :uint_ptr; // timer handle
+ curcount :integer; // repeat count
+ inprocess :bool; // starting processing
+ inaction :bool; // timer event processing
+ end;
+ pTaskList = ^tTaskList;
+ tTaskList = array [0..1023] of tTaskRec;
+
+var
+ TaskList:pTaskList = nil;
+ MaxTasks:integer = 0;
+
+procedure TimerProc(wnd:HWND;uMsg:uint;idEvent:uint_ptr;dwTime:dword); stdcall;
+var
+ ltime:uint;
+ i:integer;
+ res:int_ptr;
+ st:tSystemTime;
+begin
+ for i:=0 to MaxTasks-1 do
+ begin
+ with TaskList[i] do
+ begin
+ if (flags and (ACF_ASSIGNED or ACF_DISABLED))=ACF_ASSIGNED then
+ if timer=idEvent then
+ begin
+ inaction:=true;
+ if ((flags and TCF_MAKEEVENT)<>0) and
+ (((flags and TCF_EVENTONCE) =0) or (curcount=count)) then
+ NotifyEventHooks(hevent,count-curcount,lParam(name));
+
+ GetLocalTime(st);
+ SystemTimeToFileTime(st,lastcall);
+
+ res:=CallService(MS_ACT_RUNBYID,action,0);
+
+ if ((res<>0) and ((flags and TCF_NONZEROBREAK)<>0)) or // non-zero result
+ (count=0) or (curcount=0) then // no need to repeat or all repeats done
+ begin
+ KillTimer(0,idEvent);
+ timer:=0;
+ flags:=flags or ACF_DISABLED;
+ end
+ else
+ begin
+ if (count<>0) and (count=curcount) then // next timer - repeat interval
+ begin
+ KillTimer(0,idEvent);
+ FileTimeToSystemTime(interval,st);
+ ltime:={st.wMilliseconds+}st.wSecond*1000+st.wMinute*1000*60+st.wHour*60*60*1000;
+ timer:=SetTimer(0,0,ltime,@TimerProc);
+ if count=-1 then
+ curcount:=1;
+ end;
+ if count>0 then
+ dec(curcount);
+ end;
+ inaction:=false;
+ break;
+ end;
+ end;
+ end;
+end;
+
+procedure SetTask(var task:tTaskRec);
+var
+ ltime:uint;
+ uli1,uli2:ULARGE_INTEGER;
+ sft:tFileTime;
+ st:tSystemTime;
+ dif:int64;
+begin
+ task.inprocess:=true;
+ // Check task time
+ if (task.flags and TCF_IMMEDIATELY)<>0 then
+ begin
+ FileTimeToSystemTime(task.interval,st);
+ ltime:={st.wMilliseconds+}st.wSecond*1000+st.wMinute*1000*60+
+ st.wHour*60*60*1000;
+ end
+ else if (task.flags and TCF_ABSOLUTE)<>0 then
+ begin
+ uli1.LowPart :=task.starttime.dwLowDateTime;
+ uli1.HighPart:=task.starttime.dwHighDateTime;
+ GetLocalTime(st);
+ SystemTimeToFileTime(st,sft);
+ uli2.LowPart :=sft.dwLowDateTime;
+ uli2.HighPart:=sft.dwHighDateTime;
+ dif:=uli1.QuadPart-uli2.QuadPart;
+ if dif>0 then // time in future
+ ltime:=dif div 10000 // 100ns to 1 ms
+ else // was in past
+ begin
+ task.flags:=task.flags or ACF_DISABLED;
+ exit;
+ end;
+ end
+ else
+ begin
+ // days+hours+minutes+seconds+millseconds
+ FileTimeToSystemTime(task.starttime,st);
+ ltime:={st.wMilliseconds+}st.wSecond*1000+st.wMinute*1000*60+
+ st.wHour*60*60*1000+task.dayoffset*24*60*60*1000;
+ end;
+ // set timer
+ task.curcount:=task.count;
+ task.timer :=SetTimer(0,0,ltime,@TimerProc);
+
+ if (task.flags and TCF_IMMEDIATELY)<>0 then
+ TimerProc(0,WM_TIMER,task.timer,0);
+ task.inprocess:=false;
+end;
+
+procedure SetAllTasks;
+var
+ i:integer;
+begin
+ for i:=0 to MaxTasks-1 do
+ begin
+ if (TaskList[i].flags and ACF_ASSIGNED)<>0 then
+ begin
+ if (TaskList[i].flags and ACF_DISABLED)=0 then
+ SetTask(TaskList[i])
+ else if TaskList[i].timer<>0 then
+ begin
+ KillTimer(0,TaskList[i].timer);
+ TaskList[i].timer:=0;
+ end;
+ end;
+ end;
+end;
+
+procedure StopAllTasks;
+var
+ i:integer;
+begin
+ for i:=0 to MaxTasks-1 do
+ begin
+ if (TaskList[i].flags and (ACF_ASSIGNED or ACF_DISABLED))=ACF_ASSIGNED then
+ if TaskList[i].timer<>0 then
+ begin
+ KillTimer(0,TaskList[i].timer);
+ TaskList[i].timer:=0;
+ end;
+ end;
+end;
+
+procedure ClearTasks;
+var
+ i:integer;
+begin
+ for i:=0 to MaxTasks-1 do
+ begin
+ with TaskList[i] do
+ begin
+//!! if (flags and ACF_ASSIGNED)<>0 then
+ mFreeMem(name);
+ end;
+ end;
+ FreeMem(TaskList);
+ MaxTasks:=0;
+end;
+
+function CreateNewTask:integer;
+var
+ i:integer;
+ tmp:pTaskList;
+ st:tSystemTime;
+begin
+ result:=-1;
+ // if list is not empty, search for hole
+ if MaxTasks>0 then
+ begin
+ for i:=0 to MaxTasks-1 do
+ begin
+ if (TaskList[i].flags and ACF_ASSIGNED)=0 then
+ begin
+ FillChar(TaskList[i],SizeOf(tTaskRec),0);
+ result:=i;
+ break;
+ end;
+ end;
+ end;
+ if result<0 then
+ begin
+ // not found or empty list
+ i:=(MaxTasks+16)*SizeOf(tTaskRec);
+ GetMem (tmp ,i);
+ FillChar(tmp^,i,0);
+ if MaxTasks>0 then
+ begin
+ move(TaskList^,tmp^,MaxTasks*SizeOf(tTaskRec));
+ FreeMem(TaskList);
+ end;
+ TaskList:=tmp;
+ result:=MaxTasks;
+ inc(MaxTasks,16);
+ end;
+ with TaskList^[result] do
+ begin
+ flags:=flags or ACF_ASSIGNED or ACF_DISABLED or TCF_ABSOLUTE;
+ GetLocalTime(st);
+ SystemTimeToFileTime(st,starttime);
+ //!!! CHEAT
+ st.wHour :=0;
+ st.wMinute:=0;
+ st.wSecond:=1;
+ SystemTimeToFileTime(st,interval);
+ end;
+end;
diff --git a/plugins/Actman/tasks/i_tconst.inc b/plugins/Actman/tasks/i_tconst.inc
new file mode 100644
index 0000000000..f4df810d32
--- /dev/null
+++ b/plugins/Actman/tasks/i_tconst.inc
@@ -0,0 +1,27 @@
+{resource constants}
+const
+ IDD_TASKS = 2030;
+
+ IDC_TASK_NAME = 1025;
+
+ IDC_TASK_DATET = 1026;
+ IDC_TASK_DATEV = 1027;
+ IDC_TASK_DAYST = 1028;
+ IDC_TASK_DAYSV = 1029;
+ IDC_TASK_TIMET = 1030;
+ IDC_TASK_TIMEV = 1031;
+
+ IDC_TASK_REPEAT = 1032;
+ IDC_TASK_BREAK = 1034;
+ IDC_TASK_INTERVAL = 1035;
+ IDC_TASK_EVENT = 1036;
+ IDC_TASK_ONCE = 1037;
+ IDC_TASK_UPDOWN = 1038;
+ IDC_TASK_ABSOLUTE = 1039;
+
+ IDC_TASK_ACTION = 1040;
+
+ IDC_TASK_INTDAYS = 1041;
+
+ IDC_TASK_NEW = 1050;
+ IDC_TASK_DELETE = 1051;
diff --git a/plugins/Actman/tasks/scheduler.pas b/plugins/Actman/tasks/scheduler.pas
new file mode 100644
index 0000000000..05e9cb6a58
--- /dev/null
+++ b/plugins/Actman/tasks/scheduler.pas
@@ -0,0 +1,86 @@
+unit scheduler;
+
+interface
+
+procedure Init;
+procedure DeInit;
+function AddOptionPage(var tmpl:pAnsiChar;var proc:pointer;var name:PAnsiChar):integer;
+
+implementation
+
+uses
+ windows, commctrl, messages,
+ mirutils, common, dbsettings, io, m_api, wrapper,
+ global;
+
+{$R tasks.res}
+
+{$include m_actman.inc}
+
+var
+ hevent: THANDLE;
+
+{$include i_task.inc}
+{$include i_tconst.inc}
+{$include i_options.inc}
+{$include i_opt_dlg.inc}
+{$include i_service.inc}
+
+// ------------ base interface functions -------------
+
+var
+ hendis,
+ hcount,
+ hdel: THANDLE;
+
+procedure Init;
+begin
+
+ if LoadTasks=0 then
+ begin
+ MaxTasks:=8;
+ GetMem (TaskList ,MaxTasks*SizeOf(tTaskRec));
+ FillChar(TaskList^,MaxTasks*SizeOf(tTaskRec),0);
+ end
+ else
+ SetAllTasks;
+
+ hcount:=CreateServiceFunction(MS_ACT_TASKCOUNT ,@TaskCount);
+ hendis:=CreateServiceFunction(MS_ACT_TASKENABLE,@TaskEnable);
+ hdel :=CreateServiceFunction(MS_ACT_TASKDELETE,@TaskDelete);
+ hevent:=CreateHookableEvent(ME_ACT_BELL);
+
+end;
+
+procedure DeInit;
+begin
+ StopAllTasks;
+ DestroyServiceFunction(hendis);
+ DestroyServiceFunction(hdel);
+ DestroyServiceFunction(hcount);
+ ClearTasks;
+end;
+
+function AddOptionPage(var tmpl:pAnsiChar;var proc:pointer;var name:PAnsiChar):integer;
+begin
+ result:=0;
+ tmpl:=PAnsiChar(IDD_TASKS);
+ proc:=@DlgProcOpt;
+ name:='Scheduler';
+end;
+
+var
+ amLink:tActionLink;
+
+procedure InitLink;
+begin
+ amLink.Next :=ActionLink;
+ amLink.Init :=@Init;
+ amLink.DeInit :=@DeInit;
+ amLink.AddOption:=@AddOptionPage;
+ ActionLink :=@amLink;
+end;
+
+initialization
+ InitLink;
+end.
diff --git a/plugins/Actman/tasks/tasks.rc b/plugins/Actman/tasks/tasks.rc
new file mode 100644
index 0000000000..2bc558fbc3
--- /dev/null
+++ b/plugins/Actman/tasks/tasks.rc
@@ -0,0 +1,47 @@
+#include "i_tconst.inc"
+
+LANGUAGE 0,0
+
+IDD_TASKS DIALOGEX 0, 0, 304, 226, 0
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_VISIBLE
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0
+{
+ CONTROL "", IDC_TASK_NAME, "SysListView32",
+ WS_BORDER | WS_TABSTOP |
+ LVS_NOCOLUMNHEADER | LVS_SHOWSELALWAYS | LVS_REPORT | LVS_EDITLABELS,// | LVS_SINGLESEL,
+ 2, 2, 130, 174, WS_EX_CONTROLPARENT
+
+ CTEXT "Action",-1 , 140, 2, 160, 12, SS_CENTERIMAGE
+ COMBOBOX IDC_TASK_ACTION, 140, 14, 160, 128, CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL
+
+ GROUPBOX "Start" , -1, 138, 30, 164, 54
+
+ COMBOBOX IDC_TASK_ABSOLUTE, 142, 40, 156, 60, CBS_DROPDOWNLIST | WS_VSCROLL
+
+ CTEXT "Date", IDC_TASK_DATET, 140, 54, 76, 12, SS_CENTERIMAGE
+ CONTROL "Date", IDC_TASK_DATEV, "SysDateTimePick32", WS_TABSTOP, 150, 66, 56, 14
+
+ CTEXT "Days", IDC_TASK_DAYST, 140, 54, 76, 12, SS_CENTERIMAGE
+ EDITTEXT IDC_TASK_DAYSV, 162, 66, 32, 14
+
+ CTEXT "Time", IDC_TASK_TIMET, 220, 54, 76, 12, SS_CENTERIMAGE
+ CONTROL "Time", IDC_TASK_TIMEV, "SysDateTimePick32", WS_TABSTOP|$09, 230, 66, 56, 14
+
+ GROUPBOX "Repeat" , -1, 138, 88, 164, 88
+
+ CTEXT "Repeat, times", -1, 140, 98, 70, 14, SS_CENTERIMAGE
+ EDITTEXT IDC_TASK_REPEAT, 155, 114, 40, 14
+
+ CTEXT "Interval", -1, 212, 98, 84, 14, SS_CENTERIMAGE
+ EDITTEXT IDC_TASK_INTDAYS, 212, 114, 24, 14
+ CONTROL "Interval", IDC_TASK_INTERVAL, "SysDateTimePick32", WS_TABSTOP|$09, 240, 114, 56, 14
+
+ AUTOCHECKBOX "Break on non-zero result", IDC_TASK_BREAK, 142, 132, 156, 14
+ AUTOCHECKBOX "Send event on start time", IDC_TASK_EVENT, 142, 146, 156, 14
+ AUTOCHECKBOX "Send event just once" , IDC_TASK_ONCE , 142, 160, 156, 14
+
+ CONTROL "New" ,IDC_TASK_NEW ,"MButtonClass",WS_TABSTOP, 2,178,16,16,$18000000
+ CONTROL "Delete",IDC_TASK_DELETE,"MButtonClass",WS_TABSTOP,22,178,16,16,$18000000
+// CONTROL "Help" ,IDC_EVENT_HELP ,"MButtonClass",WS_TABSTOP,42,164,16,16,$18000000
+}
diff --git a/plugins/Actman/tasks/tasks.res b/plugins/Actman/tasks/tasks.res
new file mode 100644
index 0000000000..bc72f06406
--- /dev/null
+++ b/plugins/Actman/tasks/tasks.res
Binary files differ
diff --git a/plugins/Actman/ua/action.ico b/plugins/Actman/ua/action.ico
new file mode 100644
index 0000000000..9e4c60d9d3
--- /dev/null
+++ b/plugins/Actman/ua/action.ico
Binary files differ
diff --git a/plugins/Actman/ua/i_inoutxm.inc b/plugins/Actman/ua/i_inoutxm.inc
new file mode 100644
index 0000000000..68ad22d694
--- /dev/null
+++ b/plugins/Actman/ua/i_inoutxm.inc
@@ -0,0 +1,357 @@
+{}
+var
+ xmlparser:XML_API_W;
+
+const
+ ioAction :PWideChar = 'Action';
+ ioUA :PWideChar = 'UA';
+
+ ioName :PWideChar = 'name';
+
+ ioTwoState :PWideChar = 'twostate';
+ ioSaveState :PWideChar = 'savestate';
+
+ ioHotkey :PWideChar = 'Hotkey';
+ ioToolbar :PWideChar = 'Toolbar';
+ ioTabSRMM :PWideChar = 'TabSRMM';
+ ioMenuItem :PWideChar = 'Menu';
+
+ ioTooltip :PWideChar = 'tooltip';
+ ioTooltipPressed :PWideChar = 'tt_pressed';
+
+ ioType :PWideChar = 'type';
+ ioMenuPopup :PWideChar = 'Popup';
+ ioMenuName :PWideChar = 'Name';
+ ioMenuShow :PWideChar = 'Show';
+ ioMenuUsed :PWideChar = 'Used';
+ ioMenuSeparated :PWideChar = 'Separated';
+
+
+function ImportMenuItems(node:HXML;var MenuItem:tUAMenuItem):integer;
+begin
+ result:=0;
+
+ with xmlparser do
+ begin
+ with MenuItem do
+ begin
+ menu_opt:=0;
+ // popup
+ StrDupW(szMenuPopup,getAttrValue(node,ioMenuPopup));
+ // name
+ StrDupW(szMenuNameVars,getAttrValue(node,ioMenuName));
+ // show
+ StrDupW(szMenuShowWhenVars,getAttrValue(node,ioMenuShow));
+ // used
+ if StrToInt(getAttrValue(node,ioMenuUsed))<>0 then
+ menu_opt:=menu_opt or UAF_MENUUSE;
+ // separated
+ if StrToInt(getAttrValue(node,ioMenuSeparated))<>0 then
+ menu_opt:=menu_opt or UAF_MENUSEP;
+ end;
+ end;
+end;
+
+function ImportUAction(actnode:HXML;var UA:tMyActionItem):integer;
+var
+ num,i:integer;
+ sub:HXML;
+begin
+ result:=0;
+ if actnode=0 then exit;
+
+ with xmlparser do
+ begin
+ // we don't need that node as is, just it's child for UA
+// actnode:=GetNthChild(actnode,ioUA,0);
+
+ UA.flags:=0;
+ // ----- Common -----
+ if StrToInt(getAttrValue(actnode,ioTwoState))<>0 then
+ UA.flags:=UA.flags or UAF_2STATE;
+
+ if StrToInt(getAttrValue(actnode,ioSaveState))<>0 then
+ UA.flags:=UA.flags or UAF_SAVESTATE;
+
+ // sub:=AddChild(actnode,ioRegister,nil);
+ if StrToInt(getAttrValue(actnode,ioHotkey))<>0 then
+ UA.flags:=UA.flags or UAF_REGHOTKEY;
+ if StrToInt(getAttrValue(actnode,ioToolbar))<>0 then
+ UA.flags:=UA.flags or UAF_REGTTBB;
+ if StrToInt(getAttrValue(actnode,ioTabSRMM))<>0 then
+ UA.flags:=UA.flags or UAF_REGTABB;
+
+ // ----- Hotkey -----
+ // nothing
+
+ // ----- Modern CList toolbar -----
+ // source - ANSI text
+ sub:=GetNthChild(actnode,ioToolbar,0);
+ WideToAnsi(GetAttrValue(sub,ioTooltip ),UA.szTTBTooltip ,MirandaCP);
+ WideToAnsi(GetAttrValue(sub,ioTooltipPressed),UA.szTTBTooltipPressed,MirandaCP);
+
+ // ----- TabSRMM toolbar -----
+ sub:=GetNthChild(actnode,ioTabSRMM,0);
+ StrDupW(UA.szTabBTooltip ,getAttrValue(sub,ioTooltip));
+ StrDupW(UA.szTabBTooltipPressed,getAttrValue(sub,ioTooltipPressed));
+
+ // ----- Menus -----
+ num:=0;
+ repeat
+ sub:=getNextChild(actnode,ioMenuItem,@num);
+ if sub=0 then break;
+
+ i:=StrToInt(getAttrValue(sub,ioType));
+ ImportMenuItems(sub,
+ UA.UAMenuItem[tMenuType(i)]);
+ until false;
+ end;
+end;
+
+function Import(fname:PWideChar;aflags:dword):integer;
+var
+ i,j,act:integer;
+ root,actnode:HXML;
+ pcw,res:pWideChar;
+ f:THANDLE;
+ num,num1:integer;
+ ptr,ptr1:pChain;
+begin
+ result:=0;
+
+ if (fname=nil) or (fname^=#0) then
+ exit;
+ i:=GetFSize(fname);
+ if i=0 then
+ exit;
+
+ num:=CallService(MS_ACT_GETLIST,0,LPARAM(@ptr));
+ if num=0 then exit;
+ ptr1:=ptr;
+
+ mGetMem (res ,i+SizeOf(WideChar));
+ FillChar(res^,i+SizeOf(WideChar),0);
+ f:=Reset(fname);
+ BlockRead(f,res^,i);
+ CloseHandle(f);
+
+ xmlparser.cbSize:={XML_API_SIZEOF_V1;//}SizeOf(XML_API_W);
+ CallService(MS_SYSTEM_GET_XI,0,lparam(@xmlparser));
+ with xmlparser do
+ begin
+ root:=parseString(ChangeUnicode(res),@i,nil);
+ j:=0;
+ repeat
+ actnode:=getNthChild(root,ioAction,j);
+ if actnode=0 then break;
+ // search id by name?
+ pcw:=GetAttrValue(actnode,ioName);
+ ptr:=ptr1;
+ inc(pbyte(ptr),4);
+ for i:=0 to num-1 do
+ begin
+ if (ptr.flags and ACCF_IMPORTED)<>0 then
+ begin
+ if StrCmpw(pcw,ptr.descr)=0 then
+ begin
+ // delete old UA for overwrited actions
+ if (ptr.flags and ACCF_OVERLOAD)<>0 then
+ begin
+ for act:=0 to HIGH(UActionList) do
+ begin
+ if ptr.id=UActionList[act].dwActID then
+ begin
+ DeleteUAction(act);
+ break;
+ end;
+ end;
+ end;
+ num1:=AddUAction(-1,ptr);
+ ImportUAction(getNthChild(actnode,ioUA,0),UActionList[num1]);
+ break;
+ end;
+ end;
+ inc(ptr);
+ end;
+
+ inc(j);
+ until false;
+
+ DestroyNode(root);
+ end;
+ CallService(MS_ACT_FREELIST,0,LPARAM(ptr1));
+ mFreeMem(res);
+ result:=1;
+ if settings<>0 then
+ begin
+ FillActionList(settings);
+ ShowAction(settings,-1);
+ end;
+end;
+
+//--------------------------
+
+function ExportMenuItems(node:HXML;MenuItem:tUAMenuItem):HXML;
+begin
+ with xmlparser do
+ begin
+ result:=AddChild(node,ioMenuItem,nil);
+ with MenuItem do
+ begin
+ // popup
+ if (szMenuPopup<>nil) and (szMenuPopup^<>#0) then
+ AddAttr(result,ioMenuPopup,szMenuPopup);
+ // name
+ if (szMenuNameVars<>nil) and (szMenuNameVars^<>#0) then
+ AddAttr(result,ioMenuName,szMenuNameVars);
+ // show
+ if (szMenuShowWhenVars<>nil) and (szMenuShowWhenVars^<>#0) then
+ AddAttr(result,ioMenuShow,szMenuShowWhenVars);
+ // used
+ AddAttrInt(result,ioMenuUsed,ord((menu_opt AND UAF_MENUUSE)<>0));
+ // separated
+ AddAttrInt(result,ioMenuSeparated,ord((menu_opt AND UAF_MENUSEP)<>0));
+ end;
+ end;
+end;
+
+procedure WriteUAction(root:HXML;id:dword;name:pWideChar);
+var
+ i:integer;
+ lmenu:tMenuType;
+ pc:pWideChar;
+ actnode,sub:HXML;
+ UA:pMyActionItem;
+begin
+ with xmlparser do
+ begin
+ for i:=0 to HIGH(UActionList) do
+ begin
+ if UActionList[i].dwActID=id then
+ begin
+ UA:=@UActionList[i];
+ actnode:=getChildByAttrValue(root,ioAction,ioName,name);
+ if actnode=0 then break;
+ // we don't need that node as is, just it's child for UA
+ actnode:=addChild(actnode,ioUA,nil);
+
+ // ----- Common -----
+ AddAttrInt(actnode,ioTwoState ,ORD((UA.flags and UAF_2STATE )<>0));
+ AddAttrInt(actnode,ioSaveState,ORD((UA.flags and UAF_SAVESTATE)<>0));
+
+ // sub:=AddChild(actnode,ioRegister,nil);
+ AddAttrInt(actnode,ioHotkey ,ORD((UA.flags and UAF_REGHOTKEY)<>0));
+ AddAttrInt(actnode,ioToolbar,ORD((UA.flags and UAF_REGTTBB )<>0));
+ AddAttrInt(actnode,ioTabSRMM,ORD((UA.flags and UAF_REGTABB )<>0));
+
+ // ----- Hotkey -----
+ // nothing
+
+ // ----- Modern CList toolbar -----
+ // source - ANSI text
+ if ((UA.szTTBTooltip <>nil) and (UA.szTTBTooltip^ <>#0)) or
+ ((UA.szTTBTooltipPressed<>nil) and (UA.szTTBTooltipPressed^<>#0)) then
+ begin
+ sub:=AddChild(actnode,ioToolbar,nil);
+ if (UA.szTTBTooltip<>nil) and (UA.szTTBTooltip^<>#0) then
+ begin
+ AnsiToWide(UA.szTTBTooltip,pc,MirandaCP);
+ AddAttr(sub,ioTooltip,pc);
+ mFreeMem(pc);
+ end;
+ if (UA.szTTBTooltipPressed<>nil) and (UA.szTTBTooltipPressed^<>#0) then
+ begin
+ AnsiToWide(UA.szTTBTooltipPressed,pc,MirandaCP);
+ AddAttr(sub,ioTooltipPressed,pc);
+ mFreeMem(pc);
+ end;
+ end;
+
+ // ----- TabSRMM toolbar -----
+ if ((UA.szTabBTooltip <>nil) and (UA.szTabBTooltip^ <>#0)) or
+ ((UA.szTabBTooltipPressed<>nil) and (UA.szTabBTooltipPressed^<>#0)) then
+ begin
+ sub:=AddChild(actnode,ioTabSRMM,nil);
+ if (UA.szTabBTooltip<>nil) and (UA.szTabBTooltip^<>#0) then
+ AddAttr(sub,ioTooltip,UA.szTabBTooltip);
+ if (UA.szTabBTooltipPressed<>nil) and (UA.szTabBTooltipPressed^<>#0) then
+ AddAttr(sub,ioTooltipPressed,UA.szTabBTooltipPressed);
+ end;
+
+ // ----- Menus -----
+ for lmenu:=main_menu to HIGH(tMenuType) do
+ begin
+ sub:=ExportMenuItems(actnode,UA.UAMenuItem[lmenu]);
+ AddAttrInt(sub,ioType,ORD(lmenu));
+ end;
+
+ break;
+ end;
+ end;
+ end;
+end;
+
+function Export(fname:pWideChar;aflags:dword):integer;
+var
+ i,num:integer;
+ f:THANDLE;
+ root:HXML;
+ res:pWideChar;
+ ptr,ptr1:pChain;
+begin
+ result:=0;
+ xmlparser.cbSize:={XML_API_SIZEOF_V1;//}SizeOf(XML_API_W);
+ CallService(MS_SYSTEM_GET_XI,0,lparam(@xmlparser));
+ with xmlparser do
+ begin
+ // we need append file, not rewrite
+ i:=GetFSize(fname);
+ if i=0 then exit;
+
+ mGetMem (res ,i+SizeOf(WideChar));
+ FillChar(res^,i+SizeOf(WideChar),0);
+ f:=Reset(fname);
+ BlockRead(f,res^,i);
+ CloseHandle(f);
+ root:=parseString(res,@i,nil);
+ mFreeMem(res);
+
+ num:=CallService(MS_ACT_GETLIST,0,LPARAM(@ptr));
+ if num>0 then
+ begin
+ ptr1:=ptr;
+ inc(pbyte(ptr),4);
+ for i:=0 to num-1 do
+ begin
+ if ((aflags and ACIO_SELECTED)=0) or
+ ((ptr.flags and ACCF_EXPORT)<>0) then
+ begin
+ WriteUAction(root,ptr.id,ptr.descr);
+ end;
+ inc(ptr);
+ end;
+ CallService(MS_ACT_FREELIST,0,LPARAM(ptr1));
+ end;
+
+ res:=toString(root,@i);
+
+ f:=Rewrite(fname);
+ BlockWrite(f,res^,i*SizeOf(WideChar));
+ CloseHandle(f);
+ xmlparser.FreeMem(res);
+ DestroyNode(root);
+ end;
+ result:=1;
+end;
+
+function ActInOut(wParam:WPARAM;lParam:LPARAM):int_ptr; cdecl;
+begin
+ if (wParam and ACIO_EXPORT)=0 then
+ begin
+ result:=Import(pWideChar(lParam),wParam);
+ end
+ else
+ begin
+ result:=Export(pWideChar(lParam),wParam);
+ end;
+end;
diff --git a/plugins/Actman/ua/i_opt_dlg.inc b/plugins/Actman/ua/i_opt_dlg.inc
new file mode 100644
index 0000000000..01f01dceb7
--- /dev/null
+++ b/plugins/Actman/ua/i_opt_dlg.inc
@@ -0,0 +1,571 @@
+{}
+const
+ settings:HWND = 0;
+const
+ NumControls = 17;
+
+ IDsArray:array [0..NumControls-1] of integer =(
+ // Menu settings controls
+ IDC_UA_SEPARATE ,IDC_UA_POPUPT ,IDC_UA_POPUPV,
+ IDC_UA_VARNAMEST,IDC_UA_VARNAMESV,IDC_UA_VARNAMESH,
+ IDC_UA_SHOWVART ,IDC_UA_SHOWVARV ,IDC_UA_SHOWVARH,
+ IDC_UA_TWOSTATE ,IDC_UA_SAVSTATE ,IDC_UA_COMMON,
+ // toolbar settings controls
+ IDC_UA_TTNORMALT,IDC_UA_TTNORMALV,IDC_UA_TTPRESSEDT,IDC_UA_TTPRESSEDV,
+ IDC_UA_GLOBAL
+ );
+
+ // Show-hide controls by place type
+ SHArray:array [0..NumTypes-1, 0..NumControls-1] of integer = (
+ // CList Modern toolbar
+ (SW_HIDE,SW_HIDE,SW_HIDE, SW_HIDE,SW_HIDE,SW_HIDE, SW_SHOW,SW_SHOW,SW_SHOW,
+ SW_SHOW,SW_SHOW,SW_SHOW, SW_SHOW,SW_SHOW,SW_SHOW,SW_SHOW, SW_HIDE),
+ // TabSRMM toolbar
+ (SW_HIDE,SW_HIDE,SW_HIDE, SW_HIDE,SW_HIDE,SW_HIDE, SW_HIDE,SW_HIDE,SW_HIDE,
+ SW_SHOW,SW_SHOW,SW_SHOW, SW_SHOW,SW_SHOW,SW_SHOW,SW_SHOW, SW_SHOW),
+ // Core Hotkey
+ (SW_HIDE,SW_HIDE,SW_HIDE, SW_HIDE,SW_HIDE,SW_HIDE, SW_HIDE,SW_HIDE,SW_HIDE,
+ SW_HIDE,SW_HIDE,SW_HIDE, SW_HIDE,SW_HIDE,SW_HIDE,SW_HIDE, SW_HIDE),
+ // Main menu
+ (SW_SHOW,SW_SHOW,SW_SHOW, SW_SHOW,SW_SHOW,SW_SHOW, SW_SHOW,SW_SHOW,SW_SHOW,
+ SW_SHOW,SW_SHOW,SW_SHOW, SW_HIDE,SW_HIDE,SW_HIDE,SW_HIDE, SW_HIDE),
+ // Contact menu
+ (SW_SHOW,SW_SHOW,SW_SHOW, SW_SHOW,SW_SHOW,SW_SHOW, SW_SHOW,SW_SHOW,SW_SHOW,
+ SW_SHOW,SW_SHOW,SW_SHOW, SW_HIDE,SW_HIDE,SW_HIDE,SW_HIDE, SW_SHOW),
+ // Tray menu
+ (SW_SHOW,SW_SHOW,SW_SHOW, SW_SHOW,SW_SHOW,SW_SHOW, SW_SHOW,SW_SHOW,SW_SHOW,
+ SW_SHOW,SW_SHOW,SW_SHOW, SW_HIDE,SW_HIDE,SW_HIDE,SW_HIDE, SW_HIDE),
+ // Protocol menu
+ (SW_SHOW,SW_SHOW,SW_SHOW, SW_SHOW,SW_SHOW,SW_SHOW, SW_SHOW,SW_SHOW,SW_SHOW,
+ SW_SHOW,SW_SHOW,SW_SHOW, SW_HIDE,SW_HIDE,SW_HIDE,SW_HIDE, SW_HIDE),
+ // Status menu
+ (SW_SHOW,SW_SHOW,SW_SHOW, SW_SHOW,SW_SHOW,SW_SHOW, SW_SHOW,SW_SHOW,SW_SHOW,
+ SW_SHOW,SW_SHOW,SW_SHOW, SW_HIDE,SW_HIDE,SW_HIDE,SW_HIDE, SW_HIDE)
+ );
+ // additional show/hide controls check by Variables installings (1 - need to check)
+ SHVarArray:array [0..NumControls-1] of byte = (
+ 0,0,0, 0,0,1, 1,1,1,
+ 0,0,0,0,0,0,0, 0);
+ // additional enable/disable controls check (1 - always enable)
+ EnDisArray:array [0..NumControls-1] of byte = (
+ 0,0,0, 0,0,0, 0,0,0,
+ 1,1,1,0,0,0,0, 1);
+
+var
+ hIC:THANDLE;
+
+procedure CheckPlacesAbility;
+var
+ i:integer;
+begin
+ for i:=0 to NumTypes-1 do
+ begin
+ with NamesArray[i] do
+ begin
+ enable:=(service=nil) or (ServiceExists(service)<>0);
+ end;
+ end;
+end;
+
+function CompareItem(lParam1,lParam2:LPARAM;SortType:LPARAM):int; stdcall;
+begin
+ result:=UActionList[lParam1].wSortIndex-UActionList[lParam2].wSortIndex;
+end;
+
+// Show or hide option items
+procedure SetupControls(Dialog:HWND;atype:integer;item:integer=-1);
+var
+ i: cardinal;
+ typ:integer;
+ wnd,wnd1:HWND;
+ enable:boolean;
+begin
+ if atype<0 then
+ begin
+ for i:=0 to NumControls-1 do
+ begin
+ ShowWindow(GetDlgItem(Dialog,IDsArray[i]),SW_HIDE);
+ end;
+ end
+ else
+ begin
+ wnd1:=GetDlgItem(Dialog,IDC_UA_PLACELIST);
+ if item<0 then
+ item:=SendMessage(wnd1,LVM_GETNEXTITEM,-1,LVNI_FOCUSED);
+ enable:=ListView_GetCheckState(wnd1,item)<>0;
+
+ for i:=0 to NumControls-1 do
+ begin
+ typ:=SHArray[LoByte(atype)+HiByte(atype)][i];
+ if typ=SW_SHOW then
+ if (SHVarArray[i]<>0) and (not IsVarsInstalled) then
+ typ:=SW_HIDE;
+ wnd:=GetDlgItem(Dialog,IDsArray[i]);
+ ShowWindow(wnd,typ);
+ EnableWindow(wnd,enable or (EnDisArray[i]<>0));
+ end;
+
+ // common settings
+ EnableWindow(GetDlgItem(Dialog,IDC_UA_SAVSTATE),
+ IsDlgButtonChecked(Dialog,IDC_UA_TWOSTATE)<>BST_UNCHECKED);
+
+ // personal settings
+ case LoByte(atype) of
+ uaTTB, uaTAB: begin
+ enable:=false;
+ if IsDlgButtonChecked(Dialog,IDC_UA_TWOSTATE)<>BST_UNCHECKED then
+ if IsWindowEnabled(GetDlgItem(Dialog,IDC_UA_TTNORMALV)) then
+ enable:=true;
+ EnableWindow(GetDlgItem(Dialog,IDC_UA_TTPRESSEDV),enable);
+ end;
+ end;
+ end;
+end;
+
+// Clear all screen buttons/text fields (reset)
+procedure ClearControls(Dialog:HWND);
+var
+ s:HWND;
+begin
+ s:=settings;
+ settings:=0;
+ CheckDlgButton (Dialog,IDC_UA_TWOSTATE ,BST_UNCHECKED);
+ CheckDlgButton (Dialog,IDC_UA_SAVSTATE ,BST_UNCHECKED);
+
+ CheckDlgButton (Dialog,IDC_UA_SEPARATE ,BST_UNCHECKED);
+ SetDlgItemTextW(Dialog,IDC_UA_POPUPV ,nil);
+ SetDlgItemTextW(Dialog,IDC_UA_VARNAMESV,nil);
+ SetDlgItemTextW(Dialog,IDC_UA_SHOWVARV ,nil);
+ settings:=s;
+end;
+
+procedure ShowSubAction(Dialog:HWND;aType:integer;item:integer=-1);
+var
+ UA:pMyActionItem;
+ s:HWND;
+begin
+ s:=settings;
+ settings:=0;
+ ClearControls(Dialog);
+
+ // get UAction number
+ item:=LV_GetLParam(GetDlgItem(Dialog,IDC_UA_ACTIONLIST),item);
+
+ UA:=@UActionList[item];
+
+ // common settings
+ if (UA.flags and UAF_2STATE)<>0 then
+ CheckDlgButton(Dialog,IDC_UA_TWOSTATE,BST_CHECKED);
+
+ if (UA.flags and UAF_SAVESTATE)<>0 then
+ CheckDlgButton(Dialog,IDC_UA_SAVSTATE,BST_CHECKED);
+
+ if (UA.flags and UAF_GLOBAL)=0 then
+ CheckDlgButton(Dialog,IDC_UA_GLOBAL,BST_CHECKED);
+
+ // Show real UA settings
+ case LoByte(aType) of
+ uaTTB: begin // CList modern toolbar
+ SetDlgItemTextA(Dialog,IDC_UA_TTNORMALV ,UA.szTTBTooltip);
+ SetDlgItemTextA(Dialog,IDC_UA_TTPRESSEDV,UA.szTTBTooltipPressed);
+ SetDlgItemTextW(Dialog,IDC_UA_SHOWVARV ,UA.szTTBShowWhenVars);
+ end;
+
+ uaTAB: begin // TabSRMM toolbar
+ SetDlgItemTextW(Dialog,IDC_UA_TTNORMALV ,UA.szTabBTooltip);
+ SetDlgItemTextW(Dialog,IDC_UA_TTPRESSEDV,UA.szTabBTooltipPressed);
+ end;
+
+ uaMenu: begin
+ with UA.UAMenuItem[tMenuType(HiByte(aType))] do
+ begin
+ if (menu_opt and UAF_MENUSEP)<>0 then
+ CheckDlgButton(Dialog,IDC_UA_SEPARATE,BST_CHECKED);
+ SetDlgItemTextW(Dialog,IDC_UA_POPUPV ,szMenuPopup);
+ SetDlgItemTextW(Dialog,IDC_UA_VARNAMESV,szMenuNameVars);
+ SetDlgItemTextW(Dialog,IDC_UA_SHOWVARV ,szMenuShowWhenVars);
+ end;
+ end;
+
+ uaHotkey: begin // Hotkey
+ // Settings in Customize/Hotkeys
+ end;
+ end;
+ SetupControls(Dialog,aType,-1);
+ settings:=s;
+end;
+
+function isPlaceActive(idx,place:integer):boolean;
+begin
+ result:=false;
+ with UActionList[idx] do
+ case LoByte(place) of
+ uaTTB : result:=(flags and UAF_REGTTBB)<>0;
+ uaTAB : result:=(flags and UAF_REGTABB)<>0;
+ uaHotkey : result:=(flags and UAF_REGHOTKEY)<>0;
+ uaMenu: begin
+ result:=(UAMenuItem[tMenuType(HiByte(place))].menu_opt and UAF_MENUUSE)<>0
+ end;
+ end;
+end;
+
+procedure ShowAction(Dialog:HWND;item:integer=-1);
+var
+ i,j:integer;
+ wnd:HWND;
+ li:LV_ITEMW;
+ buf:array [0..255] of WideChar;
+ lset:HWND;
+begin
+ wnd:=GetDlgItem(Dialog,IDC_UA_PLACELIST);
+ SendMessage(wnd,LVM_DELETEALLITEMS,0,0);
+ j:=LV_GetLParam(GetDlgItem(Dialog,IDC_UA_ACTIONLIST),item);
+ if j>=0 then
+ begin
+ with UActionList[j] do
+ begin
+ lset:=settings;
+ settings:=0;
+ // make "places" list
+ for i:=0 to NumTypes-1 do
+ begin
+ with NamesArray[i] do
+ begin
+ if enable then // cached ability flag
+ begin
+ li.mask :=LVIF_TEXT+LVIF_PARAM;
+ li.iSubItem:=0;
+ li.iItem :=i;
+ li.lParam :=atype; //!!!!!! need to add subtype
+ li.pszText :=TranslateW(FastAnsiToWideBuf(name,buf));
+ li.iItem :=SendMessageW(wnd,LVM_INSERTITEMW,0,LPARAM(@li));
+
+ ListView_SetCheckState(wnd,li.iItem,isPlaceActive(j,atype));
+ end;
+ end;
+ end;
+ ListView_SetItemState(wnd,0,
+ LVIS_FOCUSED or LVIS_SELECTED,
+ LVIS_FOCUSED or LVIS_SELECTED);
+ // show first selected "place"
+ ShowSubAction(Dialog,LV_GetLParam(wnd));
+ settings:=lset;
+ end;
+ end
+ else
+ begin
+ ClearControls(Dialog);
+ SetupControls(Dialog,-1,-1);
+ end;
+end;
+
+procedure SetChangedFlag(Dialog:HWND);
+var
+ num,atype:integer;
+begin
+ num :=LV_GetLParam(GetDlgItem(Dialog,IDC_UA_ACTIONLIST),-1);
+ atype:=LV_GetLParam(GetDlgItem(Dialog,IDC_UA_PLACELIST ),-1);
+ UActionList[num].UAMenuItem[tMenuType(HiByte(atype))].changed:=true;
+end;
+
+procedure SaveMenuSubAction(Dialog:HWND;var MenuItem:tUAMenuItem);
+begin
+ with MenuItem do
+ begin
+ mFreeMem(szMenuPopup ); szMenuPopup :=GetDlgText(Dialog,IDC_UA_POPUPV);
+ mFreeMem(szMenuNameVars ); szMenuNameVars :=GetDlgText(Dialog,IDC_UA_VARNAMESV);
+ mFreeMem(szMenuShowWhenVars); szMenuShowWhenVars:=GetDlgText(Dialog,IDC_UA_SHOWVARV);
+ menu_opt:=0;
+ if IsDlgButtonchecked(Dialog,IDC_UA_SEPARATE)<>BST_UNCHECKED then
+ menu_opt:=menu_opt or UAF_MENUSEP;
+ end;
+end;
+
+procedure SetPlaceActive(idx,place:integer;active:boolean);
+begin
+ with UActionList[idx] do
+ case LoByte(place) of
+ uaTTB : if active then flags:=flags or UAF_REGTTBB else flags:=flags and not UAF_REGTTBB;
+ uaTAB : if active then flags:=flags or UAF_REGTABB else flags:=flags and not UAF_REGTABB;
+ uaHotkey: if active then flags:=flags or UAF_REGHOTKEY else flags:=flags and not UAF_REGHOTKEY;
+ uaMenu :
+ with UAMenuItem[tMenuType(HiByte(place))] do
+ if active then menu_opt:=menu_opt or UAF_MENUUSE
+ else menu_opt:=menu_opt and not UAF_MENUUSE;
+ end;
+end;
+
+procedure SaveAction(Dialog:HWND;item:integer=-1;atype:integer=-1);
+var
+ i,num:integer;
+ wnd:HWND;
+begin
+ num:=LV_GetLParam(GetDlgItem(Dialog,IDC_UA_ACTIONLIST),item);
+ if num<0 then exit;
+
+ wnd:=GetDlgItem(Dialog,IDC_UA_PLACELIST);
+ atype:=LV_GetLParam(wnd,atype);
+ with UActionList[num] do
+ begin
+ // main flags
+ flags:=flags and not UAF_USING;
+ // common section
+ if IsDlgButtonChecked(Dialog,IDC_UA_TWOSTATE)<>BST_UNCHECKED then
+ flags:=flags or UAF_2STATE
+ else
+ flags:=flags and not UAF_2STATE;
+
+ if IsDlgButtonChecked(Dialog,IDC_UA_SAVSTATE)<>BST_UNCHECKED then
+ flags:=flags or UAF_SAVESTATE
+ else
+ flags:=flags and not UAF_SAVESTATE;
+
+ if IsDlgButtonChecked(Dialog,IDC_UA_GLOBAL)=BST_UNCHECKED then
+ flags:=flags or UAF_GLOBAL
+ else
+ flags:=flags and not UAF_GLOBAL;
+
+ // custom data
+ case LoByte(atype) of
+ uaTTB: begin // CList modern toolbar
+ mFreeMem(szTTBTooltip ); szTTBTooltip :=GetDlgText(Dialog,IDC_UA_TTNORMALV ,true);
+ mFreeMem(szTTBTooltipPressed); szTTBTooltipPressed:=GetDlgText(Dialog,IDC_UA_TTPRESSEDV,true);
+ mFreeMem(szTTBShowWhenVars ); szTTBShowWhenVars :=GetDlgText(Dialog,IDC_UA_SHOWVARV);
+ end;
+
+ uaTAB: begin // TabSRMM toolbar
+ mFreeMem(szTabBTooltip ); szTabBTooltip :=GetDlgText(Dialog,IDC_UA_TTNORMALV);
+ mFreeMem(szTabBTooltipPressed); szTabBTooltipPressed:=GetDlgText(Dialog,IDC_UA_TTPRESSEDV);
+ end;
+
+ uaMenu: SaveMenuSubAction(Dialog,UAMenuItem[tMenuType(HiByte(atype))]);
+
+ uaHotkey: begin // Hotkey
+ // Settings in Customize/Hotkeys
+ end;
+ end;
+ for i:=0 to SendMessage(wnd,LVM_GETITEMCOUNT,0,0)-1 do
+ begin
+ SetPlaceActive(num,LV_GetLParam(wnd,i),ListView_GetCheckState(wnd,i)<>0);
+ end;
+ //just after Action (not place) changes
+ if item<0 then
+ SaveUA(num);
+ end;
+end;
+
+procedure FillActionList(wnd:HWND);
+var
+ i:integer;
+ li:LV_ITEMW;
+ il:HIMAGELIST;
+ lmenu:tMenuType;
+begin
+ wnd:=GetDlgItem(wnd,IDC_UA_ACTIONLIST);
+ SendMessage(wnd,LVM_DELETEALLITEMS,0,0);
+
+ il:=ImageList_Create(16,16,ILC_COLOR32 or ILC_MASK,0,1);
+ for i:=0 to HIGH(UActionList) do
+ begin
+ li.mask :=LVIF_TEXT+LVIF_PARAM+LVIF_IMAGE;
+ li.iSubItem:=0;
+ li.iItem :=i;
+ li.lParam :=i;
+ li.pszText :=UActionList[i].szActDescr;
+ li.iImage:=ImageList_AddIcon(il,
+ HICON(CallService(MS_SKIN2_GETICONBYHANDLE,0,LPARAM(UActionList[i].hIcolibIcon))));
+ li.iItem :=SendMessageW(wnd,LVM_INSERTITEMW,0,LPARAM(@li));
+
+ for lmenu:=main_menu to HIGH(tMenuType) do
+ UActionList[i].UAMenuItem[lmenu].changed:=false;
+ end;
+ ImageList_Destroy(SendMessage(wnd,LVM_SETIMAGELIST,LVSIL_SMALL,il));
+
+ SendMessage(wnd,LVM_SORTITEMS,0,LPARAM(@CompareItem));
+
+ ListView_SetItemState(wnd,0,
+ LVIS_FOCUSED or LVIS_SELECTED,
+ LVIS_FOCUSED or LVIS_SELECTED);
+end;
+
+// refresh icons in UA list (at least)
+function IconChanged(wParam:WPARAM;lParam:LPARAM):int;cdecl;
+var
+ i:integer;
+ li:LV_ITEMW;
+ il:HIMAGELIST;
+ wnd:HWND;
+begin
+ result:=0;
+ wnd:=GetDlgItem(settings,IDC_UA_ACTIONLIST);
+
+ il:=ImageList_Create(16,16,ILC_COLOR32 or ILC_MASK,0,1);
+ for i:=0 to HIGH(UActionList) do
+ begin
+ li.mask :=LVIF_IMAGE;
+ li.iSubItem:=0;
+ li.iItem :=i;
+ li.iImage:=ImageList_AddIcon(il,
+ HICON(CallService(MS_SKIN2_GETICONBYHANDLE,0,TLPARAM(UActionList[i].hIcolibIcon))));
+ SendMessageW(wnd,LVM_SETITEM,0,TLPARAM(@li));
+ end;
+ ImageList_Destroy(SendMessage(wnd,LVM_SETIMAGELIST,LVSIL_SMALL,il));
+//!!refresh?
+end;
+
+function DlgProcOpt(Dialog:HWnd;hMessage:UINT;wParam:WPARAM;lParam:LPARAM):lresult; stdcall;
+var
+ wnd:HWND;
+ lv:LV_COLUMNW;
+ i:integer;
+begin
+ result:=0;
+ case hMessage of
+ WM_CLOSE: begin
+ settings:=0;
+ UnhookEvent(hIC);
+ end;
+
+ WM_INITDIALOG: begin
+ settings:=0;
+ TranslateDialogDefault(Dialog);
+
+ wnd:=GetDlgItem(Dialog,IDC_UA_PLACELIST);
+ SendMessage(wnd,LVM_SETEXTENDEDLISTVIEWSTYLE,LVS_EX_CHECKBOXES,LVS_EX_CHECKBOXES);
+ SendMessage(wnd,LVM_SETUNICODEFORMAT,1,0);
+ zeromemory(@lv,sizeof(lv));
+ lv.mask:=LVCF_WIDTH;
+ lv.cx :=110;
+ SendMessageW(wnd,LVM_INSERTCOLUMNW ,0,tlparam(@lv));
+ SendMessageW(wnd,LVM_SETCOLUMNWIDTH,0,LVSCW_AUTOSIZE_USEHEADER);
+
+ wnd:=GetDlgItem(Dialog,IDC_UA_ACTIONLIST);
+// SendMessage(wnd,LVM_SETEXTENDEDLISTVIEWSTYLE,LVS_EX_CHECKBOXES,LVS_EX_CHECKBOXES);
+ SendMessage(wnd,LVM_SETUNICODEFORMAT,1,0);
+ zeromemory(@lv,sizeof(lv));
+ lv.mask:=LVCF_WIDTH;
+ lv.cx :=110;
+ SendMessageW(wnd,LVM_INSERTCOLUMNW ,0,tlparam(@lv));
+ SendMessageW(wnd,LVM_SETCOLUMNWIDTH,0,LVSCW_AUTOSIZE_USEHEADER);
+ FillActionList(Dialog);
+ ShowAction(Dialog,-1);
+
+// if isVarsInstalled then
+ begin
+ SendDlgItemMessage(Dialog,IDC_UA_VARNAMESH,BM_SETIMAGE,IMAGE_ICON,
+ CallService(MS_VARS_GETSKINITEM,0,VSI_HELPICON));
+ SendDlgItemMessage(Dialog,IDC_UA_SHOWVARH,BM_SETIMAGE,IMAGE_ICON,
+ CallService(MS_VARS_GETSKINITEM,0,VSI_HELPICON));
+// SendDlgItemMessage(Dialog,IDC_UA_VARNAMESH,BUTTONSETASFLATBTN,0,0);
+// SendDlgItemMessage(Dialog,IDC_UA_SHOWVARH ,BUTTONSETASFLATBTN,0,0);
+ end;
+
+ settings:=Dialog;
+ hIC:=HookEvent(ME_SKIN2_ICONSCHANGED,@IconChanged);
+ end;
+
+ WM_COMMAND: begin
+ case wParam shr 16 of
+ EN_CHANGE: begin
+ if settings<>0 then
+ begin
+ SendMessage(GetParent(Dialog),PSM_CHANGED,0,0);
+ if loword(wParam)=IDC_UA_POPUPV then
+ SetChangedFlag(Dialog);
+ end;
+ end;
+
+ BN_CLICKED: begin
+ if settings<>0 then
+ begin
+ case loword(wParam) of
+ IDC_UA_TWOSTATE: begin
+ SetupControls(Dialog,
+ LV_GetLParam(GetDlgItem(Dialog,IDC_UA_PLACELIST)),-1);
+ {
+ EnableWindow(GetDlgItem(Dialog,IDC_UA_TTPRESSEDV),
+ IsDlgButtonChecked(Dialog,IDC_UA_TWOSTATE)<>BST_UNCHECKED);
+ }
+ if IsDlgButtonChecked(Dialog,IDC_UA_TWOSTATE)=BST_UNCHECKED then
+ DeleteIcolibIconP(
+ UActionList[LV_GetLParam(GetDlgItem(Dialog,IDC_UA_ACTIONLIST),-1)])
+ else
+ AddIcolibIconP(
+ UActionList[LV_GetLParam(GetDlgItem(Dialog,IDC_UA_ACTIONLIST),-1)]);
+
+ SendMessage(GetParent(Dialog),PSM_CHANGED,0,0);
+ end;
+
+ IDC_UA_VARNAMESH: ShowVarHelp(Dialog,IDC_UA_VARNAMESV);
+ IDC_UA_SHOWVARH : ShowVarHelp(Dialog,IDC_UA_SHOWVARV);
+
+//??? IDC_UA_SAVSTATE,
+ IDC_UA_GLOBAL: SendMessage(GetParent(Dialog),PSM_CHANGED,0,0);
+
+ IDC_UA_SEPARATE: begin
+ SetChangedFlag(Dialog);
+ SendMessage(GetParent(Dialog),PSM_CHANGED,0,0);
+ end;
+ end;
+ end;
+ end;
+ end;
+ end;
+
+ WM_NOTIFY: begin
+ case integer(PNMHdr(lParam)^.code) of
+ PSN_APPLY: begin
+ SaveAction(Dialog);
+ SaveUAs;
+ FillChar(arMenuRec[0],Length(arMenuRec)*SizeOf(tuaMenuRecA),0);
+ for i:=0 to HIGH(UActionList) do
+ begin
+ SetAllActionUsers(UActionList[i],false);
+ end;
+ end;
+
+ LVN_ITEMCHANGED: begin
+ if settings=0 then exit;
+ if PNMLISTVIEW(lParam)^.uChanged=LVIF_STATE then
+ begin
+ i:=(PNMLISTVIEW(lParam)^.uOldState and LVNI_FOCUSED)-
+ (PNMLISTVIEW(lParam)^.uNewState and LVNI_FOCUSED);
+
+ if i>0 then // old focus
+ begin
+ if wParam=IDC_UA_ACTIONLIST then
+ SaveAction(Dialog,PNMLISTVIEW(lParam)^.iItem)
+ else //if wParam=IDC_UA_PLACELIST then
+ SaveAction(Dialog,-1,PNMLISTVIEW(lParam)^.iItem);
+ end
+ else if i<0 then // new focus
+ begin
+ if wParam=IDC_UA_ACTIONLIST then
+ ShowAction(Dialog,PNMLISTVIEW(lParam)^.iItem)
+ else//if wParam=IDC_UA_PLACELIST then
+ ShowSubAction(Dialog,
+ LV_GetLParam(GetDlgItem(Dialog,IDC_UA_PLACELIST),
+ PNMLISTVIEW(lParam)^.iItem));
+ end
+ else if (settings<>0) and
+ ((PNMLISTVIEW(lParam)^.uOldState or PNMLISTVIEW(lParam)^.uNewState)=$3000) then
+ begin
+ // which type
+ wnd:=GetDlgItem(Dialog,IDC_UA_PLACELIST);
+ if PNMLISTVIEW(lParam)^.iItem<>
+ SendMessage(wnd,LVM_GETNEXTITEM,-1,LVNI_FOCUSED) then
+ ListView_SetItemState(wnd,PNMLISTVIEW(lParam)^.iItem,
+ LVIS_FOCUSED or LVIS_SELECTED,
+ LVIS_FOCUSED or LVIS_SELECTED)
+ else
+ SetupControls(Dialog,LV_GetLParam(wnd,PNMLISTVIEW(lParam)^.iItem),
+ PNMLISTVIEW(lParam)^.iItem);
+
+ SendMessage(GetParent(Dialog),PSM_CHANGED,0,0);
+ end;
+ end;
+ end;
+ end;
+ end;
+ end;
+end;
diff --git a/plugins/Actman/ua/i_options.inc b/plugins/Actman/ua/i_options.inc
new file mode 100644
index 0000000000..91f54e89d8
--- /dev/null
+++ b/plugins/Actman/ua/i_options.inc
@@ -0,0 +1,337 @@
+{}
+const
+ opt_TTBTooltip :pAnsiChar = 'MTBTooltip';
+ opt_TTBTooltipPressed :pAnsiChar = 'MTBTooltipPressed';
+ opt_TTBShowWhenVars :pAnsiChar = 'MTBVarStr';
+
+ opt_TabBTooltip :pAnsiChar = 'TabBTooltip';
+ opt_TabBTooltipPressed:pAnsiChar = 'TabBTooltipPressed';
+
+ opt_MenuPopup :pAnsiChar = 'MenuPopup';
+ opt_MenuNameVars :pAnsiChar = 'MenuName';
+ opt_MenuShowWhenVars:pAnsiChar = 'MenuVarStr';
+ opt_MenuOptions :pAnsiChar = 'MenuOptions';
+
+{}
+procedure DeleteUASettings(idx:integer);
+var
+ setting:array [0..63] of AnsiChar;
+ p,pm:pAnsiChar;
+ lmenu:tMenuType;
+begin
+ with UActionList[idx] do
+ begin
+ p:=GetUABranch(setting,dwActID);
+ if p<>nil then
+ begin
+ p:=StrCopyE(p,opt_UA);
+ p^:='/'; inc(p);
+
+ StrCopy(p,opt_Flags); DBDeleteSetting(0,DBBranch,setting);
+
+ StrCopy(p,opt_TTBTooltip ); DBDeleteSetting(0,DBBranch,setting);
+ StrCopy(p,opt_TTBTooltipPressed ); DBDeleteSetting(0,DBBranch,setting);
+ StrCopy(p,opt_TTBShowWhenVars ); DBDeleteSetting(0,DBBranch,setting);
+
+ StrCopy(p,opt_TabBTooltip ); DBDeleteSetting(0,DBBranch,setting);
+ StrCopy(p,opt_TabBTooltipPressed); DBDeleteSetting(0,DBBranch,setting);
+
+ for lmenu:=main_menu to HIGH(tMenuType) do
+ begin
+ pm:=p;
+ pm^:=AnsiChar(ORD(lmenu)+ORD('0')); inc(pm);
+ pm^:='_'; inc(pm);
+ StrCopy(pm,opt_MenuPopup ); DBDeleteSetting(0,DBBranch,setting);
+ StrCopy(pm,opt_MenuNameVars ); DBDeleteSetting(0,DBBranch,setting);
+ StrCopy(pm,opt_MenuShowWhenVars); DBDeleteSetting(0,DBBranch,setting);
+ StrCopy(pm,opt_MenuOptions ); DBDeleteSetting(0,DBBranch,setting);
+ end;
+ end;
+ end;
+end;
+
+procedure addSaveUA(setting:pAnsiChar;txt:pWideChar); overload;
+begin
+ if (txt=nil) or (txt^=#0) then DBDeleteSetting(0,DBBranch,setting)
+ else DBWriteUnicode(0,DBBranch,setting,txt);
+end;
+
+procedure addSaveUA(setting:pAnsiChar;txt:pAnsiChar); overload;
+begin
+ if (txt=nil) or (txt^=#0) then DBDeleteSetting(0,DBBranch,setting)
+ else DBWriteString(0,DBBranch,setting,txt);
+end;
+
+procedure SaveUA(idx:integer);
+var
+ setting:array [0..63] of AnsiChar;
+ p,pm:pAnsiChar;
+ lmenu:tMenuType;
+begin
+ with UActionList[idx] do
+ begin
+ p:=GetUABranch(setting,dwActID);
+ if p<>nil then
+ begin
+ p:=StrCopyE(p,opt_UA);
+ p^:='/'; inc(p);
+
+ StrCopy(p,opt_Flags); DBWriteDWord(0,DBBranch,setting,
+ flags and not (UAF_REALTIME OR UAF_SPECIAL));
+
+ StrCopy(p,opt_TTBTooltip ); addSaveUA(setting,szTTBTooltip);
+ StrCopy(p,opt_TTBTooltipPressed); addSaveUA(setting,szTTBTooltipPressed);
+ StrCopy(p,opt_TTBShowWhenVars ); addSaveUA(setting,szTTBShowWhenVars);
+
+ StrCopy(p,opt_TabBTooltip ); addSaveUA(setting,szTabBTooltip);
+ StrCopy(p,opt_TabBTooltipPressed); addSaveUA(setting,szTabBTooltipPressed);
+
+ for lmenu:=main_menu to HIGH(tMenuType) do
+ begin
+ pm:=p;
+ pm^:=AnsiChar(ORD(lmenu)+ORD('0')); inc(pm);
+ pm^:='_'; inc(pm);
+ with UAMenuItem[lmenu] do
+ begin
+ StrCopy(pm,opt_MenuPopup ); addSaveUA(setting,szMenuPopup);
+ StrCopy(pm,opt_MenuNameVars ); addSaveUA(setting,szMenuNameVars);
+ StrCopy(pm,opt_MenuShowWhenVars); addSaveUA(setting,szMenuShowWhenVars);
+ StrCopy(pm,opt_MenuOptions ); DBWriteWord(0,DBBranch,setting,menu_opt);
+ end;
+ end;
+ end;
+ end;
+end;
+
+procedure SaveUAs;
+var
+ i:integer;
+begin
+ for i:=0 to HIGH(UActionList) do
+ SaveUA(i);
+end;
+
+function LoadUA(idx:integer):integer;
+var
+ setting:array [0..63] of AnsiChar;
+ p,pm:pAnsiChar;
+ lmenu:tMenuType;
+begin
+ result:=0;
+ with UActionList[idx] do
+ begin
+ p:=GetUABranch(setting,dwActID);
+ if p<>nil then
+ begin
+ p:=StrCopyE(p,opt_UA);
+ p^:='/'; inc(p);
+
+ StrCopy(p,opt_Flags);
+ flags:=DBReadDWord(0,DBBranch,setting,dword(UAF_SPECIAL));
+ if flags=dword(UAF_SPECIAL) then // no settings
+ begin
+ flags:=0;
+ exit;
+ end;
+ // no need to use previous "pressed" state
+ if (flags and UAF_SAVESTATE)=0 then
+ flags:=flags and not UAF_PRESSED;
+
+ flags:=flags and not UAF_REALTIME;
+ result:=1;
+
+ StrCopy(p,opt_TTBTooltip ); szTTBTooltip :=DBReadString (0,DBBranch,setting);
+ StrCopy(p,opt_TTBTooltipPressed); szTTBTooltipPressed:=DBReadString (0,DBBranch,setting);
+ StrCopy(p,opt_TTBShowWhenVars ); szTTBShowWhenVars :=DBReadUnicode(0,DBBranch,setting);
+
+ StrCopy(p,opt_TabBTooltip ); szTabBTooltip :=DBReadUnicode(0,DBBranch,setting);
+ StrCopy(p,opt_TabBTooltipPressed); szTabBTooltipPressed:=DBReadUnicode(0,DBBranch,setting);
+
+ for lmenu:=main_menu to HIGH(tMenuType) do
+ begin
+ pm:=p;
+ pm^:=AnsiChar(ORD(lmenu)+ORD('0')); inc(pm);
+ pm^:='_'; inc(pm);
+ with UAMenuItem[lmenu] do
+ begin
+ StrCopy(pm,opt_MenuPopup ); szMenuPopup :=DBReadUnicode(0,DBBranch,setting);
+ StrCopy(pm,opt_MenuNameVars ); szMenuNameVars :=DBReadUnicode(0,DBBranch,setting);
+ StrCopy(pm,opt_MenuShowWhenVars); szMenuShowWhenVars:=DBReadUnicode(0,DBBranch,setting);
+ StrCopy(pm,opt_MenuOptions ); menu_opt :=DBReadWord (0,DBBranch,setting);
+ end;
+ end;
+ end;
+ end;
+end;
+(*
+function LoadUAs:integer;
+{
+var
+ section:array [0..63] of AnsiChar;
+ p:PAnsiChar;
+ i:integer;
+}
+begin
+ result:=0;
+{
+ MaxTasks:=DBReadByte(0,opt_tasks,opt_count);
+ result:=MaxTasks;
+ if MaxTasks>0 then
+ begin
+ GetMem (TaskList ,MaxTasks*SizeOf(tTaskRec));
+ FillChar(TaskList^,MaxTasks*SizeOf(tTaskRec),0);
+ for i:=0 to MaxTasks-1 do
+ begin
+ p:=StrEnd(IntToStr(section,i));
+ with TaskList[i] do
+ begin
+ StrCopy(p,opt_flags ); flags :=DBReadDWord (0,opt_tasks,section);
+ StrCopy(p,opt_name ); name :=DBReadUnicode(0,opt_tasks,section);
+ StrCopy(p,opt_action); action :=DBReadDWord (0,opt_tasks,section);
+ end;
+ end;
+ end;
+}
+end;
+*)
+procedure SetAllActionUsers(var ActionItem:tMyActionItem; initial:boolean);
+var
+ setting:array [0..63] of AnsiChar;
+ p:pAnsiChar;
+ luse:boolean;
+ lmenu:tMenuType;
+begin
+ if NamesArray[uaHotkey].enable then
+ begin
+ if (ActionItem.flags and UAF_REGHOTKEY)<>0 then
+ AddCoreHotkey(ActionItem)
+ else
+ DeleteCoreHotkey(ActionItem);
+ end;
+ if not initial then
+ begin
+ if NamesArray[uaTTB].enable then
+ begin
+ DeleteTTBButton(ActionItem); // no modify command there, just delete, then insert back
+ if (ActionItem.flags and UAF_REGTTBB)<>0 then
+ AddTTBButton(ActionItem);
+ end;
+
+ if NamesArray[uaTAB].enable then
+ begin
+ if (ActionItem.flags and UAF_REGTABB)<>0 then
+ AddTabBBButton(ActionItem)
+ else
+ DeleteTabBBButton(ActionItem);
+ end;
+ end;
+
+ luse:=false;
+ for lmenu:=main_menu to HIGH(tMenuType) do
+ begin
+ if NamesArray[uaMenu+ORD(lmenu)].enable then
+ begin
+ if (ActionItem.UAMenuItem[lmenu].menu_opt and UAF_MENUUSE)<>0 then
+ begin
+ luse:=true;
+ if ActionItem.UAMenuItem[lmenu].changed then
+ DeleteMenuItem(ActionItem,lmenu);
+ CreateMenuItem(ActionItem,lmenu);
+ end
+ else
+ DeleteMenuItem(ActionItem,lmenu);
+ end;
+ end;
+
+ if (not luse) and (ActionItem.hMenuService<>0) then
+ begin
+ DestroyServiceFunction(ActionItem.hMenuService);
+ ActionItem.hMenuService:=0;
+ end;
+
+ // First run (ok ok, if ppl ask for it....)
+ p:=GetUABranch(setting,ActionItem.dwActID);
+ if p<>nil then
+ begin
+ p:=StrCopyE(p,opt_UA);
+ p^:='/'; inc(p);
+ StrCopy(p,'_FirstRun');
+ if DBReadByte(0,DBBranch,setting,0)<>0 then
+ begin
+ CAllService(MS_ACT_RUNBYID,ActionItem.dwActID,0);
+ DBDeleteSetting(0,DBBranch,setting);
+ end;
+ end;
+
+end;
+
+procedure DeleteUAction(num:integer);
+var
+ ActionItem:pMyActionItem;
+ setting:array [0..63] of AnsiChar;
+ p:pAnsiChar;
+ luse:boolean;
+ lmenu:tMenuType;
+begin
+ DeleteUASettings(num);
+
+ ActionItem:=@UActionList[num];
+
+ DeleteIcolibIcon(ActionItem^);
+
+ if (ActionItem.flags and UAF_REGHOTKEY)<>0 then
+ DeleteCoreHotkey(ActionItem^);
+
+ if (ActionItem.flags and UAF_REGTTBB)<>0 then
+ DeleteTTBButton(ActionItem^);
+ mFreeMem(ActionItem.szTTBTooltip);
+ mFreeMem(ActionItem.szTTBTooltipPressed);
+ mFreeMem(ActionItem.szTTBShowWhenVars);
+
+ if (ActionItem.flags and UAF_REGTABB)<>0 then
+ DeleteTabBBButton(ActionItem^);
+ mFreeMem(ActionItem.szTabBTooltip);
+ mFreeMem(ActionItem.szTabBTooltipPressed);
+
+ luse:=false;
+ for lmenu:=main_menu to HIGH(tMenuType) do
+ begin
+ with ActionItem.UAMenuItem[lmenu] do
+ begin
+ if (menu_opt and UAF_MENUUSE)<>0 then
+ begin
+ luse:=true;
+ DeleteMenuItem(ActionItem^,lmenu);
+ end;
+ mFreeMem(szMenuPopup);
+ mFreeMem(szMenuNameVars);
+ mFreeMem(szMenuShowWhenVars);
+ end;
+ end;
+
+ if (not luse) and (ActionItem.hMenuService<>0) then
+ begin
+ DestroyServiceFunction(ActionItem.hMenuService);
+ ActionItem.hMenuService:=0;
+ end;
+
+ p:=GetUABranch(setting,ActionItem.dwActID);
+ if p<>nil then
+ begin
+ p:=StrCopyE(p,opt_UA);
+ p^:='/'; inc(p);
+ StrCopy(p,'_FirstRun');
+ DBDeleteSetting(0,DBBranch,setting);
+ end;
+
+ // Free Memory
+ mFreeMem(ActionItem.szNameID);
+ mFreeMem(ActionItem.szActDescr);
+
+ // compact list
+ if num<HIGH(UActionList) then
+ begin
+ move(UActionList[num+1],UActionList[num],(HIGH(UACtionList)-num)*SizeOf(tMyActionItem));
+ end;
+ SetLength(UActionList,Length(UActionList)-1);
+end;
diff --git a/plugins/Actman/ua/i_ua.inc b/plugins/Actman/ua/i_ua.inc
new file mode 100644
index 0000000000..61641a7447
--- /dev/null
+++ b/plugins/Actman/ua/i_ua.inc
@@ -0,0 +1,155 @@
+{}
+function AddUAction(idx:integer; ptr:pChain):integer;
+var
+ buf:array [0..127] of AnsiChar;
+begin
+ if idx<0 then idx:=Length(UActionList);
+ if idx=Length(UActionList) then
+ SetLength(UActionList,Length(UActionList)+1);
+
+ FillChar(UActionList[idx],SizeOf(tMyActionItem),0);
+
+ with UActionList[idx] do
+ begin
+ // get Action settings
+ dwActID:=ptr^.id;
+ if (ptr^.flags and ACCF_DISABLED)<>0 then
+ flags:=UAF_DISABLED;
+ StrDupW(szActDescr,ptr^.descr);
+ wSortIndex:=idx;
+
+ // prepare for work
+ IntToStr(StrCopyE(buf,'Actions/Action_'),ptr^.id);
+ StrDup(szNameID,@buf);
+ AddIcolibIcon (UActionList[idx]);
+ end;
+
+ SetLength(arMenuRec,Length(UActionList)+1);
+ FillChar (arMenuRec[HIGH(arMenuRec)],SizeOf(tuaMenuRecA),0);
+ result:=idx;
+end;
+
+function CreateUActionList:integer;
+var
+ ptr,ptr1:pChain;
+ i:integer;
+begin
+ result:=CallService(MS_ACT_GETLIST,0,LPARAM(@ptr));
+ SetLength(UActionList,result);
+
+ SetLength(arMenuRec, result+1);
+ FillChar (arMenuRec[0],(result+1)*SizeOf(tuaMenuRecA),0);
+
+ if result>0 then
+ begin
+ ptr1:=ptr;
+ inc(pbyte(ptr),4);
+ for i:=0 to result-1 do
+ begin
+ AddUAction(i,ptr);
+ LoadUA(i); // just here coz at list changes for new we don't have settings
+ if (UActionList[i].flags and UAF_2STATE)<>0 then
+ AddIcolibIconP(UActionList[i]);
+ SetAllActionUsers(UActionList[i],true);
+ inc(ptr);
+ end;
+ CallService(MS_ACT_FREELIST,0,LPARAM(ptr1));
+ end;
+end;
+
+function ActListChange(wParam:WPARAM;lParam:LPARAM):integer; cdecl;
+var
+ ptr,ptr1:pChain;
+ idx,i,j,count:integer;
+ bFound:boolean;
+begin
+ result:=0;
+
+ count:=CallService(MS_ACT_GETLIST,0,TLPARAM(@ptr));
+
+ if count>0 then
+ begin
+ ptr1:=ptr;
+ inc(pbyte(ptr),4);
+ // maybe add ACTM_RELOAD (as NEW and DELETE) here too?
+ if (wParam and (ACTM_NEW or ACTM_RENAME or ACTM_SORT or ACTM_DELETE))<>0 then
+ for i:=0 to count-1 do
+ begin
+ // search corresponding element
+ idx:=-1;
+ for j:=0 to HIGH(UActionList) do
+ begin
+ if UActionList[j].dwActID=ptr^.id then
+ begin
+ idx:=j;
+ break;
+ end;
+ end;
+ // if we have no item in list for this action - then add new one
+ if idx<0 then
+ AddUAction(-1,ptr)
+ else
+ begin
+ if (wParam and ACTM_RENAME)<>0 then
+ begin
+ // check for time economy - no need to change ALL items
+ if StrCmpW(UActionList[idx].szActDescr,ptr^.descr)<>0 then
+ begin
+ mFreeMem(UActionList[idx].szActDescr);
+ StrDupW (UActionList[idx].szActDescr,ptr^.descr);
+ end;
+ end;
+
+ if (wParam and (ACTM_SORT or ACTM_DELETE or ACTM_NEW))<>0 then
+ UActionList[idx].wSortIndex:=i;
+ end;
+ inc(ptr);
+ end;
+ end
+ else
+ ptr1:=nil;
+
+ // now search deleted items
+ if (wParam and ACTM_DELETE)<>0 then
+ begin
+ for j:=HIGH(UActionList) downto 0 do
+ begin
+ bFound:=false;
+ if count>0 then
+ begin
+ ptr:=ptr1;
+ inc(pbyte(ptr),4);
+ for i:=0 to count-1 do
+ begin
+ if UActionList[j].dwActID=ptr^.id then
+ begin
+ bFound:=true;
+ break;
+ end;
+ inc(ptr);
+ end;
+ end;
+ if not bFound then
+ DeleteUAction(j);
+ end;
+ end;
+
+ if count>0 then
+ CallService(MS_ACT_FREELIST,0,TLPARAM(ptr1));
+
+ if settings<>0 then
+ begin
+ FillActionList(settings);
+ ShowAction(settings,-1);
+ SendMessage(GetParent(settings),PSM_CHANGED,0,0);
+ end
+ else
+ begin
+ SaveUAs;
+ FillChar(arMenuRec[0],Length(arMenuRec)*SizeOf(tuaMenuRecA),0);
+ for i:=0 to HIGH(UActionList) do
+ begin
+ SetAllActionUsers(UActionList[i],false);
+ end;
+ end;
+end;
diff --git a/plugins/Actman/ua/i_uaplaces.inc b/plugins/Actman/ua/i_uaplaces.inc
new file mode 100644
index 0000000000..1d923e25a3
--- /dev/null
+++ b/plugins/Actman/ua/i_uaplaces.inc
@@ -0,0 +1,831 @@
+{}
+
+const
+ MenuServices:array [tMenuType] of pAnsiChar = (
+ 'CList/AddMainMenuItem' {MS_CLIST_ADDMAINMENUITEM },
+ 'CList/AddContactMenuItem'{MS_CLIST_ADDCONTACTMENUITEM},
+ 'CList/AddTrayMenuItem' {MS_CLIST_ADDTRAYMENUITEM },
+ 'CList/AddProtoMenuItem' {MS_CLIST_ADDPROTOMENUITEM },
+ 'CList/AddStatusMenuItem' {MS_CLIST_ADDSTATUSMENUITEM }
+ );
+type
+ tuaMenuRec = record
+ hMenuRoot:HMENU;
+ position :integer;
+ end;
+ tuaMenuRecA = array [tMenuType] of tuaMenuRec;
+
+var
+ arMenuRec: array of tuaMenuRecA;
+
+//===== Support =====
+
+function ServiceCallWithLParam(wParam:WPARAM; lParam:LPARAM):int_ptr; cdecl;
+begin
+ result:=CallService(MS_ACT_RUNBYID, lParam, wParam);
+end;
+
+procedure SetTTBState(var ActionItem:tMyActionItem);
+var
+ lflag:integer;
+begin
+ if ActionItem.hTTBButton=0 then exit;
+ if (ActionItem.flags and UAF_2STATE)=0 then exit;
+
+ lflag:=CallService(MS_TTB_GETBUTTONSTATE,ActionItem.hTTBButton,0);
+ if lflag=TTBST_PUSHED then
+ begin
+ if (ActionItem.flags and (UAF_2STATE+UAF_PRESSED))<>(UAF_2STATE+UAF_PRESSED) then exit;
+ lflag:=TTBST_RELEASED;
+ end
+ else
+ begin
+ if (ActionItem.flags and (UAF_2STATE+UAF_PRESSED))=(UAF_2STATE+UAF_PRESSED) then exit;
+ if (ActionItem.flags and UAF_PRESSED)=0 then exit;
+ lflag:=TTBST_PUSHED;
+ end;
+ CallService(MS_TTB_SETBUTTONSTATE,ActionItem.hTTBButton,lflag);
+end;
+
+procedure SetTABState(hContact:THANDLE;var ActionItem:tMyActionItem;pressed:integer);
+var
+ tabb:BBButton;
+ pc:pWideChar;
+begin
+ FillChar(tabb,SizeOf(tabb),0);
+ tabb.cbSize :=SizeOf(tabb);
+ tabb.dwButtonID :=ActionItem.dwActID;
+ tabb.pszModuleName:=MODULE_NAME;
+
+ if pressed<>0 then
+ begin
+ pc:=ActionItem.szTabBTooltipPressed;
+ if pc=nil then pc:=ActionItem.szTabBTooltip;
+ tabb.hIcon:=ActionItem.hIcolibIconPressed;
+ tabb.bbbFlags:=BBSF_PUSHED;
+ end
+ else
+ begin
+ pc:=ActionItem.szTabBTooltip;
+ tabb.hIcon:=ActionItem.hIcolibIcon;
+ tabb.bbbFlags:=BBSF_RELEASED;
+ end;
+ if pc=nil then pc:=ActionItem.szActDescr;
+ tabb.szTooltip.w:=pc;
+ CallService(MS_BB_SETBUTTONSTATE,hContact,TLPARAM(@tabb));
+end;
+
+function IsLocalItem(const UAItem:tMyActionItem):boolean;
+begin
+ result:=((UAItem.flags and UAF_GLOBAL)=0) and
+ (UAItem.UAMenuItem[main_menu ].hMenuItem=0) and
+ (UAItem.UAMenuItem[tray_menu ].hMenuItem=0) and
+ (UAItem.UAMenuItem[proto_menu ].hMenuItem=0) and
+ (UAItem.UAMenuItem[status_menu].hMenuItem=0) and
+ (UAItem.hTTBButton=0);
+end;
+
+function ServiceCallWithFParam(wParam:WPARAM; lParam:LPARAM; fParam:LPARAM):int_ptr; cdecl;
+var
+ i:integer;
+ setting:array [0..63] of AnsiChar;
+ p:pAnsiChar;
+ cnt:THANDLE;
+ state:integer;
+begin
+ for i:=0 to HIGH(UActionList) do
+ begin
+ with UActionList[i] do
+ if dwActID=cardinal(fParam) then
+ if (flags and UAF_2STATE)<>0 then
+ begin
+ // sync buttons/menus
+ if IsLocalItem(UActionList[i]) then
+ begin
+ // if (flags and UAF_SAVESTATE)<>0 then
+ begin
+ state:=DBReadByte(lastContact,opt_ua,szNameID);
+ state:=state xor 1;
+ DBWriteByte(lastContact,opt_ua,szNameID,state);
+ cnt:=lastContact;
+ end;
+ end
+ else
+ begin
+ flags:=flags xor UAF_PRESSED;
+ // save "pressed" state
+ if (flags and UAF_SAVESTATE)<>0 then
+ begin
+ p:=GetUABranch(setting,dwActID);
+ if p<>nil then
+ begin
+ p:=StrCopyE(p,opt_ua);
+ p^:='/'; inc(p);
+ StrCopy(p,opt_flags);
+ DBWriteDWord(0,DBBranch,setting,flags and not UAF_REALTIME);
+ end;
+ end;
+
+ if hTTBButton<>0 then
+ SetTTBState(UActionList[i]);
+
+ cnt:=0;
+ state:=ORD(flags and UAF_PRESSED);
+ end;
+ if (flags and UAF_REGTABB)<>0 then
+ SetTABState(cnt,UActionList[i],state);
+
+ break;
+ end;
+ end;
+
+ result:=CallService(MS_ACT_RUNBYID, fParam, wParam);
+end;
+
+function AddIcolibIconP(var ActionItem:tMyActionItem):THANDLE;
+var
+ sid:TSKINICONDESC;
+ buf,buf1:array [0..63] of WideChar;
+begin
+ if (ActionItem.hIcolibIconPressed=0) or
+ (ActionItem.hIcolibIconPressed=ActionItem.hIcolibIcon) then
+ begin
+ // add icon for action to icolib
+ fillChar(sid,SizeOf(sid),0);
+ sid.cbSize :=sizeof(sid);
+ sid.szSection .w:=ICOLIB_ACTSECTION;
+ sid.szDefaultFile.w:=szMyPath;
+ sid.iDefaultIndex :=-IDI_ACTION;
+ sid.cx :=16;
+ sid.cy :=16;
+ sid.flags :=SIDF_ALL_UNICODE;
+ // icon "off"
+ StrCopyW(StrCopyEW(buf,ActionItem.szActDescr),' (pressed)');
+ sid.szDescription.w:=@buf;
+ StrCopy(StrCopyE(@buf1,ActionItem.szNameID),'_pressed');
+ sid.pszName :=@buf1;
+ ActionItem.hIcolibIconPressed:=Skin_AddIcon(@sid);
+ end;
+ result:=ActionItem.hIcolibIconPressed;
+end;
+
+function AddIcolibIcon(var ActionItem:tMyActionItem):THANDLE;
+var
+ sid:TSKINICONDESC;
+begin
+ if ActionItem.hIcolibIcon=0 then
+ begin
+ // add icon for action to icolib
+ fillChar(sid,SizeOf(sid),0);
+ sid.cbSize :=sizeof(sid);
+ sid.szSection .w:=ICOLIB_ACTSECTION;
+ sid.szDefaultFile.w:=szMyPath;
+ sid.iDefaultIndex :=-IDI_ACTION;
+ sid.cx :=16;
+ sid.cy :=16;
+ sid.flags :=SIDF_ALL_UNICODE;
+ // icon "on"
+ sid.szDescription.w:=ActionItem.szActDescr;
+ sid.pszName :=ActionItem.szNameID;
+ ActionItem.hIcolibIcon:=Skin_AddIcon(@sid);
+ end;
+ result:=ActionItem.hIcolibIcon;
+end;
+
+procedure DeleteIcolibIconP(var ActionItem:tMyActionItem);
+var
+ buf1:array [0..63] of WideChar;
+begin
+ if (ActionItem.hIcolibIconPressed<>0) and
+ (ActionItem.hIcolibIconPressed<>ActionItem.hIcolibIcon) then
+ begin
+ StrCopy(StrCopyE(@buf1,ActionItem.szNameID),'_pressed');
+ CallService(MS_SKIN2_REMOVEICON,0,LPARAM(@buf1));
+ ActionItem.hIcolibIconPressed:=ActionItem.hIcolibIcon;
+ end;
+end;
+
+procedure DeleteIcolibIcon(var ActionItem:tMyActionItem);
+begin
+ DeleteIcolibIconP(ActionItem);
+ CallService(MS_SKIN2_REMOVEICON,0,LPARAM(ActionItem.szNameID));
+ ActionItem.hIcolibIcon :=0;
+ ActionItem.hIcolibIconPressed:=0;
+end;
+
+//===== Really places =====
+
+//----- Hotkeys -----
+
+function AddCoreHotkey(var ActionItem:tMyActionItem):boolean;
+var
+ hkd:THOTKEYDESC;
+begin
+ if (ActionItem.flags and UAF_HKREGGED)=0 then
+ begin
+ FillChar(hkd,SizeOf(hkd),0);
+ hkd.cbSize := SizeOf(hkd); // HOTKEYDESC_SIZE_V1 for pre-0.9
+ hkd.dwFlags := HKD_UNICODE; // since 0.9 only
+ hkd.pszName := ActionItem.szNameID;
+ hkd.pszDescription.w:= ActionItem.szActDescr;
+ hkd.pszSection .w:= MODULE_NAME;
+ hkd.pszService := SERVICE_WITH_LPARAM_NAME;
+ hkd.lParam := ActionItem.dwActID;
+ result:=Hotkey_Register(@hkd)<>0;
+ if result then
+ ActionItem.flags:=ActionItem.flags or UAF_HKREGGED;
+ end
+ else
+ result:=true; //!!
+end;
+
+procedure DeleteCoreHotkey(var ActionItem:tMyActionItem);
+begin
+ if // bCoreHotkeyPresents and
+ // (ServiceExists(MS_HOTKEY_UNREGISTER)<>0) and
+ ((ActionItem.flags and UAF_HKREGGED)<>0) then
+ begin
+ CallService(MS_HOTKEY_UNREGISTER,0,LParam(ActionItem.szNameID));
+ ActionItem.flags:=ActionItem.flags and not UAF_HKREGGED;
+ end;
+end;
+
+//----- Common menu functions -----
+
+function AddRootMenuIcon(szPopupName:pWideChar):THANDLE;
+var
+ sid:TSKINICONDESC;
+begin
+ FillChar(sid,SizeOf(sid),0);
+ //first - register icon for root popup
+ sid.cbSize := sizeof(sid);
+ sid.szSection.w := ICOLIB_MNUSECTION;
+ sid.flags := SIDF_ALL_UNICODE;
+ sid.cx := 16;
+ sid.cy := 16;
+ sid.szDescription.w:= szPopupName;
+ sid.szDefaultFile.w:= szMyPath;
+ sid.iDefaultIndex := -IDI_ACTION;
+ WideToAnsi(szPopupName,sid.pszName);
+ result:=Skin_AddIcon(@sid);
+ mFreeMem(sid.pszName);
+end;
+
+procedure DeleteMenuItem(var ActionItem:tMyActionItem;mtype:tMenuType);
+var
+ i:integer;
+ hMenuRoot:THANDLE;
+ p:pMyActionItem;
+begin
+ with ActionItem.UAMenuItem[mtype] do
+ begin
+ if hMenuItem=0 then exit;
+ CallService(MO_REMOVEMENUITEM,hMenuItem,0);
+ hMenuItem:=0;
+ end;
+
+ hMenuRoot:=ActionItem.UAMenuItem[mtype].hMenuRoot;
+ if hMenuRoot<>0 then
+ begin
+ for i:=0 to HIGH(UActionList) do
+ begin
+ p:=@UActionList[i];
+ // presents somethere else
+ if (p<>@ActionItem) and (p.UAMenuItem[mtype].hMenuRoot=hMenuRoot) then
+ exit;
+ end;
+ // menu array cleanup now?
+ for i:=0 to HIGH(arMenuRec) do
+ begin
+ if arMenuRec[i][mtype].hMenuRoot=hMenuRoot then
+ begin
+ FillChar(arMenuRec[i][mtype],SizeOf(tuaMenuRec),0);
+// arMenuRec[i][mtype].hMenuRoot:=0;
+ break;
+ end;
+ end;
+ CallService(MO_REMOVEMENUITEM,hMenuRoot,0);
+ ActionItem.UAMenuItem[mtype].hMenuRoot:=0;
+ end;
+end;
+
+function GetMenuPosition(hMenu:HMENU;mtype:tMenuType;toset:boolean):integer;
+var
+ i:integer;
+begin
+ result:=0;
+ for i:=0 to HIGH(arMenuRec) do
+ begin
+ if arMenuRec[i][mtype].hMenuRoot=hMenu then
+ begin
+ if toset then
+ inc(arMenuRec[i][mtype].position,100000);
+ result:=arMenuRec[i][mtype].position;
+ break;
+ end;
+ end;
+end;
+
+function MakeMenuItem(mtype:tMenuType;clmi:PCListMenuItem):THANDLE;
+begin
+ case mtype of
+ main_menu : result:=Menu_AddMainMenuItem(clmi);
+ contact_menu: result:=Menu_AddContactMenuItem(clmi);
+ tray_menu : result:=Menu_AddTrayMenuItem(clmi);
+ proto_menu : result:=Menu_AddProtoMenuItem(clmi);
+ status_menu : result:=Menu_AddStatusMenuItem(clmi);
+ else
+ result:=0;
+ end;
+end;
+
+procedure CreateMenuItem(var ActionItem:tMyActionItem;mtype:tMenuType);
+var
+ i:integer;
+ ActItem:pMyActionItem;
+ ActMItem,UAMenuItem:pUAMenuItem;
+ clmi:TCListMenuItem;
+ res:boolean;
+ extra:pWideChar;
+begin
+{}
+ UAMenuItem:=@ActionItem.UAMenuItem[mtype];
+ if UAMenuItem.hMenuItem<>0 then exit;
+
+ // create popup menu
+{}{}
+ res:=true;
+ if (UAMenuItem.szMenuPopup<>nil) and (UAMenuItem.szMenuPopup^<>#0) then
+ begin
+ res:=false;
+ for i:=0 to HIGH(UActionList) do
+ begin
+ // try to find root popup with same name (if we already created one)
+ ActItem :=@UActionList[i];
+ ActMItem:=@ActItem.UAMenuItem[mtype];
+
+ if (ActMItem.szMenuPopup<>nil) and
+ (ActMItem.hMenuRoot<>0) and
+ ( (ActItem<>@ActionItem) and
+ (StrCmpW(ActMItem.szMenuPopup,UAMenuItem.szMenuPopup)=0) ) then
+ begin
+ UAMenuItem.hMenuRoot:=ActMItem.hMenuRoot;
+ res:=true;
+ break;
+ end;
+ end;
+ end;
+ // popup menu not found
+ if not res then
+ begin
+ FillChar(clmi,SizeOf(clmi),0);
+ clmi.cbSize:=SizeOf(clmi);
+ clmi.flags :=CMIF_UNICODE or CMIF_ICONFROMICOLIB;
+
+ if (UAMenuItem.szMenuPopup<>nil) and (UAMenuItem.szMenuPopup^<>#0) then
+ clmi.szName.w:=ParseVarString(UAMenuItem.szMenuPopup)
+ else
+ clmi.szName.w:=ActionItem.szActDescr;
+
+ clmi.hIcon :=AddRootMenuIcon(clmi.szName.w);
+ clmi.position:=ActionItem.wSortIndex*10;
+
+ // position in Root Menu
+ inc(clmi.position,GetMenuPosition(0,mtype,
+ (UAMenuItem.menu_opt and UAF_MENUSEP)<>0));
+
+ UAMenuItem.hMenuRoot:=MakeMenuItem(mtype,@clmi);
+ //CallService(MenuServices[mtype],0,LPARAM(@clmi));
+ if clmi.szName.w<>ActionItem.szActDescr then
+ mFreeMem(clmi.szName.w);
+
+ for i:=1 to HIGH(arMenuRec) do
+ begin
+ with arMenuRec[i][mtype] do
+ if hMenuRoot=0 then
+ begin
+// MenuName :=ActionItem.szActDescr;
+ hMenuRoot:=UAMenuItem.hMenuRoot;
+ break;
+ end;
+ end;
+
+ end;
+{}{}
+
+ // Now Menu Item preparing
+{}{}
+ FillChar(clmi,SizeOf(clmi),0);
+ clmi.cbSize:=SizeOf(clmi);
+ clmi.flags:=CMIF_UNICODE or CMIF_ICONFROMICOLIB;
+ if (ActionItem.flags and (UAF_2STATE+UAF_PRESSED))<>(UAF_2STATE+UAF_PRESSED) then
+ begin
+ clmi.hIcon:=ActionItem.hIcolibIcon;
+ extra:='0';
+ end
+ else
+ begin
+ clmi.hIcon:=ActionItem.hIcolibIconPressed;
+ clmi.flags:=CMIF_UNICODE or CMIF_ICONFROMICOLIB or CMIF_CHECKED;
+ extra:='1';
+ end;
+
+ with ActionItem.UAMenuItem[mtype] do
+ begin
+ if (szMenuNameVars<>nil) and (szMenuNameVars^<>#0) then
+ clmi.szName.w:=ParseVarString(szMenuNameVars,0,extra)
+ else
+ clmi.szName.w:=ActionItem.szActDescr;
+
+ if hMenuRoot<>0 then
+ begin
+ clmi.flags:=clmi.flags or CMIF_ROOTHANDLE;
+ clmi.szPopupName.w:=pWideChar(hMenuRoot);
+ end;
+ end;
+
+ clmi.pszService:=ActionItem.szNameID;
+ if ActionItem.hMenuService=0 then
+ ActionItem.hMenuService:=CreateServiceFunctionParam(
+ clmi.pszService,@ServiceCallWithFParam,ActionItem.dwActID);
+
+ clmi.position:=ActionItem.wSortIndex*10;
+{}{}
+ inc(clmi.position,GetMenuPosition(UAMenuItem.hMenuRoot,mtype,
+ (UAMenuItem.menu_opt and UAF_MENUSEP)<>0));
+
+ UAMenuItem.hMenuItem:=MakeMenuItem(mtype,@clmi);
+ //CallService(MenuServices[mtype],0,LPARAM(@clmi));
+ if clmi.szName.w<>ActionItem.szActDescr then
+ mFreeMem(clmi.szName.w);
+{}
+
+end;
+
+function PreBuildMenu(mtype:tMenuType;hContact:THANDLE=0):int;
+var
+ i:integer;
+ mi:TCListMenuItem;
+ p,extra:pWideChar;
+begin
+ result:=0;
+
+ FillChar(mi,SizeOf(mi),0);
+ mi.cbSize:=SizeOf(mi);
+
+ for i:=0 to HIGH(UActionList) do
+ begin
+ mi.flags:=CMIM_FLAGS;
+ p:=nil;
+ with UActionList[i] do
+ begin
+ with UAMenuItem[mtype] do
+ begin
+ if hMenuItem<>0 then // it means, we process that item here
+ begin
+ mi.szName.w:=nil;
+ // Show / hide
+ if isVarsInstalled then
+ begin
+ if (szMenuShowWhenVars<>nil) and (szMenuShowWhenVars^<>#0) then
+ begin
+ p:=ParseVarString(szMenuShowWhenVars,hContact);
+ if p<>nil then
+ begin
+ if StrCmpW(p,'1')<>0 then
+ mi.flags:=CMIM_FLAGS or CMIF_HIDDEN;
+ mFreeMem(p);
+ end;
+ end;
+ end;
+
+ // change if need to show only
+ // (popup can be used by many items, keep unchanged)
+ if (mi.flags and CMIF_HIDDEN)=0 then
+ begin
+ //!!!! icon (check for contact menu)
+ mi.flags:=mi.flags or CMIM_ICON or CMIM_FLAGS or CMIF_ICONFROMICOLIB;
+
+ if (mtype=contact_menu) and IsLocalItem(UActionList[i]) then
+ begin
+ lastContact:=hContact;
+ if ((flags and UAF_2STATE)<>0) and
+ (DBReadByte(hContact,opt_ua,szNameID)<>0) then
+ begin
+ mi.flags:=mi.flags or CMIF_CHECKED;
+ mi.hIcon:=hIcolibIconPressed;
+ extra:='1';
+ flags:=flags or UAF_PRESSED;
+ end
+ else
+ begin
+ mi.hIcon:=hIcolibIcon;
+ flags:=flags and not UAF_PRESSED;
+ extra:='0';
+ end;
+
+ end
+ else
+ begin
+ if (flags and (UAF_2STATE+UAF_PRESSED))=(UAF_2STATE+UAF_PRESSED) then
+ begin
+ mi.flags:=mi.flags or CMIF_CHECKED;
+ mi.hIcon:=hIcolibIconPressed;
+ extra:='1';
+ end
+ else
+ begin
+ mi.hIcon:=hIcolibIcon;
+ extra:='0';
+ end;
+ end;
+
+ // new name
+ mi.flags:=mi.flags or CMIM_NAME or CMIF_UNICODE;
+ if (szMenuNameVars<>nil) and (szMenuNameVars^<>#0) then
+ mi.szName.w:=ParseVarString(szMenuNameVars,hContact,extra);
+
+ if mi.szName.w=nil then
+ mi.szName.w:=szActDescr;
+ end;
+
+ CallService(MS_CLIST_MODIFYMENUITEM,hMenuItem,LPARAM(@mi));
+ if mi.szName.w<>szActDescr then
+ mFreeMem(mi.szName.w);
+ end;
+ end;
+ end;
+
+ end;
+end;
+
+function PreBuildMainMenu(wParam:WPARAM;lParam:LPARAM):int; cdecl;
+begin
+ result:=PreBuildMenu(main_menu,wParam);
+end;
+
+function PreBuildContactMenu(wParam:WPARAM;lParam:LPARAM):int; cdecl;
+begin
+ result:=PreBuildMenu(contact_menu,wParam);
+end;
+
+function PreBuildTrayMenu(wParam:WPARAM;lParam:LPARAM):int; cdecl;
+begin
+ result:=PreBuildMenu(tray_menu,wParam);
+end;
+
+//----- TopToolbar -----
+
+procedure AddTTBButton(var ActionItem:tMyActionItem);
+var
+ mtButton:TTBButton;
+ pc,pc1,pc2:pAnsiChar;
+ res:boolean;
+ p:pWideChar;
+begin
+ if not NamesArray[uaTTB].enable then exit;
+
+ if ActionItem.hTTBButton=0 then
+ begin
+ // Add or not
+ if isVarsInstalled then
+ begin
+ if (ActionItem.szTTBShowWhenVars<>nil) and (ActionItem.szTTBShowWhenVars^<>#0) then
+ begin
+ p:=ParseVarString(ActionItem.szTTBShowWhenVars);
+ if p<>nil then
+ begin
+ res:=StrCmpW(p,'1')<>0;
+ mFreeMem(p);
+ end
+ else
+ res:=true;
+ if res then
+ exit;
+ end;
+ end;
+
+ FillChar(mtButton,SizeOf(mtButton),0);
+ mtButton.cbSize :=SizeOf(mtButton);
+
+ mtButton.pszService:=TTB_SERVICE_NAME;//SERVICE_WITH_LPARAM_NAME;
+ mtButton.lParamUp :=ActionItem.dwActID;
+ mtButton.lParamDown:=ActionItem.dwActID;
+
+ mtButton.hIconUp:=ActionItem.hIcolibIcon;
+ mtButton.hIconDn:=ActionItem.hIcolibIconPressed;
+
+ WideToAnsi(ActionItem.szActDescr,pc);
+
+ if (ActionItem.flags and UAF_2STATE)<>0 then
+ mtButton.dwFlags:=TTBBF_VISIBLE or TTBBF_SHOWTOOLTIP{ or TTBBF_ASPUSHBUTTON}
+ else
+ mtButton.dwFlags:=TTBBF_VISIBLE or TTBBF_SHOWTOOLTIP;
+
+ if ActionItem.szTTBTooltip =nil then
+ pc1:=pc
+ else pc1:=ActionItem.szTTBTooltip;
+
+ if ((ActionItem.flags and UAF_2STATE)=0) or
+ (ActionItem.szTTBTooltipPressed=nil) then
+ pc2:=pc1
+ else
+ pc2:=ActionItem.szTTBTooltipPressed;
+
+ mtButton.Name :=pc;
+ mtButton.pszTooltipUp :=pc1;
+ mtButton.pszTooltipDn :=pc2;
+
+ ActionItem.hTTBButton:=TopToolbar_AddButton(@mtButton);
+ if ActionItem.hTTBButton=THANDLE(-1) then
+ ActionItem.hTTBButton:=0;
+ mFreeMem(pc);
+ end;
+end;
+
+procedure DeleteTTBButton(var ActionItem:tMyActionItem);
+begin
+ if ActionItem.hTTBButton<>0 then
+ begin
+ CallService(MS_TTB_REMOVEBUTTON,ActionItem.hTTBButton,0);
+ ActionItem.hTTBButton:=0;
+ end;
+end;
+
+function TTBServiceCall(wParam:WPARAM; lParam:LPARAM):int_ptr; cdecl;
+var
+ i,lflag:integer;
+begin
+ result:=0;
+ for i:=0 to HIGH(UActionList) do
+ begin
+ if TLPARAM(UActionList[i].dwActID)=lParam then
+ begin
+ with UActionList[i] do
+ begin
+ if (flags and UAF_2STATE)<>0 then
+ begin
+ if CallService(MS_TTB_GETBUTTONSTATE,hTTBButton,0)=TTBST_PUSHED then
+ begin
+ lflag:=TTBST_RELEASED;
+ end
+ else
+ begin
+ lflag:=TTBST_PUSHED;
+ end;
+ CallService(MS_TTB_SETBUTTONSTATE,hTTBButton,lflag);
+ end;
+ end;
+
+ result:=ServiceCallWithFParam(0,0,lParam);
+ break;
+ end;
+ end;
+end;
+
+function OnTTBLoaded(wParam:WPARAM;lParam:LPARAM):int; cdecl;
+var
+ i:integer;
+begin
+ result:=0;
+ for i:=HIGH(UActionList) downto 0 do
+ begin
+ if (UActionList[i].flags and UAF_REGTTBB)<>0 then
+ AddTTBButton(UActionList[i]);
+ end;
+end;
+
+//----- TabSRMM Toolbar -----
+
+const
+ TABTOOLBAR_INITPOS = 350;
+
+procedure AddTabBBButton(var ActionItem:tMyActionItem);
+var
+ tabb:BBButton;
+begin
+ if not NamesArray[uaTAB].enable then exit;
+
+ if (ActionItem.flags and UAF_TBREGGED)=0 then
+ begin
+ FillChar(tabb,SizeOf(tabb),0);
+ // register Tab ButtonBar button
+ tabb.cbSize :=SizeOf(tabb);
+ tabb.dwButtonID :=ActionItem.dwActID;
+ tabb.pszModuleName:=MODULE_NAME;
+ tabb.dwDefPos :=(TABTOOLBAR_INITPOS+ActionItem.wSortIndex*10) and $7FFF;
+ tabb.iButtonWidth :=0;
+ tabb.hIcon :=ActionItem.hIcolibIcon;
+ if (ActionItem.flags and UAF_2STATE)<>0 then
+ tabb.bbbFlags:=BBBF_ISIMBUTTON or BBBF_ISLSIDEBUTTON or
+ BBBF_ISCHATBUTTON or BBBF_ISPUSHBUTTON
+ else
+ tabb.bbbFlags:=BBBF_ISIMBUTTON or BBBF_ISLSIDEBUTTON or
+ BBBF_ISCHATBUTTON;
+
+ if ActionItem.szTabBTooltip<>nil then
+ tabb.szTooltip.w:=ActionItem.szTabBTooltip
+ else
+ tabb.szTooltip.w:=ActionItem.szActDescr;
+
+ if CallService(MS_BB_ADDBUTTON,0,LPARAM(@tabb))=0 then
+ ActionItem.flags:=ActionItem.flags or UAF_TBREGGED;
+ end;
+end;
+
+procedure DeleteTabBBButton(var ActionItem:tMyActionItem);
+var
+ tabb:BBButton;
+begin
+ if (ActionItem.flags and UAF_TBREGGED)<>0 then
+ begin
+ FillChar(tabb,SizeOf(tabb),0);
+ tabb.cbSize :=SizeOf(tabb);
+ tabb.dwButtonID :=ActionItem.dwActID;
+ tabb.pszModuleName:=MODULE_NAME;
+ CallService(MS_BB_REMOVEBUTTON,0,LPARAM(@tabb));
+ ActionItem.flags:=ActionItem.flags and not UAF_TBREGGED;
+ end;
+end;
+
+function OnTabButtonPressed(wParam:WPARAM;lParam:LPARAM):int; cdecl;
+var
+ cbcd:pCustomButtonClickData;
+// tabb:BBButton;
+// pc:pWideChar;
+ i:integer;
+begin
+ result:=0;
+ cbcd:=pointer(lParam);
+ if StrCmp(cbcd.pszModule,MODULE_NAME)<>0 then
+ exit;
+
+ for i:=0 to HIGH(UActionList) do
+ begin
+ with UActionList[i] do
+ begin
+ if cbcd.dwButtonId=dwActID then
+ begin
+{
+ FillChar(tabb,SizeOf(tabb),0);
+ tabb.cbSize :=SizeOf(tabb);
+ tabb.dwButtonID :=cbcd.dwButtonId;
+ tabb.pszModuleName:=MODULE_NAME;
+ if (flags and UAF_2STATE)<>0 then
+ begin
+ CallService(MS_BB_GETBUTTONSTATE,cbcd.hContact,TLPARAM(@tabb));
+ if IsLocalItem(UActionList[i]) then
+ begin
+ if DBReadByte(hContact,opt_ua,szNameID)<>0 then
+ end
+ else
+ begin
+ if (tabb.bbbFlags and BBSF_PUSHED)<>0 then
+ begin
+ pc:=szTabBTooltipPressed;
+ if pc=nil then pc:=szTabBTooltip;
+ tabb.hIcon:=hIcolibIconPressed;
+ end
+ else
+ begin
+ pc:=szTabBTooltip;
+ tabb.hIcon:=hIcolibIcon;
+ end;
+ if pc=nil then pc:=szActDescr;
+ tabb.szTooltip.w:=pc;
+ tabb.bbbFlags :=BBBF_ISIMBUTTON or BBBF_ISLSIDEBUTTON or
+ BBBF_ISCHATBUTTON or BBBF_ISPUSHBUTTON;
+ end
+ else
+ begin
+ tabb.hIcon:=hIcolibIcon;
+ tabb.szTooltip.w:=szTabBTooltip;
+ if tabb.szTooltip.w=nil then tabb.szTooltip.w:=szActDescr;
+ tabb.bbbFlags :=BBBF_ISIMBUTTON or BBBF_ISLSIDEBUTTON or
+ BBBF_ISCHATBUTTON;
+ end;
+
+ tabb.iButtonWidth:=0;
+ tabb.dwDefPos :=(TABTOOLBAR_INITPOS+wSortIndex*10) and $7FFF;
+ CallService(MS_BB_MODIFYBUTTON,0,TLPARAM(@tabb));
+}
+ ServiceCallWithFParam(cbcd.hContact,0,cbcd.dwButtonId);
+ result:=1;
+ break;
+ end;
+ end;
+ end;
+
+end;
+
+function OnTabBBLoaded(wParam:WPARAM;lParam:LPARAM):int; cdecl;
+var
+ i:integer;
+begin
+ result:=0;
+ for i:=HIGH(UActionList) downto 0 do
+ begin
+ if (UActionList[i].flags and UAF_REGTABB)<>0 then
+ AddTabBBButton(UActionList[i]);
+ end;
+end;
diff --git a/plugins/Actman/ua/i_uavars.inc b/plugins/Actman/ua/i_uavars.inc
new file mode 100644
index 0000000000..bab2ac12a1
--- /dev/null
+++ b/plugins/Actman/ua/i_uavars.inc
@@ -0,0 +1,124 @@
+{}
+const
+ MODULE_NAME = 'Actions';
+const
+ opt_groups:PAnsiChar = 'Group';
+ opt_ua :PAnsiChar = 'UA';
+ opt_id :PAnsiChar = 'id';
+ opt_flags :PAnsiChar = 'Flags';
+
+const
+ ICOLIB_ACTSECTION = MODULE_NAME+'/Registered actions';
+ ICOLIB_MNUSECTION = MODULE_NAME+'/Menu icons';
+
+ SERVICE_WITH_LPARAM_NAME = MODULE_NAME+'/CallAction';
+ TTB_SERVICE_NAME = MODULE_NAME+'/TTBAction';
+
+type
+ tMenuType = (main_menu,contact_menu,tray_menu,proto_menu,status_menu);
+ pUAMenuItem = ^tUAMenuItem;
+ tUAMenuItem = record
+ hMenuItem :THANDLE;
+ szMenuPopup :pWideChar;
+ szMenuNameVars :pWideChar;
+ szMenuShowWhenVars:pWideChar;
+ hMenuRoot :THANDLE;
+ menu_opt :dword;
+ changed :boolean;
+ end;
+type
+ pMyActionItem = ^tMyActionItem;
+ tMyActionItem = record
+ flags :dword;
+ dwActID :dword; // action ID
+ wSortIndex :word; // list/menu/toolbar order
+ // UseActions/Action_ID
+ szNameID :pAnsiChar; // uaction ID
+ szActDescr :pWideChar; // action name
+
+ hIcolibIcon,
+ hIcolibIconPressed :THANDLE;
+
+ hTTBButton :THANDLE; // TopToolbar button
+ szTTBTooltip :PAnsiChar;
+ szTTBTooltipPressed :PAnsiChar;
+ szTTBShowWhenVars :pWideChar;
+
+ szTabBTooltip :PWideChar; // TabSRMM toolbar button
+ szTabBTooltipPressed:PWideChar;
+
+ lastContact :THANDLE; // for contact menu
+ hMenuService :THANDLE; // common menu service
+ UAMenuItem :array [tMenuType] of tUAMenuItem;
+ end;
+
+const
+ UAF_NONE = 0;
+
+ UAF_REGHOTKEY = 1 shl 0; // hotkey
+ UAF_REGTTBB = 1 shl 1; // modern toolbar
+
+ UAF_REGTABB = 1 shl 5; // TabSRMM toolbar
+ UAF_USING = UAF_REGHOTKEY or UAF_REGTTBB or UAF_REGTABB;
+
+ UAF_2STATE = 1 shl 11; // Buttons/menu items are 2-state
+ UAF_PRESSED = 1 shl 12; // Button pressed/menu item selected
+ UAF_SAVESTATE = 1 shl 13; // Save or not "pressed" state
+ UAF_GLOBAL = 1 shl 14; // not contact related even if in contact menu only
+
+ // realtime, no save
+ UAF_HKREGGED = 1 shl 16; // hotkey registered
+ UAF_TBREGGED = 1 shl 17; // TabSRMM button registered
+ UAF_DISABLED = 1 shl 30; // action disabled atm
+ UAF_REALTIME = UAF_HKREGGED or UAF_TBREGGED or UAF_DISABLED;
+
+ UAF_SPECIAL = 1 shl 31; // for settings read
+
+ // menu options
+ UAF_MENUSEP = 1 shl 1; // menu item separated
+ UAF_MENUUSE = 1 shl 8; // use this menu
+
+type
+ tNameRec = record
+ name :PAnsiChar;
+ service:PAnsiChar;
+ mask :dword;
+ atype :word;
+ enable :boolean;
+ end;
+
+const
+ NumTypes = 8;
+const
+ uaTTB = 0;
+ uaTAB = 1;
+ uaHotkey = 2;
+ uaMenu = 3;
+
+const
+ NamesArray: array [0..NumTypes-1] of tNameRec = (
+ (name:'TopToolbar'; service:'TopToolBar/AddButton';
+ mask:UAF_REGTTBB ; atype:uaTTB; enable:false),
+ (name:'TabSRMM toolbar' ; service:'TabSRMM/ButtonsBar/AddButton';
+ mask:UAF_REGTABB ; atype:uaTAB; enable:false),
+ (name:'Core Hotkey' ; service:nil{MS_HOTKEY_REGISTER};
+ mask:UAF_REGHOTKEY; atype:uaHotkey; enable:false),
+ (name:'Main menu' ; service:nil;
+ mask:0; atype:uaMenu+(ORD(main_menu ) shl 8); enable:false),
+ (name:'Contact menu' ; service:nil;
+ mask:0; atype:uaMenu+(ORD(contact_menu) shl 8); enable:false),
+ (name:'Tray menu' ; service:'CList/AddTrayMenuItem';
+ mask:0; atype:uaMenu+(ORD(tray_menu ) shl 8); enable:false),
+ (name:'Protocol menus' ; service:'CList/AddProtoMenuItem';
+ mask:0; atype:uaMenu+(ORD(proto_menu ) shl 8); enable:false),
+ (name:'Status menu' ; service:'CList/AddStatusMenuItem';
+ mask:0; atype:uaMenu+(ORD(status_menu ) shl 8); enable:false)
+ );
+
+var
+ UActionList:array of tMyActionItem;
+var
+ szMyPath:array [0..MAX_PATH] of WideChar;
+var
+ hServiceWithLParam:THANDLE;
+ hTTBService:THANDLE;
diff --git a/plugins/Actman/ua/i_uconst.inc b/plugins/Actman/ua/i_uconst.inc
new file mode 100644
index 0000000000..34dde3ee9e
--- /dev/null
+++ b/plugins/Actman/ua/i_uconst.inc
@@ -0,0 +1,34 @@
+{resource constants}
+const
+ IDD_UA = 1031;
+
+ IDC_UA_ACTIONLIST = 1025;
+ IDC_UA_PLACELIST = 1026;
+
+ // menu settings
+ IDC_UA_SEPARATE = 1027;
+ IDC_UA_POPUPT = 1028;
+ IDC_UA_POPUPV = 1029;
+
+ IDC_UA_VARNAMEST = 1030;
+ IDC_UA_VARNAMESV = 1031;
+ IDC_UA_VARNAMESH = 1032;
+
+ IDC_UA_SHOWVART = 1033;
+ IDC_UA_SHOWVARV = 1034;
+ IDC_UA_SHOWVARH = 1035;
+
+ // toolbar settings
+ IDC_UA_TTNORMALT = 2028;
+ IDC_UA_TTNORMALV = 2029;
+ IDC_UA_TTPRESSEDT = 2030;
+ IDC_UA_TTPRESSEDV = 2031;
+
+ // common
+ IDC_UA_COMMON = 2000;
+ IDC_UA_TWOSTATE = 2001;
+ IDC_UA_SAVSTATE = 2002;
+
+ IDC_UA_GLOBAL = 2003;
+
+ IDI_ACTION = 101;
diff --git a/plugins/Actman/ua/ua.pas b/plugins/Actman/ua/ua.pas
new file mode 100644
index 0000000000..62b9604286
--- /dev/null
+++ b/plugins/Actman/ua/ua.pas
@@ -0,0 +1,124 @@
+unit ua;
+
+interface
+
+procedure Init;
+procedure DeInit;
+function AddOptionPage(var tmpl:pAnsiChar;var proc:pointer;var name:PAnsiChar):integer;
+
+implementation
+
+uses
+ windows, commctrl, messages,
+ mirutils, common, dbsettings, io, m_api, wrapper,
+ global;
+
+{$R ua.res}
+
+{$include m_actman.inc}
+
+{$include i_uconst.inc}
+{$include i_uavars.inc}
+
+// in - Action ID, out - action (group) number
+function GetUABranch(setting:pAnsiChar;id:cardinal):pAnsiChar;
+var
+ i:integer;
+ p,p1:pAnsiChar;
+begin
+ result:=nil;
+ p1:=StrCopyE(setting,opt_groups);
+ for i:=0 to CallService(MS_ACT_GETLIST,0,0)-1 do
+ begin
+ p:=StrEnd(IntToStr(p1,i));
+ p^:='/'; inc(p);
+ StrCopy(p,opt_id);
+ if DBReadDWord(0,DBBranch,setting)=id then
+ begin
+ p^:=#0;
+ result:=p;
+ break;
+ end;
+ end;
+end;
+
+var
+ amLink:tActionLink;
+
+{$include i_uaplaces.inc}
+{$include i_options.inc}
+{$include i_opt_dlg.inc}
+{$include i_ua.inc}
+{$include i_inoutxm.inc}
+
+// ------------ base interface functions -------------
+
+var
+ iohook:THANDLE;
+ hontabloaded,
+ honttbloaded,
+ ontabbtnpressed,
+ onactchanged:THANDLE;
+ hPreBuildMMenu,
+ hPreBuildCMenu,
+ hPreBuildTMenu:THANDLE;
+
+procedure Init;
+begin
+ GetModuleFileNameW(hInstance,szMyPath,MAX_PATH);
+
+ hServiceWithLParam:=CreateServiceFunction(SERVICE_WITH_LPARAM_NAME,@ServiceCallWithLParam);
+ hTTBService :=CreateServiceFunction(TTB_SERVICE_NAME ,@TTBServiceCall);
+ CheckPlacesAbility;
+
+ CreateUActionList;
+
+ honttbloaded :=HookEvent(ME_TTB_MODULELOADED ,@OnTTBLoaded);
+ hontabloaded :=HookEvent(ME_MSG_TOOLBARLOADED,@OnTabBBLoaded);
+ ontabbtnpressed:=HookEvent(ME_MSG_BUTTONPRESSED,@OnTabButtonPressed);
+ onactchanged :=HookEvent(ME_ACT_CHANGED ,@ActListChange);
+
+ hPreBuildMMenu:=HookEvent(ME_CLIST_PREBUILDMAINMENU , PreBuildMainMenu);
+ hPreBuildCMenu:=HookEvent(ME_CLIST_PREBUILDCONTACTMENU, PreBuildContactMenu);
+ hPreBuildTMenu:=HookEvent(ME_CLIST_PREBUILDTRAYMENU , PreBuildTrayMenu);
+
+ iohook:=HookEvent(ME_ACT_INOUT,@ActInOut);
+end;
+
+procedure DeInit;
+begin
+ SetLength(arMenuRec,0);
+
+ UnhookEvent(hPreBuildMMenu);
+ UnhookEvent(hPreBuildCMenu);
+ UnhookEvent(hPreBuildTMenu);
+
+ UnhookEvent(honttbloaded);
+ UnhookEvent(hontabloaded);
+ UnhookEvent(ontabbtnpressed);
+ UnhookEvent(onactchanged);
+ UnhookEvent(iohook);
+ DestroyServiceFunction(hServiceWithLParam);
+ DestroyServiceFunction(hTTBService);
+end;
+
+function AddOptionPage(var tmpl:pAnsiChar;var proc:pointer;var name:PAnsiChar):integer;
+begin
+ result:=0;
+ tmpl:=PAnsiChar(IDD_UA);
+ proc:=@DlgProcOpt;
+ name:='Use Actions';
+end;
+
+procedure InitLink;
+begin
+ amLink.Next :=ActionLink;
+ amLink.Init :=@Init;
+ amLink.DeInit :=@DeInit;
+ amLink.AddOption:=@AddOptionPage;
+ ActionLink :=@amLink;
+end;
+
+initialization
+ InitLink;
+end.
diff --git a/plugins/Actman/ua/ua.rc b/plugins/Actman/ua/ua.rc
new file mode 100644
index 0000000000..76d8c0ad77
--- /dev/null
+++ b/plugins/Actman/ua/ua.rc
@@ -0,0 +1,51 @@
+#include "i_uconst.inc"
+
+LANGUAGE 0,0
+
+IDD_UA DIALOGEX 0, 0, 304, 226, 0
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_VISIBLE
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0
+{
+ CTEXT "Action list",-1, 2,2,132,10, SS_CENTERIMAGE
+ CONTROL "", IDC_UA_ACTIONLIST, "SysListView32",
+ WS_BORDER | WS_TABSTOP |
+ LVS_NOCOLUMNHEADER | LVS_SHOWSELALWAYS | LVS_REPORT | LVS_SINGLESEL,
+ 2, 12, 132, 212, WS_EX_CONTROLPARENT
+
+ CTEXT "Where to use",-1, 138,2,160,10, SS_CENTERIMAGE
+ CONTROL "", IDC_UA_PLACELIST, "SysListView32",
+ WS_BORDER | WS_TABSTOP |
+ LVS_NOCOLUMNHEADER | LVS_SHOWSELALWAYS | LVS_REPORT | LVS_SINGLESEL,
+ 138, 12, 160, 74, WS_EX_CONTROLPARENT
+
+ GROUPBOX "Common" , IDC_UA_COMMON , 138, 88,160,38
+ AUTOCHECKBOX "2 state button/item" , IDC_UA_TWOSTATE, 140, 96,156,14, BS_LEFTTEXT | BS_RIGHT
+ AUTOCHECKBOX "Save button/item state", IDC_UA_SAVSTATE, 140,110,156,14, BS_LEFTTEXT | BS_RIGHT
+
+ AUTOCHECKBOX "Contact related", IDC_UA_GLOBAL, 138,128,160,14, BS_LEFTTEXT | BS_RIGHT
+
+ // Buttons settings block
+ RTEXT "Normal button tooltip",IDC_UA_TTNORMALT, 138,148,160,8
+ EDITTEXT IDC_UA_TTNORMALV, 138,158,160,12, ES_AUTOHSCROLL
+
+ RTEXT "Pressed button tooltip",IDC_UA_TTPRESSEDT, 138,172,160,8
+ EDITTEXT IDC_UA_TTPRESSEDV, 138,182,160,12, ES_AUTOHSCROLL
+
+ // Menu settings block
+ AUTOCHECKBOX "Separated",IDC_UA_SEPARATE, 138,142,160,14, BS_LEFTTEXT | BS_RIGHT
+
+ RTEXT "Root popup:",IDC_UA_POPUPT,138,158,80,12, SS_CENTERIMAGE
+ EDITTEXT IDC_UA_POPUPV, 218,158,80,12, ES_AUTOHSCROLL
+
+ RTEXT "Menu item name:",IDC_UA_VARNAMEST, 138,172,140,8
+ EDITTEXT IDC_UA_VARNAMESV, 138,182,140,12, ES_AUTOHSCROLL
+ CONTROL "V",IDC_UA_VARNAMESH,"MButtonClass",WS_TABSTOP, 282,180,16,16, $18000000
+
+ RTEXT "Show only if variables return 1",IDC_UA_SHOWVART, 138,200,140,8
+ EDITTEXT IDC_UA_SHOWVARV,138,210,140,12,ES_AUTOHSCROLL
+ CONTROL "V",IDC_UA_SHOWVARH,"MButtonClass",WS_TABSTOP, 282,208,16,16, $18000000
+
+}
+
+IDI_ACTION ICON "action.ico"
diff --git a/plugins/Actman/ua/ua.res b/plugins/Actman/ua/ua.res
new file mode 100644
index 0000000000..8316b81f51
--- /dev/null
+++ b/plugins/Actman/ua/ua.res
Binary files differ