{} 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;