summaryrefslogtreecommitdiff
path: root/plugins/Actman30/hooks
diff options
context:
space:
mode:
authorVadim Dashevskiy <watcherhd@gmail.com>2013-07-16 20:08:30 +0000
committerVadim Dashevskiy <watcherhd@gmail.com>2013-07-16 20:08:30 +0000
commit74e738f374f759723daf8920677158712d0ca5c1 (patch)
tree89a93d70f87e950e28d23466d3c84120ead0e770 /plugins/Actman30/hooks
parente5c9c0077f7b50bbfe90201154c31c13e1a6fc63 (diff)
- Actman 3 added (not adopted)
git-svn-id: http://svn.miranda-ng.org/main/trunk@5391 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/Actman30/hooks')
-rw-r--r--plugins/Actman30/hooks/hooks.pas69
-rw-r--r--plugins/Actman30/hooks/hooks.rc28
-rw-r--r--plugins/Actman30/hooks/i_hconst.inc20
-rw-r--r--plugins/Actman30/hooks/i_hook.inc154
-rw-r--r--plugins/Actman30/hooks/i_opt_dlg.inc419
-rw-r--r--plugins/Actman30/hooks/i_options.inc71
6 files changed, 761 insertions, 0 deletions
diff --git a/plugins/Actman30/hooks/hooks.pas b/plugins/Actman30/hooks/hooks.pas
new file mode 100644
index 0000000000..02ab937cab
--- /dev/null
+++ b/plugins/Actman30/hooks/hooks.pas
@@ -0,0 +1,69 @@
+unit hooks;
+
+interface
+
+implementation
+
+uses
+ windows, commctrl, messages,
+ mirutils, common, dbsettings, 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/Actman30/hooks/hooks.rc b/plugins/Actman30/hooks/hooks.rc
new file mode 100644
index 0000000000..ff351cc94d
--- /dev/null
+++ b/plugins/Actman30/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/Actman30/hooks/i_hconst.inc b/plugins/Actman30/hooks/i_hconst.inc
new file mode 100644
index 0000000000..d011278b7e
--- /dev/null
+++ b/plugins/Actman30/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/Actman30/hooks/i_hook.inc b/plugins/Actman30/hooks/i_hook.inc
new file mode 100644
index 0000000000..8b7b487d98
--- /dev/null
+++ b/plugins/Actman30/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/Actman30/hooks/i_opt_dlg.inc b/plugins/Actman30/hooks/i_opt_dlg.inc
new file mode 100644
index 0000000000..012fc5b361
--- /dev/null
+++ b/plugins/Actman30/hooks/i_opt_dlg.inc
@@ -0,0 +1,419 @@
+{}
+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_ITEMW;
+ p:pAnsiChar;
+ buf:array [0..127] of WideChar;
+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;
+ p:=ApiCard.NameFromList(GetDlgItem(Dialog,IDC_EVENTLIST));
+ li.pszText :=FastAnsitoWideBuf(p,buf);
+ //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),
+ DBReadByte(0,DBBranch,'SrvListMode'));
+
+ FillActionList(GetDlgItem(Dialog,IDC_ACTIONLIST));
+ FillHookList(wnd);
+ ShowHookData(Dialog);
+
+ onactchanged:=HookEvent(ME_ACT_CHANGED,@ActListChange);
+ settings:=Dialog;
+ end;
+
+ WM_HELP: begin
+ tmp:=ApiCard.NameFromList(GetDlgItem(Dialog,IDC_EVENTLIST));
+ ApiCard.Event:=tmp;
+ mFreeMem(tmp);
+ 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: SendMessage(Dialog,WM_HELP,0,0);
+ 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/Actman30/hooks/i_options.inc b/plugins/Actman30/hooks/i_options.inc
new file mode 100644
index 0000000000..4404cfbde6
--- /dev/null
+++ b/plugins/Actman30/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;