From 864081102a5f252415f41950b3039a896b4ae9c5 Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Mon, 8 Oct 2012 18:43:29 +0000 Subject: Awkwars's plugins - welcome to our trunk git-svn-id: http://svn.miranda-ng.org/main/trunk@1822 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/Actman/actman.dpr | 189 ++++ plugins/Actman/global.pas | 21 + plugins/Actman/hooks/hooks.pas | 73 ++ plugins/Actman/hooks/hooks.rc | 28 + plugins/Actman/hooks/hooks.res | Bin 0 -> 688 bytes plugins/Actman/hooks/i_hconst.inc | 20 + plugins/Actman/hooks/i_hook.inc | 154 +++ plugins/Actman/hooks/i_opt_dlg.inc | 410 +++++++ plugins/Actman/hooks/i_options.inc | 71 ++ plugins/Actman/i_action.inc | 952 ++++++++++++++++ plugins/Actman/i_actlow.inc | 836 ++++++++++++++ plugins/Actman/i_const.inc | 219 ++++ plugins/Actman/i_contact.inc | 113 ++ plugins/Actman/i_dlglists.inc | 75 ++ plugins/Actman/i_inoutxm.inc | 1180 ++++++++++++++++++++ plugins/Actman/i_opt_dlg.inc | 215 ++++ plugins/Actman/i_opt_dlg2.inc | 2109 ++++++++++++++++++++++++++++++++++++ plugins/Actman/i_options.inc | 459 ++++++++ plugins/Actman/i_services.inc | 131 +++ plugins/Actman/i_vars.inc | 31 + plugins/Actman/i_visual.inc | 1073 ++++++++++++++++++ plugins/Actman/ico/advance.ico | Bin 0 -> 2550 bytes plugins/Actman/ico/apply.ico | Bin 0 -> 1406 bytes plugins/Actman/ico/chain.ico | Bin 0 -> 2550 bytes plugins/Actman/ico/contact.ico | Bin 0 -> 2550 bytes plugins/Actman/ico/delete.ico | Bin 0 -> 2550 bytes plugins/Actman/ico/down.ico | Bin 0 -> 2550 bytes plugins/Actman/ico/export.ico | Bin 0 -> 2550 bytes plugins/Actman/ico/format.ico | Bin 0 -> 2550 bytes plugins/Actman/ico/import.ico | Bin 0 -> 2550 bytes plugins/Actman/ico/insert.ico | Bin 0 -> 2550 bytes plugins/Actman/ico/message.ico | Bin 0 -> 2550 bytes plugins/Actman/ico/new.ico | Bin 0 -> 2550 bytes plugins/Actman/ico/program.ico | Bin 0 -> 2550 bytes plugins/Actman/ico/reload.ico | Bin 0 -> 2550 bytes plugins/Actman/ico/rw.ico | Bin 0 -> 2550 bytes plugins/Actman/ico/service.ico | Bin 0 -> 2550 bytes plugins/Actman/ico/test.ico | Bin 0 -> 2550 bytes plugins/Actman/ico/up.ico | Bin 0 -> 2550 bytes plugins/Actman/ico/vcheck.ico | Bin 0 -> 350 bytes plugins/Actman/ico/vuncheck.ico | Bin 0 -> 350 bytes plugins/Actman/m_actions.inc | 193 ++++ plugins/Actman/m_actman.h | 96 ++ plugins/Actman/m_actman.inc | 158 +++ plugins/Actman/make.bat | 20 + plugins/Actman/options.rc | 328 ++++++ plugins/Actman/options.res | Bin 0 -> 55904 bytes plugins/Actman/question.pas | 51 + plugins/Actman/readme.txt | 126 +++ plugins/Actman/services.ini | 497 +++++++++ plugins/Actman/tasks/i_opt_dlg.inc | 536 +++++++++ plugins/Actman/tasks/i_options.inc | 99 ++ plugins/Actman/tasks/i_service.inc | 87 ++ plugins/Actman/tasks/i_task.inc | 242 +++++ plugins/Actman/tasks/i_tconst.inc | 27 + plugins/Actman/tasks/scheduler.pas | 86 ++ plugins/Actman/tasks/tasks.rc | 47 + plugins/Actman/tasks/tasks.res | Bin 0 -> 1288 bytes plugins/Actman/ua/action.ico | Bin 0 -> 2550 bytes plugins/Actman/ua/i_inoutxm.inc | 357 ++++++ plugins/Actman/ua/i_opt_dlg.inc | 571 ++++++++++ plugins/Actman/ua/i_options.inc | 337 ++++++ plugins/Actman/ua/i_ua.inc | 155 +++ plugins/Actman/ua/i_uaplaces.inc | 831 ++++++++++++++ plugins/Actman/ua/i_uavars.inc | 124 +++ plugins/Actman/ua/i_uconst.inc | 34 + plugins/Actman/ua/ua.pas | 124 +++ plugins/Actman/ua/ua.rc | 51 + plugins/Actman/ua/ua.res | Bin 0 -> 3944 bytes 69 files changed, 13536 insertions(+) create mode 100644 plugins/Actman/actman.dpr create mode 100644 plugins/Actman/global.pas create mode 100644 plugins/Actman/hooks/hooks.pas create mode 100644 plugins/Actman/hooks/hooks.rc create mode 100644 plugins/Actman/hooks/hooks.res create mode 100644 plugins/Actman/hooks/i_hconst.inc create mode 100644 plugins/Actman/hooks/i_hook.inc create mode 100644 plugins/Actman/hooks/i_opt_dlg.inc create mode 100644 plugins/Actman/hooks/i_options.inc create mode 100644 plugins/Actman/i_action.inc create mode 100644 plugins/Actman/i_actlow.inc create mode 100644 plugins/Actman/i_const.inc create mode 100644 plugins/Actman/i_contact.inc create mode 100644 plugins/Actman/i_dlglists.inc create mode 100644 plugins/Actman/i_inoutxm.inc create mode 100644 plugins/Actman/i_opt_dlg.inc create mode 100644 plugins/Actman/i_opt_dlg2.inc create mode 100644 plugins/Actman/i_options.inc create mode 100644 plugins/Actman/i_services.inc create mode 100644 plugins/Actman/i_vars.inc create mode 100644 plugins/Actman/i_visual.inc create mode 100644 plugins/Actman/ico/advance.ico create mode 100644 plugins/Actman/ico/apply.ico create mode 100644 plugins/Actman/ico/chain.ico create mode 100644 plugins/Actman/ico/contact.ico create mode 100644 plugins/Actman/ico/delete.ico create mode 100644 plugins/Actman/ico/down.ico create mode 100644 plugins/Actman/ico/export.ico create mode 100644 plugins/Actman/ico/format.ico create mode 100644 plugins/Actman/ico/import.ico create mode 100644 plugins/Actman/ico/insert.ico create mode 100644 plugins/Actman/ico/message.ico create mode 100644 plugins/Actman/ico/new.ico create mode 100644 plugins/Actman/ico/program.ico create mode 100644 plugins/Actman/ico/reload.ico create mode 100644 plugins/Actman/ico/rw.ico create mode 100644 plugins/Actman/ico/service.ico create mode 100644 plugins/Actman/ico/test.ico create mode 100644 plugins/Actman/ico/up.ico create mode 100644 plugins/Actman/ico/vcheck.ico create mode 100644 plugins/Actman/ico/vuncheck.ico create mode 100644 plugins/Actman/m_actions.inc create mode 100644 plugins/Actman/m_actman.h create mode 100644 plugins/Actman/m_actman.inc create mode 100644 plugins/Actman/make.bat create mode 100644 plugins/Actman/options.rc create mode 100644 plugins/Actman/options.res create mode 100644 plugins/Actman/question.pas create mode 100644 plugins/Actman/readme.txt create mode 100644 plugins/Actman/services.ini create mode 100644 plugins/Actman/tasks/i_opt_dlg.inc create mode 100644 plugins/Actman/tasks/i_options.inc create mode 100644 plugins/Actman/tasks/i_service.inc create mode 100644 plugins/Actman/tasks/i_task.inc create mode 100644 plugins/Actman/tasks/i_tconst.inc create mode 100644 plugins/Actman/tasks/scheduler.pas create mode 100644 plugins/Actman/tasks/tasks.rc create mode 100644 plugins/Actman/tasks/tasks.res create mode 100644 plugins/Actman/ua/action.ico create mode 100644 plugins/Actman/ua/i_inoutxm.inc create mode 100644 plugins/Actman/ua/i_opt_dlg.inc create mode 100644 plugins/Actman/ua/i_options.inc create mode 100644 plugins/Actman/ua/i_ua.inc create mode 100644 plugins/Actman/ua/i_uaplaces.inc create mode 100644 plugins/Actman/ua/i_uavars.inc create mode 100644 plugins/Actman/ua/i_uconst.inc create mode 100644 plugins/Actman/ua/ua.pas create mode 100644 plugins/Actman/ua/ua.rc create mode 100644 plugins/Actman/ua/ua.res (limited to 'plugins/Actman') 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 Binary files /dev/null and b/plugins/Actman/hooks/hooks.res 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 = ''; + +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,'',sbuf); + StrCopy(buf1,setting); + StrReplace(buf1,'',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,'',IntToStr(buf,aparam)); + StrReplaceW(tmp,'' ,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)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,'')<>nil then + begin + mGetMem(tmpc1,8192); + StrCopyW(tmpc1,msgtitle); + StrReplaceW(tmpc1,'',tmpc); + end + else + tmpc1:=msgtitle; + if StrPosW(msgtext,'')<>nil then + begin + mGetMem(tmpc2,8192); + StrCopyW(tmpc2,msgtext); + StrReplaceW(tmpc2,'',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 i0 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 i0 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 i0 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=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 replacing'#13#10+ + 'by last result'#13#10#13#10+ + 'Text 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 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)0); + EnableWindow(GetDlgItem(Dialog,IDC_GROUP_DOWN), + (num+1)0; + end; +{ + else + begin + okup :=num>0; + okdown:=(num+1)0); + EnableWindow(GetDlgItem(Dialog,IDC_ACTION_DOWN), + (num+1)=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 NumGroups0 then + begin + act:=@ActionList[1]; + while MaxActions>0 do + begin + FreeAction(act); + inc(act); + dec(MaxActions); + end; + FreeMem(ActionList); + end; +} + NumActions:=DBReadWord(0,DBBranch,opt_numacts,ActListPage); + if NumActions0 then // not needed in normal cases + begin + StrCopy(p,opt_id ); id :=DBReadDWord (0,DBBranch,section); + StrCopy(p,opt_descr); descr:=DBReadUnicode(0,DBBranch,section,nil); + if descr=nil then + StrDupW(descr,TranslateW('No Description')); + + StrCopy(p,opt_numacts); num:=DBReadWord(0,DBBranch,section); + p^:=#0; + firstAction:=LoadActions(section,num); + end; + end; + inc(HK); + inc(i); + end; + fCLfilter:=DBReadByte (0,DBBranch,'CLfilter',0)<>0; + fCLformat:=DBReadUnicode(0,DBBranch,'CLformat'); +end; 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 Binary files /dev/null and b/plugins/Actman/ico/advance.ico differ diff --git a/plugins/Actman/ico/apply.ico b/plugins/Actman/ico/apply.ico new file mode 100644 index 0000000000..80c3802c09 Binary files /dev/null and b/plugins/Actman/ico/apply.ico differ diff --git a/plugins/Actman/ico/chain.ico b/plugins/Actman/ico/chain.ico new file mode 100644 index 0000000000..3a98b8ac30 Binary files /dev/null and b/plugins/Actman/ico/chain.ico differ diff --git a/plugins/Actman/ico/contact.ico b/plugins/Actman/ico/contact.ico new file mode 100644 index 0000000000..8174fa221a Binary files /dev/null and b/plugins/Actman/ico/contact.ico differ diff --git a/plugins/Actman/ico/delete.ico b/plugins/Actman/ico/delete.ico new file mode 100644 index 0000000000..eea851da19 Binary files /dev/null and b/plugins/Actman/ico/delete.ico differ diff --git a/plugins/Actman/ico/down.ico b/plugins/Actman/ico/down.ico new file mode 100644 index 0000000000..d4fdb83bbf Binary files /dev/null and b/plugins/Actman/ico/down.ico differ diff --git a/plugins/Actman/ico/export.ico b/plugins/Actman/ico/export.ico new file mode 100644 index 0000000000..ddddb59074 Binary files /dev/null and b/plugins/Actman/ico/export.ico differ diff --git a/plugins/Actman/ico/format.ico b/plugins/Actman/ico/format.ico new file mode 100644 index 0000000000..ddddb59074 Binary files /dev/null and b/plugins/Actman/ico/format.ico differ diff --git a/plugins/Actman/ico/import.ico b/plugins/Actman/ico/import.ico new file mode 100644 index 0000000000..481da4dbaf Binary files /dev/null and b/plugins/Actman/ico/import.ico differ diff --git a/plugins/Actman/ico/insert.ico b/plugins/Actman/ico/insert.ico new file mode 100644 index 0000000000..481da4dbaf Binary files /dev/null and b/plugins/Actman/ico/insert.ico differ diff --git a/plugins/Actman/ico/message.ico b/plugins/Actman/ico/message.ico new file mode 100644 index 0000000000..fa6c604542 Binary files /dev/null and b/plugins/Actman/ico/message.ico differ diff --git a/plugins/Actman/ico/new.ico b/plugins/Actman/ico/new.ico new file mode 100644 index 0000000000..73937210e0 Binary files /dev/null and b/plugins/Actman/ico/new.ico differ diff --git a/plugins/Actman/ico/program.ico b/plugins/Actman/ico/program.ico new file mode 100644 index 0000000000..30c7df1875 Binary files /dev/null and b/plugins/Actman/ico/program.ico differ diff --git a/plugins/Actman/ico/reload.ico b/plugins/Actman/ico/reload.ico new file mode 100644 index 0000000000..dc070c5083 Binary files /dev/null and b/plugins/Actman/ico/reload.ico differ diff --git a/plugins/Actman/ico/rw.ico b/plugins/Actman/ico/rw.ico new file mode 100644 index 0000000000..d5927ebb08 Binary files /dev/null and b/plugins/Actman/ico/rw.ico differ diff --git a/plugins/Actman/ico/service.ico b/plugins/Actman/ico/service.ico new file mode 100644 index 0000000000..ddddb59074 Binary files /dev/null and b/plugins/Actman/ico/service.ico differ diff --git a/plugins/Actman/ico/test.ico b/plugins/Actman/ico/test.ico new file mode 100644 index 0000000000..345530ba76 Binary files /dev/null and b/plugins/Actman/ico/test.ico differ diff --git a/plugins/Actman/ico/up.ico b/plugins/Actman/ico/up.ico new file mode 100644 index 0000000000..56fde31eda Binary files /dev/null and b/plugins/Actman/ico/up.ico differ diff --git a/plugins/Actman/ico/vcheck.ico b/plugins/Actman/ico/vcheck.ico new file mode 100644 index 0000000000..3f4afbbb01 Binary files /dev/null and b/plugins/Actman/ico/vcheck.ico differ diff --git a/plugins/Actman/ico/vuncheck.ico b/plugins/Actman/ico/vuncheck.ico new file mode 100644 index 0000000000..9587919f5b Binary files /dev/null and b/plugins/Actman/ico/vuncheck.ico 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 Binary files /dev/null and b/plugins/Actman/options.res 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) +'' 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: + - parameter + - 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 +'' in module name will be replaced with contact protocol name + +-- MessageBox + Subaction uses for standard windows MessageBox showing. text 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: numberhelp +;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:/Bookmarks] +wparam=0 +lparam=0 +plugin=Jabber +descr=Manage Jabber Bookmarks + +[Service:/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:/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:/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:/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 Binary files /dev/null and b/plugins/Actman/tasks/tasks.res differ diff --git a/plugins/Actman/ua/action.ico b/plugins/Actman/ua/action.ico new file mode 100644 index 0000000000..9e4c60d9d3 Binary files /dev/null and b/plugins/Actman/ua/action.ico 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 num0 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 Binary files /dev/null and b/plugins/Actman/ua/ua.res differ -- cgit v1.2.3