powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / EventHook [32\64]bit
21 сообщений из 21, страница 1 из 1
EventHook [32\64]bit
    #39702998
Гирлионайльдо
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Предоставляю вашему вниманию собственную разработку хука над обработчиками событий

Как это может быть полезно?

Это может быть полезно для каких нибудь программ вроде конструкторов, которые могут в реальном времени просматривать цепочки разных событий - и их аргументы.

К примеру, нам надо создать в интерпретаторе объект какого нибудь класса. И потом, перехватить вызов нажатия кнопки, и передать к примеру в Lua коллбэк. Имитируя вызов Lua функции.

Скрипт вышел довольно маленький. По этому могу выложить сюда под спойлер

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
unit EventHook;

interface

uses
  Generics.Collections,
  Rtti,
  TypInfo,
  System.SysUtils;

const
  paEAX = Word(0);
  paEDX = Word(1);
  paECX = Word(2);
  paStack = Word(3);

type
  ParamInfo = record
    Stack: Boolean;
    Offset: Integer;
    Param: TRttiParameter;
  end;

  PParameters = ^TParameters;

  TParameters = packed record
    Registers: array [paEAX .. paStack] of NativeUInt;
    Stack: array [0 .. 255 * SizeOf(Pointer)] of Byte;
  end;

  TAddresParams = TArray<ParamInfo>;

  TBaseEvent = class
  private
    AddresParams: TAddresParams;
    MethodDefault: TMethod;
    StackSize: Byte;
    procedure EventCall;
    procedure Handler;
  public
    Sender: TObject;
    InfoArgs: TArray<TRttiParameter>;
    LengthArgs: Byte;
    PropType: TRttiProperty;
    EventName: string;
    constructor Create(aSender: TObject; _PropType: TRttiProperty);
    destructor Destroy;
  end;

  TEventBeforeNotify = reference to procedure(Base: TBaseEvent;
    Params: TArray<TValue>);

  TEventHook = class
  private
    RttiContext: TRttiContext;
    FlList: TDictionary<String, TBaseEvent>;
    FOnBefore: TEventBeforeNotify;
  public
    property OnBefore: TEventBeforeNotify read FOnBefore write FOnBefore;
    function Add(aSender: TObject; PropName: string): Boolean;
    function Rem(aSender: TObject; PropName: string): Boolean;
    constructor Create();
    destructor Destroy;
  end;

var
  EventHookObject: TEventHook;

implementation

constructor TEventHook.Create();
begin
  FlList := TDictionary<String, TBaseEvent>.Create();
end;

var
  Parameters: PParameters;

procedure TBaseEvent.Handler;
var
  I, r: Byte;
  Offset: Integer;
  P: ParamInfo;
  Params: TArray<TValue>;
  TAddr: Pointer;
begin
  SetLength(Params, LengthArgs);
{$IFDEF CPUX64}
  Parameters := Pointer(NativeUInt(Parameters) + $38);
{$ENDIF}
  Offset := NativeUInt(Parameters) + StackSize;
  for I := Low(AddresParams) to High(AddresParams) do
  begin
    P := AddresParams[I];
    if P.Stack then
      TAddr := @Parameters.Registers[P.Offset]
    else
      TAddr := @Parameters.Stack[P.Offset];

    if P.Param.Flags * [pfVar, pfOut] <> [] then
      TAddr := Pointer(TAddr^);

    TValue.Make(TAddr, P.Param.ParamType.Handle, Params[I]);
  end;

  if @EventHookObject.OnBefore <> nil then
    EventHookObject.OnBefore(self, Params);
end;

procedure TBaseEvent.EventCall; assembler;
asm
  {$IFDEF CPUX86}
  push ebp
  push eax
  push ecx
  push edx
  mov Parameters, esp
  call TEventHook.Handler
  pop edx
  pop ecx
  pop eax
  pop ebp

  MOV ECX, DWORD PTR  SELF.StackSize
  pop [esp+ecx-4]
  lea esp,[esp+ecx-4]
  {$ELSE}
  push rbp
  sub rsp,$20
  mov rbp,rsp
  mov [rbp+$30],rcx
  mov [rbp+$38],rdx
  mov [rbp+$40],r8
  mov [rbp+$48],r9
  mov rcx,[rbp+$30]
  mov Parameters, rbp
  call TEventHook.Handler
  lea rsp, [rbp + $20]
  pop rbp
  {$ENDIF}
end;

constructor TBaseEvent.Create(aSender: TObject; _PropType: TRttiProperty);
var
  I, CurReg, Calc: Integer;
  Param: TRttiParameter;
begin
  Sender := aSender;
  PropType := _PropType;
  EventName := PropType.Name;
  InfoArgs := TRttiInvokableType(PropType.PropertyType).GetParameters;
  LengthArgs := Length(InfoArgs);

  CurReg := paEAX;
  StackSize := 0;
  SetLength(AddresParams, LengthArgs);
  Calc := 0;

  for I := 0 to LengthArgs - 1 do
  begin
    with AddresParams[I] do
    begin
      Param := InfoArgs[I];
      Stack := (Param.ParamType.TypeSize <= SizeOf(Pointer)) and (CurReg <=
{$IFDEF CPUX86}paEDX {$ELSE}paStack {$ENDIF});
      if Stack then
      begin
        Offset := CurReg;
        StackSize := (LengthArgs - Offset - 1) * SizeOf(Pointer);
{$IFDEF CPUX86}
        Calc := StackSize;
{$ENDIF}
        inc(CurReg);
      end
      else
      begin
        Offset := Calc;

{$IFDEF CPUX86} dec {$ELSE}inc{$ENDIF}(Calc, SizeOf(Pointer));
      end;
    end;
  end;
end;

destructor TBaseEvent.Destroy;
begin
  SetLength(InfoArgs, 0);
  SetLength(AddresParams, 0);
end;

function TEventHook.Add(aSender: TObject; PropName: string): Boolean;
var
  m: TMethod;
  Base: TBaseEvent;
  NameCase: string;
  Prop: TRttiProperty;
begin
  Result := false;

  Prop := RttiContext.GetType(aSender.ClassInfo).GetProperty(PropName);

  if (Prop <> nil) then
  begin
    NameCase := IntToStr(NativeUInt(aSender)) + '_' + PropName;
    if not FlList.TryGetValue(NameCase, Base) then
    begin
      Base := TBaseEvent.Create(aSender, Prop);

      Base.MethodDefault := GetMethodProp(aSender, PropName);

      TObject(m.Data) := Base;
      m.Code := @TBaseEvent.EventCall;

      FlList.Add(NameCase, Base);

      Result := true;
    end;
    if Result then
      setMethodProp(aSender, PropName, m);
  end;
end;

function TEventHook.Rem(aSender: TObject; PropName: string): Boolean;
var
  NameCase: string;
  Base: TBaseEvent;
begin
  Result := false;

  NameCase := IntToStr(NativeUInt(aSender)) + '_' + PropName;
  if FlList.TryGetValue(NameCase, Base) then
  begin
    setMethodProp(Base.Sender, Base.EventName, Base.MethodDefault);
    Base.Destroy;

    FlList.Remove(NameCase);

    Result := true;
  end;
end;

destructor TEventHook.Destroy;
var
  Item: TPair<String, TBaseEvent>;
begin
  for Item in FlList do
    Item.Value.Destroy;

  FlList.Free;
end;

initialization

EventHookObject := TEventHook.Create;

finalization

EventHookObject.Destroy;

end.



И конечно же сам проект
...
Рейтинг: 0 / 0
EventHook [32\64]bit
    #39702999
Гирлионайльдо
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
EventHook [32\64]bit
    #39703018
ziv-2014
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гирлионайльдо, Одно плохо, есть код на асме, поэтому нельзя будет использовать на кросплатформе.
...
Рейтинг: 0 / 0
EventHook [32\64]bit
    #39703021
Гирлионайльдо
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ziv-2014,

Под 64 битный компилятор и не нужен ассемблер. А вот под 32 обязательно. Так как я пока не понял, как мне размер стека сдать (Попробую пока пошаманить из кода)

Работает адекватно только под 64 битный
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
unit EventHook;

interface

uses
  Generics.Collections,
  Rtti,
  TypInfo,
  System.SysUtils, vcl.dialogs;

const
  paEAX = Word(0);
  paEDX = Word(1);
  paECX = Word(2);
  paStack = Word(3);

type
  ParamInfo = record
    Stack: Boolean;
    Offset: Integer;
    Param: TRttiParameter;
  end;

  PParameters = ^TParameters;

  TParameters = packed record
    Registers: array [paEAX .. paStack] of NativeUInt;
    Stack: array [0 .. 255 * SizeOf(Pointer)] of Byte;
  end;

  TAddresParams = TArray<ParamInfo>;

  TBaseEvent = class
  private
    AddresParams: TAddresParams;
    MethodDefault: TMethod;
    StackSize: Byte;
    function EventCall(A, V, C, f: NativeUInt): NativeUInt;
    procedure Handler;
  public
    Sender: TObject;
    InfoArgs: TArray<TRttiParameter>;
    LengthArgs: Byte;
    PropType: TRttiProperty;
    EventName: string;
    constructor Create(aSender: TObject; _PropType: TRttiProperty);
    destructor Destroy;
  end;

  TEventBeforeNotify = reference to procedure(Base: TBaseEvent;
    Params: TArray<TValue>);

  TEventHook = class
  private
    RttiContext: TRttiContext;
    FlList: TDictionary<String, TBaseEvent>;
    FOnBefore: TEventBeforeNotify;
  public
    property OnBefore: TEventBeforeNotify read FOnBefore write FOnBefore;
    function Add(aSender: TObject; PropName: string): Boolean;
    function Rem(aSender: TObject; PropName: string): Boolean;
    constructor Create();
    destructor Destroy;
  end;

var
  EventHookObject: TEventHook;

implementation

constructor TEventHook.Create();
begin
  FlList := TDictionary<String, TBaseEvent>.Create();
end;

var
  Parameters: PParameters;

procedure TBaseEvent.Handler;
var
  I, r: Byte;
  P: ParamInfo;
  Params: TArray<TValue>;
  TAddr: Pointer;
begin
  SetLength(Params, LengthArgs);
  for I := Low(AddresParams) to High(AddresParams) do
  begin
    P := AddresParams[I];
    if P.Stack then
      TAddr := @Parameters.Registers[P.Offset]
    else
      TAddr := @Parameters.Stack[P.Offset];

    if P.Param.Flags * [pfVar, pfOut] <> [] then
      TAddr := Pointer(TAddr^);

    TValue.Make(TAddr, P.Param.ParamType.Handle, Params[I]);
  end;

  if @EventHookObject.OnBefore <> nil then
    EventHookObject.OnBefore(self, Params);
end;

function TBaseEvent.EventCall(A, V, C, f: NativeUInt): NativeUInt;
begin
  Parameters :=
{$IFDEF CPUX86}Pointer(NativeUInt(@Result) - SizeOf(Pointer))
{$ELSE}@A{$ENDIF};
  Handler;
end;

constructor TBaseEvent.Create(aSender: TObject; _PropType: TRttiProperty);
var
  I, CurReg, Calc: Integer;
  Param: TRttiParameter;
begin
  Sender := aSender;
  PropType := _PropType;
  EventName := PropType.Name;
  InfoArgs := TRttiInvokableType(PropType.PropertyType).GetParameters;
  LengthArgs := Length(InfoArgs);

  CurReg := paEAX;
  StackSize := 0;
  SetLength(AddresParams, LengthArgs);
  Calc := 0;

  for I := 0 to LengthArgs - 1 do
  begin
    with AddresParams[I] do
    begin
      Param := InfoArgs[I];
      Stack := (Param.ParamType.TypeSize <= SizeOf(Pointer)) and (CurReg <=
{$IFDEF CPUX86}paEDX {$ELSE}paStack {$ENDIF});
      if Stack then
      begin
        Offset := CurReg;
        StackSize := (LengthArgs - Offset - 1) * SizeOf(Pointer);
{$IFDEF CPUX86}
        Calc := StackSize;
{$ENDIF}
        inc(CurReg);
      end
      else
      begin
        Offset := Calc;

{$IFDEF CPUX86} dec {$ELSE}inc{$ENDIF}(Calc, SizeOf(Pointer));
      end;
    end;
  end;
end;

destructor TBaseEvent.Destroy;
begin
  setMethodProp(Sender, EventName, MethodDefault);
  SetLength(InfoArgs, 0);
  SetLength(AddresParams, 0);
end;

function TEventHook.Add(aSender: TObject; PropName: string): Boolean;
var
  m: TMethod;
  Base: TBaseEvent;
  NameCase: string;
  Prop: TRttiProperty;
begin
  Result := false;

  Prop := RttiContext.GetType(aSender.ClassInfo).GetProperty(PropName);

  if (Prop <> nil) then
  begin
    NameCase := IntToStr(NativeUInt(aSender)) + '_' + PropName;
    if not FlList.TryGetValue(NameCase, Base) then
    begin
      Base := TBaseEvent.Create(aSender, Prop);

      Base.MethodDefault := GetMethodProp(aSender, PropName);

      TObject(m.Data) := Base;
      m.Code := @TBaseEvent.EventCall;

      FlList.Add(NameCase, Base);

      Result := true;
    end;
    if Result then
      setMethodProp(aSender, PropName, m);
  end;
end;

function TEventHook.Rem(aSender: TObject; PropName: string): Boolean;
var
  NameCase: string;
  Base: TBaseEvent;
begin
  Result := false;

  NameCase := IntToStr(NativeUInt(aSender)) + '_' + PropName;
  if FlList.TryGetValue(NameCase, Base) then
  begin
    Base.Destroy;

    FlList.Remove(NameCase);

    Result := true;
  end;
end;

destructor TEventHook.Destroy;
var
  Item: TPair<String, TBaseEvent>;
begin
  for Item in FlList do
    Item.Value.Destroy;

  FlList.Free;
end;

initialization

EventHookObject := TEventHook.Create;

finalization

EventHookObject.Destroy;

end.

...
Рейтинг: 0 / 0
EventHook [32\64]bit
    #39703039
ziv-2014
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гирлионайльдо,
есть еще всякие arm и андроиды и iOs - такую штуку хочется иметь кросс-платформенную.
...
Рейтинг: 0 / 0
EventHook [32\64]bit
    #39703193
Гирлионайльдо
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот вам, полностью кроссплатформенный, для 32 и 64 битной системы

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
295.
296.
297.
298.
299.
300.
301.
302.
303.
304.
305.
306.
307.
308.
309.
310.
311.
312.
313.
314.
315.
316.
317.
318.
319.
320.
321.
322.
323.
324.
325.
326.
327.
328.
329.
330.
331.
332.
333.
334.
335.
336.
337.
338.
339.
340.
341.
342.
343.
344.
345.
346.
347.
348.
349.
350.
351.
352.
353.
354.
355.
356.
357.
358.
359.
360.
361.
362.
363.
364.
365.
366.
367.
368.
369.
370.
371.
372.
373.
374.
375.
376.
377.
378.
379.
380.
381.
382.
383.
384.
385.
386.
387.
388.
389.
390.
391.
392.
393.
394.
395.
396.
397.
398.
399.
400.
401.
402.
403.
404.
405.
406.
407.
408.
409.
410.
411.
412.
413.
414.
415.
416.
417.
418.
419.
420.
421.
422.
423.
424.
425.
426.
427.
428.
429.
430.
431.
432.
433.
434.
435.
436.
437.
438.
439.
440.
441.
442.
443.
444.
445.
446.
447.
448.
449.
450.
451.
452.
453.
454.
455.
456.
457.
458.
459.
460.
461.
462.
463.
464.
465.
466.
467.
468.
469.
470.
471.
472.
473.
474.
475.
476.
477.
478.
479.
480.
481.
482.
483.
484.
485.
486.
487.
488.
489.
490.
491.
492.
493.
494.
495.
496.
497.
498.
499.
500.
501.
502.
503.
504.
505.
506.
507.
508.
509.
510.
511.
512.
513.
514.
515.
516.
517.
518.
519.
520.
521.
522.
523.
524.
525.
526.
527.
528.
529.
530.
531.
532.
533.
534.
535.
536.
537.
538.
539.
540.
541.
542.
543.
544.
545.
546.
547.
548.
549.
550.
551.
552.
553.
554.
555.
556.
557.
558.
559.
560.
561.
562.
563.
564.
565.
566.
567.
568.
569.
570.
571.
572.
573.
574.
575.
576.
577.
578.
579.
580.
581.
582.
583.
584.
585.
586.
587.
588.
589.
590.
591.
592.
593.
594.
595.
596.
597.
598.
599.
600.
601.
602.
603.
604.
605.
606.
607.
608.
609.
610.
611.
612.
613.
614.
615.
616.
617.
618.
619.
620.
621.
622.
623.
624.
625.
626.
627.
628.
629.
630.
631.
632.
633.
634.
635.
636.
637.
638.
639.
640.
641.
642.
643.
644.
645.
646.
647.
648.
649.
650.
651.
652.
653.
654.
655.
656.
657.
658.
659.
660.
661.
662.
663.
664.
665.
666.
667.
668.
669.
670.
671.
672.
673.
674.
675.
676.
677.
678.
679.
680.
681.
682.
683.
684.
685.
686.
687.
688.
689.
690.
691.
692.
693.
694.
695.
696.
697.
698.
699.
700.
701.
702.
703.
704.
705.
706.
707.
708.
709.
710.
711.
712.
713.
714.
715.
716.
717.
718.
719.
720.
721.
722.
723.
724.
725.
726.
727.
728.
729.
730.
731.
732.
733.
734.
735.
736.
737.
738.
739.
740.
741.
742.
743.
744.
745.
746.
747.
748.
749.
750.
751.
752.
753.
754.
755.
756.
757.
758.
759.
760.
761.
762.
763.
764.
765.
766.
767.
768.
769.
770.
771.
772.
773.
774.
775.
776.
777.
778.
779.
780.
781.
782.
783.
784.
785.
786.
787.
788.
789.
790.
791.
792.
793.
794.
795.
796.
797.
798.
799.
800.
801.
802.
803.
804.
805.
806.
807.
808.
809.
810.
811.
812.
813.
814.
815.
816.
817.
818.
819.
820.
821.
822.
823.
824.
825.
826.
827.
828.
829.
830.
831.
832.
833.
834.
835.
836.
837.
838.
839.
840.
841.
842.
843.
844.
845.
846.
847.
848.
849.
850.
851.
852.
853.
854.
855.
856.
857.
858.
859.
860.
861.
862.
863.
864.
865.
866.
867.
868.
869.
870.
871.
872.
873.
874.
875.
876.
877.
878.
879.
880.
881.
882.
883.
884.
885.
886.
887.
888.
889.
890.
891.
892.
893.
894.
895.
896.
897.
898.
899.
900.
901.
902.
903.
904.
905.
906.
907.
908.
909.
910.
911.
912.
913.
914.
915.
916.
917.
918.
919.
920.
921.
922.
923.
924.
925.
926.
927.
928.
929.
930.
931.
932.
933.
934.
935.
936.
937.
938.
939.
940.
941.
942.
943.
944.
945.
946.
947.
948.
949.
950.
951.
952.
953.
954.
955.
956.
957.
958.
959.
960.
961.
962.
963.
964.
965.
966.
967.
968.
969.
970.
971.
972.
973.
974.
975.
976.
977.
978.
979.
980.
981.
982.
983.
984.
985.
986.
987.
988.
989.
990.
991.
992.
993.
994.
995.
996.
997.
998.
999.
1000.
1001.
1002.
1003.
1004.
1005.
1006.
1007.
1008.
1009.
1010.
1011.
1012.
1013.
1014.
1015.
1016.
1017.
1018.
1019.
1020.
1021.
1022.
1023.
1024.
1025.
1026.
1027.
1028.
1029.
1030.
1031.
1032.
1033.
1034.
1035.
1036.
1037.
1038.
1039.
1040.
1041.
1042.
1043.
1044.
1045.
1046.
1047.
1048.
1049.
1050.
1051.
1052.
1053.
1054.
1055.
1056.
1057.
1058.
1059.
1060.
1061.
1062.
1063.
1064.
1065.
1066.
1067.
1068.
1069.
1070.
1071.
1072.
1073.
1074.
1075.
1076.
1077.
1078.
1079.
1080.
1081.
1082.
1083.
1084.
1085.
1086.
1087.
1088.
1089.
1090.
1091.
1092.
1093.
1094.
1095.
1096.
1097.
1098.
1099.
1100.
1101.
1102.
1103.
1104.
1105.
1106.
1107.
1108.
1109.
1110.
1111.
1112.
1113.
unit EventHook;

interface

uses
  Generics.Collections,
  Rtti,
  TypInfo,
  System.SysUtils, vcl.dialogs;

type

  TBaseEvent = class
  private
    MethodDefault: TMethod;
    StackSize: Byte;

    Procedure EventCall1(A1: NativeUInt);
    Procedure EventCall2(A1, A2: NativeUInt);
    Procedure EventCall3(A1, A2, A3: NativeUInt);
    Procedure EventCall4(A1, A2, A3, A4: NativeUInt);
    Procedure EventCall5(A1, A2, A3, A4, A5: NativeUInt);
    Procedure EventCall6(A1, A2, A3, A4, A5, A6: NativeUInt);
    Procedure EventCall7(A1, A2, A3, A4, A5, A6, A7: NativeUInt);
    Procedure EventCall8(A1, A2, A3, A4, A5, A6, A7, A8: NativeUInt);
    Procedure EventCall9(A1, A2, A3, A4, A5, A6, A7, A8, A9: NativeUInt);
    Procedure EventCall10(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10: NativeUInt);
    Procedure EventCall11(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10,
      A11: NativeUInt);
    Procedure EventCall12(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11,
      A12: NativeUInt);
    Procedure EventCall13(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
      A13: NativeUInt);
    Procedure EventCall14(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
      A13, A14: NativeUInt);
    Procedure EventCall15(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
      A13, A14, A15: NativeUInt);
    Procedure EventCall16(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
      A13, A14, A15, A16: NativeUInt);
    Procedure EventCall17(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
      A13, A14, A15, A16, A17: NativeUInt);
    Procedure EventCall18(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
      A13, A14, A15, A16, A17, A18: NativeUInt);
    Procedure EventCall19(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
      A13, A14, A15, A16, A17, A18, A19: NativeUInt);
    Procedure EventCall20(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
      A13, A14, A15, A16, A17, A18, A19, A20: NativeUInt);
    Procedure EventCall21(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
      A13, A14, A15, A16, A17, A18, A19, A20, A21: NativeUInt);
    Procedure EventCall22(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
      A13, A14, A15, A16, A17, A18, A19, A20, A21, A22: NativeUInt);
    Procedure EventCall23(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
      A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23: NativeUInt);
    Procedure EventCall24(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
      A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24: NativeUInt);
    Procedure EventCall25(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
      A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24,
      A25: NativeUInt);
    Procedure EventCall26(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
      A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25,
      A26: NativeUInt);
    Procedure EventCall27(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
      A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25, A26,
      A27: NativeUInt);
    Procedure EventCall28(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
      A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25, A26, A27,
      A28: NativeUInt);
    Procedure EventCall29(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
      A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25, A26, A27,
      A28, A29: NativeUInt);
    Procedure EventCall30(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
      A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25, A26, A27,
      A28, A29, A30: NativeUInt);
    Procedure EventCall31(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
      A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25, A26, A27,
      A28, A29, A30, A31: NativeUInt);
    Procedure EventCall32(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
      A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25, A26, A27,
      A28, A29, A30, A31, A32: NativeUInt);
    Procedure EventCall33(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
      A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25, A26, A27,
      A28, A29, A30, A31, A32, A33: NativeUInt);
    Procedure EventCall34(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
      A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25, A26, A27,
      A28, A29, A30, A31, A32, A33, A34: NativeUInt);
    Procedure EventCall35(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
      A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25, A26, A27,
      A28, A29, A30, A31, A32, A33, A34, A35: NativeUInt);
    Procedure EventCall36(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
      A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25, A26, A27,
      A28, A29, A30, A31, A32, A33, A34, A35, A36: NativeUInt);

    procedure Handler;
  public
    PointArgs: array [0 .. 35] of Pointer;

    Sender: TObject;
    InfoArgs: TArray<TRttiParameter>;
    LengthArgs: Byte;
    PropType: TRttiProperty;
    EventName: string;
    constructor Create(aSender: TObject; _PropType: TRttiProperty);
    destructor Destroy;
  end;

  TEventBeforeNotify = reference to procedure(Base: TBaseEvent;
    Params: TArray<TValue>);

  TEventHook = class
  private
    RttiContext: TRttiContext;
    FlList: TDictionary<String, TBaseEvent>;
    FOnBefore: TEventBeforeNotify;
  public
    property OnBefore: TEventBeforeNotify read FOnBefore write FOnBefore;
    function Add(aSender: TObject; PropName: string): Boolean;
    function Rem(aSender: TObject; PropName: string): Boolean;
    constructor Create();
    destructor Destroy;
  end;

var
  EventHookObject: TEventHook;

implementation

constructor TEventHook.Create();
begin
  FlList := TDictionary<String, TBaseEvent>.Create();
end;

procedure TBaseEvent.Handler;
var
  I: Byte;
  Params: TArray<TValue>;
begin
  SetLength(Params, LengthArgs);
  for I := Low(InfoArgs) to High(InfoArgs) do
    TValue.Make(self.PointArgs[I], InfoArgs[I].ParamType.Handle, Params[I]);

  if @EventHookObject.OnBefore <> nil then
    EventHookObject.OnBefore(self, Params);
end;

constructor TBaseEvent.Create(aSender: TObject; _PropType: TRttiProperty);
begin
  Sender := aSender;
  PropType := _PropType;
  EventName := PropType.Name;
  InfoArgs := TRttiInvokableType(PropType.PropertyType).GetParameters;
  LengthArgs := Length(InfoArgs);
end;

destructor TBaseEvent.Destroy;
begin
  setMethodProp(Sender, EventName, MethodDefault);
  SetLength(InfoArgs, 0);
end;

function TEventHook.Add(aSender: TObject; PropName: string): Boolean;
var
  m: TMethod;
  Base: TBaseEvent;
  NameCase: string;
  Prop: TRttiProperty;
begin
  Result := false;

  Prop := RttiContext.GetType(aSender.ClassInfo).GetProperty(PropName);

  if (Prop <> nil) then
  begin
    NameCase := IntToStr(NativeUInt(aSender)) + '_' + PropName;
    if not FlList.TryGetValue(NameCase, Base) then
    begin
      Base := TBaseEvent.Create(aSender, Prop);
      Base.MethodDefault := GetMethodProp(aSender, PropName);

      TObject(m.Data) := Base;

      case Base.LengthArgs of
        0: m.Code := @TBaseEvent.Handler;
        1: m.Code := @TBaseEvent.EventCall1;
        2: m.Code := @TBaseEvent.EventCall2;
        3: m.Code := @TBaseEvent.EventCall3;
        4: m.Code := @TBaseEvent.EventCall4;
        5: m.Code := @TBaseEvent.EventCall5;
        6: m.Code := @TBaseEvent.EventCall6;
        7: m.Code := @TBaseEvent.EventCall7;
        8: m.Code := @TBaseEvent.EventCall8;
        9: m.Code := @TBaseEvent.EventCall9;
        10: m.Code := @TBaseEvent.EventCall10;
        11: m.Code := @TBaseEvent.EventCall11;
        12: m.Code := @TBaseEvent.EventCall12;
        13: m.Code := @TBaseEvent.EventCall13;
        14: m.Code := @TBaseEvent.EventCall14;
        15: m.Code := @TBaseEvent.EventCall15;
        16: m.Code := @TBaseEvent.EventCall16;
        17: m.Code := @TBaseEvent.EventCall17;
        18: m.Code := @TBaseEvent.EventCall18;
        19: m.Code := @TBaseEvent.EventCall19;
        20: m.Code := @TBaseEvent.EventCall20;
        21: m.Code := @TBaseEvent.EventCall21;
        22: m.Code := @TBaseEvent.EventCall22;
        23: m.Code := @TBaseEvent.EventCall23;
        24: m.Code := @TBaseEvent.EventCall24;
        25: m.Code := @TBaseEvent.EventCall25;
        26: m.Code := @TBaseEvent.EventCall26;
        27: m.Code := @TBaseEvent.EventCall27;
        28: m.Code := @TBaseEvent.EventCall28;
        29: m.Code := @TBaseEvent.EventCall29;
        30: m.Code := @TBaseEvent.EventCall30;
        31: m.Code := @TBaseEvent.EventCall31;
        32: m.Code := @TBaseEvent.EventCall32;
        33: m.Code := @TBaseEvent.EventCall33;
        34: m.Code := @TBaseEvent.EventCall34;
        35: m.Code := @TBaseEvent.EventCall35;
        36: m.Code := @TBaseEvent.EventCall36;
      end;

      FlList.Add(NameCase, Base);

      Result := true;
    end;
    if Result then
      setMethodProp(aSender, PropName, m);
  end;
end;

function TEventHook.Rem(aSender: TObject; PropName: string): Boolean;
var
  NameCase: string;
  Base: TBaseEvent;
begin
  Result := false;

  NameCase := IntToStr(NativeUInt(aSender)) + '_' + PropName;
  if FlList.TryGetValue(NameCase, Base) then
  begin
    Base.Destroy;

    FlList.Remove(NameCase);

    Result := true;
  end;
end;

destructor TEventHook.Destroy;
var
  Item: TPair<String, TBaseEvent>;
begin
  for Item in FlList do
    Item.Value.Destroy;

  FlList.Free;
end;

Procedure TBaseEvent.EventCall1;
begin
  PointArgs[0] := @A1;
  Handler
end;

Procedure TBaseEvent.EventCall2;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  Handler
end;

Procedure TBaseEvent.EventCall3;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  Handler
end;

Procedure TBaseEvent.EventCall4;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  Handler
end;

Procedure TBaseEvent.EventCall5;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  Handler
end;

Procedure TBaseEvent.EventCall6;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  Handler
end;

Procedure TBaseEvent.EventCall7;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  Handler
end;

Procedure TBaseEvent.EventCall8;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  Handler
end;

Procedure TBaseEvent.EventCall9;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  Handler
end;

Procedure TBaseEvent.EventCall10;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  Handler
end;

Procedure TBaseEvent.EventCall11;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  PointArgs[10] := @A11;
  Handler
end;

Procedure TBaseEvent.EventCall12;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  PointArgs[10] := @A11;
  PointArgs[11] := @A12;
  Handler
end;

Procedure TBaseEvent.EventCall13;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  PointArgs[10] := @A11;
  PointArgs[11] := @A12;
  PointArgs[12] := @A13;
  Handler
end;

Procedure TBaseEvent.EventCall14;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  PointArgs[10] := @A11;
  PointArgs[11] := @A12;
  PointArgs[12] := @A13;
  PointArgs[13] := @A14;
  Handler
end;

Procedure TBaseEvent.EventCall15;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  PointArgs[10] := @A11;
  PointArgs[11] := @A12;
  PointArgs[12] := @A13;
  PointArgs[13] := @A14;
  PointArgs[14] := @A15;
  Handler
end;

Procedure TBaseEvent.EventCall16;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  PointArgs[10] := @A11;
  PointArgs[11] := @A12;
  PointArgs[12] := @A13;
  PointArgs[13] := @A14;
  PointArgs[14] := @A15;
  PointArgs[15] := @A16;
  Handler
end;

Procedure TBaseEvent.EventCall17;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  PointArgs[10] := @A11;
  PointArgs[11] := @A12;
  PointArgs[12] := @A13;
  PointArgs[13] := @A14;
  PointArgs[14] := @A15;
  PointArgs[15] := @A16;
  PointArgs[16] := @A17;
  Handler
end;

Procedure TBaseEvent.EventCall18;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  PointArgs[10] := @A11;
  PointArgs[11] := @A12;
  PointArgs[12] := @A13;
  PointArgs[13] := @A14;
  PointArgs[14] := @A15;
  PointArgs[15] := @A16;
  PointArgs[16] := @A17;
  PointArgs[17] := @A18;
  Handler
end;

Procedure TBaseEvent.EventCall19;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  PointArgs[10] := @A11;
  PointArgs[11] := @A12;
  PointArgs[12] := @A13;
  PointArgs[13] := @A14;
  PointArgs[14] := @A15;
  PointArgs[15] := @A16;
  PointArgs[16] := @A17;
  PointArgs[17] := @A18;
  PointArgs[18] := @A19;
  Handler
end;

Procedure TBaseEvent.EventCall20;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  PointArgs[10] := @A11;
  PointArgs[11] := @A12;
  PointArgs[12] := @A13;
  PointArgs[13] := @A14;
  PointArgs[14] := @A15;
  PointArgs[15] := @A16;
  PointArgs[16] := @A17;
  PointArgs[17] := @A18;
  PointArgs[18] := @A19;
  PointArgs[19] := @A20;
  Handler
end;

Procedure TBaseEvent.EventCall21;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  PointArgs[10] := @A11;
  PointArgs[11] := @A12;
  PointArgs[12] := @A13;
  PointArgs[13] := @A14;
  PointArgs[14] := @A15;
  PointArgs[15] := @A16;
  PointArgs[16] := @A17;
  PointArgs[17] := @A18;
  PointArgs[18] := @A19;
  PointArgs[19] := @A20;
  PointArgs[20] := @A21;
  Handler
end;

Procedure TBaseEvent.EventCall22;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  PointArgs[10] := @A11;
  PointArgs[11] := @A12;
  PointArgs[12] := @A13;
  PointArgs[13] := @A14;
  PointArgs[14] := @A15;
  PointArgs[15] := @A16;
  PointArgs[16] := @A17;
  PointArgs[17] := @A18;
  PointArgs[18] := @A19;
  PointArgs[19] := @A20;
  PointArgs[20] := @A21;
  PointArgs[21] := @A22;
  Handler
end;

Procedure TBaseEvent.EventCall23;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  PointArgs[10] := @A11;
  PointArgs[11] := @A12;
  PointArgs[12] := @A13;
  PointArgs[13] := @A14;
  PointArgs[14] := @A15;
  PointArgs[15] := @A16;
  PointArgs[16] := @A17;
  PointArgs[17] := @A18;
  PointArgs[18] := @A19;
  PointArgs[19] := @A20;
  PointArgs[20] := @A21;
  PointArgs[21] := @A22;
  PointArgs[22] := @A23;
  Handler
end;

Procedure TBaseEvent.EventCall24;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  PointArgs[10] := @A11;
  PointArgs[11] := @A12;
  PointArgs[12] := @A13;
  PointArgs[13] := @A14;
  PointArgs[14] := @A15;
  PointArgs[15] := @A16;
  PointArgs[16] := @A17;
  PointArgs[17] := @A18;
  PointArgs[18] := @A19;
  PointArgs[19] := @A20;
  PointArgs[20] := @A21;
  PointArgs[21] := @A22;
  PointArgs[22] := @A23;
  PointArgs[23] := @A24;
  Handler
end;

Procedure TBaseEvent.EventCall25;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  PointArgs[10] := @A11;
  PointArgs[11] := @A12;
  PointArgs[12] := @A13;
  PointArgs[13] := @A14;
  PointArgs[14] := @A15;
  PointArgs[15] := @A16;
  PointArgs[16] := @A17;
  PointArgs[17] := @A18;
  PointArgs[18] := @A19;
  PointArgs[19] := @A20;
  PointArgs[20] := @A21;
  PointArgs[21] := @A22;
  PointArgs[22] := @A23;
  PointArgs[23] := @A24;
  PointArgs[24] := @A25;
  Handler
end;

Procedure TBaseEvent.EventCall26;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  PointArgs[10] := @A11;
  PointArgs[11] := @A12;
  PointArgs[12] := @A13;
  PointArgs[13] := @A14;
  PointArgs[14] := @A15;
  PointArgs[15] := @A16;
  PointArgs[16] := @A17;
  PointArgs[17] := @A18;
  PointArgs[18] := @A19;
  PointArgs[19] := @A20;
  PointArgs[20] := @A21;
  PointArgs[21] := @A22;
  PointArgs[22] := @A23;
  PointArgs[23] := @A24;
  PointArgs[24] := @A25;
  PointArgs[25] := @A26;
  Handler
end;

Procedure TBaseEvent.EventCall27;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  PointArgs[10] := @A11;
  PointArgs[11] := @A12;
  PointArgs[12] := @A13;
  PointArgs[13] := @A14;
  PointArgs[14] := @A15;
  PointArgs[15] := @A16;
  PointArgs[16] := @A17;
  PointArgs[17] := @A18;
  PointArgs[18] := @A19;
  PointArgs[19] := @A20;
  PointArgs[20] := @A21;
  PointArgs[21] := @A22;
  PointArgs[22] := @A23;
  PointArgs[23] := @A24;
  PointArgs[24] := @A25;
  PointArgs[25] := @A26;
  PointArgs[26] := @A27;
  Handler
end;

Procedure TBaseEvent.EventCall28;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  PointArgs[10] := @A11;
  PointArgs[11] := @A12;
  PointArgs[12] := @A13;
  PointArgs[13] := @A14;
  PointArgs[14] := @A15;
  PointArgs[15] := @A16;
  PointArgs[16] := @A17;
  PointArgs[17] := @A18;
  PointArgs[18] := @A19;
  PointArgs[19] := @A20;
  PointArgs[20] := @A21;
  PointArgs[21] := @A22;
  PointArgs[22] := @A23;
  PointArgs[23] := @A24;
  PointArgs[24] := @A25;
  PointArgs[25] := @A26;
  PointArgs[26] := @A27;
  PointArgs[27] := @A28;
  Handler
end;

Procedure TBaseEvent.EventCall29;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  PointArgs[10] := @A11;
  PointArgs[11] := @A12;
  PointArgs[12] := @A13;
  PointArgs[13] := @A14;
  PointArgs[14] := @A15;
  PointArgs[15] := @A16;
  PointArgs[16] := @A17;
  PointArgs[17] := @A18;
  PointArgs[18] := @A19;
  PointArgs[19] := @A20;
  PointArgs[20] := @A21;
  PointArgs[21] := @A22;
  PointArgs[22] := @A23;
  PointArgs[23] := @A24;
  PointArgs[24] := @A25;
  PointArgs[25] := @A26;
  PointArgs[26] := @A27;
  PointArgs[27] := @A28;
  PointArgs[28] := @A29;
  Handler
end;

Procedure TBaseEvent.EventCall30;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  PointArgs[10] := @A11;
  PointArgs[11] := @A12;
  PointArgs[12] := @A13;
  PointArgs[13] := @A14;
  PointArgs[14] := @A15;
  PointArgs[15] := @A16;
  PointArgs[16] := @A17;
  PointArgs[17] := @A18;
  PointArgs[18] := @A19;
  PointArgs[19] := @A20;
  PointArgs[20] := @A21;
  PointArgs[21] := @A22;
  PointArgs[22] := @A23;
  PointArgs[23] := @A24;
  PointArgs[24] := @A25;
  PointArgs[25] := @A26;
  PointArgs[26] := @A27;
  PointArgs[27] := @A28;
  PointArgs[28] := @A29;
  PointArgs[29] := @A30;
  Handler
end;

Procedure TBaseEvent.EventCall31;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  PointArgs[10] := @A11;
  PointArgs[11] := @A12;
  PointArgs[12] := @A13;
  PointArgs[13] := @A14;
  PointArgs[14] := @A15;
  PointArgs[15] := @A16;
  PointArgs[16] := @A17;
  PointArgs[17] := @A18;
  PointArgs[18] := @A19;
  PointArgs[19] := @A20;
  PointArgs[20] := @A21;
  PointArgs[21] := @A22;
  PointArgs[22] := @A23;
  PointArgs[23] := @A24;
  PointArgs[24] := @A25;
  PointArgs[25] := @A26;
  PointArgs[26] := @A27;
  PointArgs[27] := @A28;
  PointArgs[28] := @A29;
  PointArgs[29] := @A30;
  PointArgs[30] := @A31;
  Handler
end;

Procedure TBaseEvent.EventCall32;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  PointArgs[10] := @A11;
  PointArgs[11] := @A12;
  PointArgs[12] := @A13;
  PointArgs[13] := @A14;
  PointArgs[14] := @A15;
  PointArgs[15] := @A16;
  PointArgs[16] := @A17;
  PointArgs[17] := @A18;
  PointArgs[18] := @A19;
  PointArgs[19] := @A20;
  PointArgs[20] := @A21;
  PointArgs[21] := @A22;
  PointArgs[22] := @A23;
  PointArgs[23] := @A24;
  PointArgs[24] := @A25;
  PointArgs[25] := @A26;
  PointArgs[26] := @A27;
  PointArgs[27] := @A28;
  PointArgs[28] := @A29;
  PointArgs[29] := @A30;
  PointArgs[30] := @A31;
  PointArgs[31] := @A32;
  Handler
end;

Procedure TBaseEvent.EventCall33;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  PointArgs[10] := @A11;
  PointArgs[11] := @A12;
  PointArgs[12] := @A13;
  PointArgs[13] := @A14;
  PointArgs[14] := @A15;
  PointArgs[15] := @A16;
  PointArgs[16] := @A17;
  PointArgs[17] := @A18;
  PointArgs[18] := @A19;
  PointArgs[19] := @A20;
  PointArgs[20] := @A21;
  PointArgs[21] := @A22;
  PointArgs[22] := @A23;
  PointArgs[23] := @A24;
  PointArgs[24] := @A25;
  PointArgs[25] := @A26;
  PointArgs[26] := @A27;
  PointArgs[27] := @A28;
  PointArgs[28] := @A29;
  PointArgs[29] := @A30;
  PointArgs[30] := @A31;
  PointArgs[31] := @A32;
  PointArgs[32] := @A33;
  Handler
end;

Procedure TBaseEvent.EventCall34;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  PointArgs[10] := @A11;
  PointArgs[11] := @A12;
  PointArgs[12] := @A13;
  PointArgs[13] := @A14;
  PointArgs[14] := @A15;
  PointArgs[15] := @A16;
  PointArgs[16] := @A17;
  PointArgs[17] := @A18;
  PointArgs[18] := @A19;
  PointArgs[19] := @A20;
  PointArgs[20] := @A21;
  PointArgs[21] := @A22;
  PointArgs[22] := @A23;
  PointArgs[23] := @A24;
  PointArgs[24] := @A25;
  PointArgs[25] := @A26;
  PointArgs[26] := @A27;
  PointArgs[27] := @A28;
  PointArgs[28] := @A29;
  PointArgs[29] := @A30;
  PointArgs[30] := @A31;
  PointArgs[31] := @A32;
  PointArgs[32] := @A33;
  PointArgs[33] := @A34;
  Handler
end;

Procedure TBaseEvent.EventCall35;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  PointArgs[10] := @A11;
  PointArgs[11] := @A12;
  PointArgs[12] := @A13;
  PointArgs[13] := @A14;
  PointArgs[14] := @A15;
  PointArgs[15] := @A16;
  PointArgs[16] := @A17;
  PointArgs[17] := @A18;
  PointArgs[18] := @A19;
  PointArgs[19] := @A20;
  PointArgs[20] := @A21;
  PointArgs[21] := @A22;
  PointArgs[22] := @A23;
  PointArgs[23] := @A24;
  PointArgs[24] := @A25;
  PointArgs[25] := @A26;
  PointArgs[26] := @A27;
  PointArgs[27] := @A28;
  PointArgs[28] := @A29;
  PointArgs[29] := @A30;
  PointArgs[30] := @A31;
  PointArgs[31] := @A32;
  PointArgs[32] := @A33;
  PointArgs[33] := @A34;
  PointArgs[34] := @A35;
  Handler
end;

Procedure TBaseEvent.EventCall36;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  PointArgs[10] := @A11;
  PointArgs[11] := @A12;
  PointArgs[12] := @A13;
  PointArgs[13] := @A14;
  PointArgs[14] := @A15;
  PointArgs[15] := @A16;
  PointArgs[16] := @A17;
  PointArgs[17] := @A18;
  PointArgs[18] := @A19;
  PointArgs[19] := @A20;
  PointArgs[20] := @A21;
  PointArgs[21] := @A22;
  PointArgs[22] := @A23;
  PointArgs[23] := @A24;
  PointArgs[24] := @A25;
  PointArgs[25] := @A26;
  PointArgs[26] := @A27;
  PointArgs[27] := @A28;
  PointArgs[28] := @A29;
  PointArgs[29] := @A30;
  PointArgs[30] := @A31;
  PointArgs[31] := @A32;
  PointArgs[32] := @A33;
  PointArgs[33] := @A34;
  PointArgs[34] := @A35;
  PointArgs[35] := @A36;

  Handler;
end;

initialization

EventHookObject := TEventHook.Create;

finalization

EventHookObject.Destroy;

end.

...
Рейтинг: 0 / 0
EventHook [32\64]bit
    #39703195
Гирлионайльдо
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Забыл добавить обработку var и out

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
295.
296.
297.
298.
299.
300.
301.
302.
303.
304.
305.
306.
307.
308.
309.
310.
311.
312.
313.
314.
315.
316.
317.
318.
319.
320.
321.
322.
323.
324.
325.
326.
327.
328.
329.
330.
331.
332.
333.
334.
335.
336.
337.
338.
339.
340.
341.
342.
343.
344.
345.
346.
347.
348.
349.
350.
351.
352.
353.
354.
355.
356.
357.
358.
359.
360.
361.
362.
363.
364.
365.
366.
367.
368.
369.
370.
371.
372.
373.
374.
375.
376.
377.
378.
379.
380.
381.
382.
383.
384.
385.
386.
387.
388.
389.
390.
391.
392.
393.
394.
395.
396.
397.
398.
399.
400.
401.
402.
403.
404.
405.
406.
407.
408.
409.
410.
411.
412.
413.
414.
415.
416.
417.
418.
419.
420.
421.
422.
423.
424.
425.
426.
427.
428.
429.
430.
431.
432.
433.
434.
435.
436.
437.
438.
439.
440.
441.
442.
443.
444.
445.
446.
447.
448.
449.
450.
451.
452.
453.
454.
455.
456.
457.
458.
459.
460.
461.
462.
463.
464.
465.
466.
467.
468.
469.
470.
471.
472.
473.
474.
475.
476.
477.
478.
479.
480.
481.
482.
483.
484.
485.
486.
487.
488.
489.
490.
491.
492.
493.
494.
495.
496.
497.
498.
499.
500.
501.
502.
503.
504.
505.
506.
507.
508.
509.
510.
511.
512.
513.
514.
515.
516.
517.
518.
519.
520.
521.
522.
523.
524.
525.
526.
527.
528.
529.
530.
531.
532.
533.
534.
535.
536.
537.
538.
539.
540.
541.
542.
543.
544.
545.
546.
547.
548.
549.
550.
551.
552.
553.
554.
555.
556.
557.
558.
559.
560.
561.
562.
563.
564.
565.
566.
567.
568.
569.
570.
571.
572.
573.
574.
575.
576.
577.
578.
579.
580.
581.
582.
583.
584.
585.
586.
587.
588.
589.
590.
591.
592.
593.
594.
595.
596.
597.
598.
599.
600.
601.
602.
603.
604.
605.
606.
607.
608.
609.
610.
611.
612.
613.
614.
615.
616.
617.
618.
619.
620.
621.
622.
623.
624.
625.
626.
627.
628.
629.
630.
631.
632.
633.
634.
635.
636.
637.
638.
639.
640.
641.
642.
643.
644.
645.
646.
647.
648.
649.
650.
651.
652.
653.
654.
655.
656.
657.
658.
659.
660.
661.
662.
663.
664.
665.
666.
667.
668.
669.
670.
671.
672.
673.
674.
675.
676.
677.
678.
679.
680.
681.
682.
683.
684.
685.
686.
687.
688.
689.
690.
691.
692.
693.
694.
695.
696.
697.
698.
699.
700.
701.
702.
703.
704.
705.
706.
707.
708.
709.
710.
711.
712.
713.
714.
715.
716.
717.
718.
719.
720.
721.
722.
723.
724.
725.
726.
727.
728.
729.
730.
731.
732.
733.
734.
735.
736.
737.
738.
739.
740.
741.
742.
743.
744.
745.
746.
747.
748.
749.
750.
751.
752.
753.
754.
755.
756.
757.
758.
759.
760.
761.
762.
763.
764.
765.
766.
767.
768.
769.
770.
771.
772.
773.
774.
775.
776.
777.
778.
779.
780.
781.
782.
783.
784.
785.
786.
787.
788.
789.
790.
791.
792.
793.
794.
795.
796.
797.
798.
799.
800.
801.
802.
803.
804.
805.
806.
807.
808.
809.
810.
811.
812.
813.
814.
815.
816.
817.
818.
819.
820.
821.
822.
823.
824.
825.
826.
827.
828.
829.
830.
831.
832.
833.
834.
835.
836.
837.
838.
839.
840.
841.
842.
843.
844.
845.
846.
847.
848.
849.
850.
851.
852.
853.
854.
855.
856.
857.
858.
859.
860.
861.
862.
863.
864.
865.
866.
867.
868.
869.
870.
871.
872.
873.
874.
875.
876.
877.
878.
879.
880.
881.
882.
883.
884.
885.
886.
887.
888.
889.
890.
891.
892.
893.
894.
895.
896.
897.
898.
899.
900.
901.
902.
903.
904.
905.
906.
907.
908.
909.
910.
911.
912.
913.
914.
915.
916.
917.
918.
919.
920.
921.
922.
923.
924.
925.
926.
927.
928.
929.
930.
931.
932.
933.
934.
935.
936.
937.
938.
939.
940.
941.
942.
943.
944.
945.
946.
947.
948.
949.
950.
951.
952.
953.
954.
955.
956.
957.
958.
959.
960.
961.
962.
963.
964.
965.
966.
967.
968.
969.
970.
971.
972.
973.
974.
975.
976.
977.
978.
979.
980.
981.
982.
983.
984.
985.
986.
987.
988.
989.
990.
991.
992.
993.
994.
995.
996.
997.
998.
999.
1000.
1001.
1002.
1003.
1004.
1005.
1006.
1007.
1008.
1009.
1010.
1011.
1012.
1013.
1014.
1015.
1016.
1017.
1018.
1019.
1020.
1021.
1022.
1023.
1024.
1025.
1026.
1027.
1028.
1029.
1030.
1031.
1032.
1033.
1034.
1035.
1036.
1037.
1038.
1039.
1040.
1041.
1042.
1043.
1044.
1045.
1046.
1047.
1048.
1049.
1050.
1051.
1052.
1053.
1054.
1055.
1056.
1057.
1058.
1059.
1060.
1061.
1062.
1063.
1064.
1065.
1066.
1067.
1068.
1069.
1070.
1071.
1072.
1073.
1074.
1075.
1076.
1077.
1078.
1079.
1080.
1081.
1082.
1083.
1084.
1085.
1086.
1087.
1088.
1089.
1090.
1091.
1092.
1093.
1094.
1095.
1096.
1097.
1098.
1099.
1100.
1101.
1102.
1103.
1104.
1105.
1106.
1107.
1108.
1109.
1110.
1111.
1112.
1113.
1114.
1115.
1116.
1117.
1118.
1119.
1120.
1121.
1122.
1123.
1124.
1125.
1126.
1127.
1128.
1129.
1130.
1131.
1132.
1133.
1134.
1135.
1136.
1137.
1138.
1139.
1140.
1141.
1142.
1143.
1144.
1145.
1146.
1147.
1148.
1149.
1150.
1151.
1152.
1153.
1154.
1155.
1156.
1157.
unit EventHook;

interface

uses
  Generics.Collections,
  Rtti,
  TypInfo,
  System.SysUtils, vcl.dialogs;

type

  TBaseEvent = class
  private
    MethodDefault: TMethod;
    StackSize: Byte;

    Procedure EventCall1(A1: NativeUInt);
    Procedure EventCall2(A1, A2: NativeUInt);
    Procedure EventCall3(A1, A2, A3: NativeUInt);
    Procedure EventCall4(A1, A2, A3, A4: NativeUInt);
    Procedure EventCall5(A1, A2, A3, A4, A5: NativeUInt);
    Procedure EventCall6(A1, A2, A3, A4, A5, A6: NativeUInt);
    Procedure EventCall7(A1, A2, A3, A4, A5, A6, A7: NativeUInt);
    Procedure EventCall8(A1, A2, A3, A4, A5, A6, A7, A8: NativeUInt);
    Procedure EventCall9(A1, A2, A3, A4, A5, A6, A7, A8, A9: NativeUInt);
    Procedure EventCall10(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10: NativeUInt);
    Procedure EventCall11(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10,
      A11: NativeUInt);
    Procedure EventCall12(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11,
      A12: NativeUInt);
    Procedure EventCall13(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
      A13: NativeUInt);
    Procedure EventCall14(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
      A13, A14: NativeUInt);
    Procedure EventCall15(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
      A13, A14, A15: NativeUInt);
    Procedure EventCall16(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
      A13, A14, A15, A16: NativeUInt);
    Procedure EventCall17(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
      A13, A14, A15, A16, A17: NativeUInt);
    Procedure EventCall18(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
      A13, A14, A15, A16, A17, A18: NativeUInt);
    Procedure EventCall19(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
      A13, A14, A15, A16, A17, A18, A19: NativeUInt);
    Procedure EventCall20(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
      A13, A14, A15, A16, A17, A18, A19, A20: NativeUInt);
    Procedure EventCall21(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
      A13, A14, A15, A16, A17, A18, A19, A20, A21: NativeUInt);
    Procedure EventCall22(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
      A13, A14, A15, A16, A17, A18, A19, A20, A21, A22: NativeUInt);
    Procedure EventCall23(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
      A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23: NativeUInt);
    Procedure EventCall24(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
      A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24: NativeUInt);
    Procedure EventCall25(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
      A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24,
      A25: NativeUInt);
    Procedure EventCall26(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
      A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25,
      A26: NativeUInt);
    Procedure EventCall27(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
      A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25, A26,
      A27: NativeUInt);
    Procedure EventCall28(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
      A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25, A26, A27,
      A28: NativeUInt);
    Procedure EventCall29(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
      A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25, A26, A27,
      A28, A29: NativeUInt);
    Procedure EventCall30(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
      A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25, A26, A27,
      A28, A29, A30: NativeUInt);
    Procedure EventCall31(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
      A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25, A26, A27,
      A28, A29, A30, A31: NativeUInt);
    Procedure EventCall32(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
      A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25, A26, A27,
      A28, A29, A30, A31, A32: NativeUInt);
    Procedure EventCall33(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
      A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25, A26, A27,
      A28, A29, A30, A31, A32, A33: NativeUInt);
    Procedure EventCall34(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
      A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25, A26, A27,
      A28, A29, A30, A31, A32, A33, A34: NativeUInt);
    Procedure EventCall35(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
      A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25, A26, A27,
      A28, A29, A30, A31, A32, A33, A34, A35: NativeUInt);
    Procedure EventCall36(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12,
      A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25, A26, A27,
      A28, A29, A30, A31, A32, A33, A34, A35, A36: NativeUInt);

    procedure Handler;
  public
    PointArgs: array [0 .. 35] of Pointer;

    Sender: TObject;
    InfoArgs: TArray<TRttiParameter>;
    LengthArgs: Byte;
    PropType: TRttiProperty;
    EventName: string;
    constructor Create(aSender: TObject; _PropType: TRttiProperty);
    destructor Destroy;
  end;

  TEventBeforeNotify = reference to procedure(Base: TBaseEvent;
    Params: TArray<TValue>);

  TEventHook = class
  private
    RttiContext: TRttiContext;
    FlList: TDictionary<String, TBaseEvent>;
    FOnBefore: TEventBeforeNotify;
  public
    property OnBefore: TEventBeforeNotify read FOnBefore write FOnBefore;
    function Add(aSender: TObject; PropName: string): Boolean;
    function Rem(aSender: TObject; PropName: string): Boolean;
    constructor Create();
    destructor Destroy;
  end;

var
  EventHookObject: TEventHook;

implementation

constructor TEventHook.Create();
begin
  FlList := TDictionary<String, TBaseEvent>.Create();
end;

procedure TBaseEvent.Handler;
var
  I: Byte;
  Params: TArray<TValue>;
  P: Pointer;
begin
  SetLength(Params, LengthArgs);
  for I := Low(InfoArgs) to High(InfoArgs) do
  begin
    P := self.PointArgs[I];
    if InfoArgs[I].Flags * [pfVar, pfOut] <> [] then
      P := PPointer(P)^;

    TValue.Make(P, InfoArgs[I].ParamType.Handle, Params[I]);
  end;

  if @EventHookObject.OnBefore <> nil then
    EventHookObject.OnBefore(self, Params);
end;

constructor TBaseEvent.Create(aSender: TObject; _PropType: TRttiProperty);
begin
  Sender := aSender;
  PropType := _PropType;
  EventName := PropType.Name;
  InfoArgs := TRttiInvokableType(PropType.PropertyType).GetParameters;
  LengthArgs := Length(InfoArgs);
end;

destructor TBaseEvent.Destroy;
begin
  setMethodProp(Sender, EventName, MethodDefault);
  SetLength(InfoArgs, 0);
end;

function TEventHook.Add(aSender: TObject; PropName: string): Boolean;
var
  m: TMethod;
  Base: TBaseEvent;
  NameCase: string;
  Prop: TRttiProperty;
begin
  Result := false;

  Prop := RttiContext.GetType(aSender.ClassInfo).GetProperty(PropName);

  if (Prop <> nil) then
  begin
    NameCase := IntToStr(NativeUInt(aSender)) + '_' + PropName;
    if not FlList.TryGetValue(NameCase, Base) then
    begin
      Base := TBaseEvent.Create(aSender, Prop);
      Base.MethodDefault := GetMethodProp(aSender, PropName);

      TObject(m.Data) := Base;

      case Base.LengthArgs of
        0:
          m.Code := @TBaseEvent.Handler;
        1:
          m.Code := @TBaseEvent.EventCall1;
        2:
          m.Code := @TBaseEvent.EventCall2;
        3:
          m.Code := @TBaseEvent.EventCall3;
        4:
          m.Code := @TBaseEvent.EventCall4;
        5:
          m.Code := @TBaseEvent.EventCall5;
        6:
          m.Code := @TBaseEvent.EventCall6;
        7:
          m.Code := @TBaseEvent.EventCall7;
        8:
          m.Code := @TBaseEvent.EventCall8;
        9:
          m.Code := @TBaseEvent.EventCall9;
        10:
          m.Code := @TBaseEvent.EventCall10;
        11:
          m.Code := @TBaseEvent.EventCall11;
        12:
          m.Code := @TBaseEvent.EventCall12;
        13:
          m.Code := @TBaseEvent.EventCall13;
        14:
          m.Code := @TBaseEvent.EventCall14;
        15:
          m.Code := @TBaseEvent.EventCall15;
        16:
          m.Code := @TBaseEvent.EventCall16;
        17:
          m.Code := @TBaseEvent.EventCall17;
        18:
          m.Code := @TBaseEvent.EventCall18;
        19:
          m.Code := @TBaseEvent.EventCall19;
        20:
          m.Code := @TBaseEvent.EventCall20;
        21:
          m.Code := @TBaseEvent.EventCall21;
        22:
          m.Code := @TBaseEvent.EventCall22;
        23:
          m.Code := @TBaseEvent.EventCall23;
        24:
          m.Code := @TBaseEvent.EventCall24;
        25:
          m.Code := @TBaseEvent.EventCall25;
        26:
          m.Code := @TBaseEvent.EventCall26;
        27:
          m.Code := @TBaseEvent.EventCall27;
        28:
          m.Code := @TBaseEvent.EventCall28;
        29:
          m.Code := @TBaseEvent.EventCall29;
        30:
          m.Code := @TBaseEvent.EventCall30;
        31:
          m.Code := @TBaseEvent.EventCall31;
        32:
          m.Code := @TBaseEvent.EventCall32;
        33:
          m.Code := @TBaseEvent.EventCall33;
        34:
          m.Code := @TBaseEvent.EventCall34;
        35:
          m.Code := @TBaseEvent.EventCall35;
        36:
          m.Code := @TBaseEvent.EventCall36;
      end;

      FlList.Add(NameCase, Base);

      Result := true;
    end;
    if Result then
      setMethodProp(aSender, PropName, m);
  end;
end;

function TEventHook.Rem(aSender: TObject; PropName: string): Boolean;
var
  NameCase: string;
  Base: TBaseEvent;
begin
  Result := false;

  NameCase := IntToStr(NativeUInt(aSender)) + '_' + PropName;
  if FlList.TryGetValue(NameCase, Base) then
  begin
    Base.Destroy;

    FlList.Remove(NameCase);

    Result := true;
  end;
end;

destructor TEventHook.Destroy;
var
  Item: TPair<String, TBaseEvent>;
begin
  for Item in FlList do
    Item.Value.Destroy;

  FlList.Free;
end;

Procedure TBaseEvent.EventCall1;
begin
  PointArgs[0] := @A1;
  Handler
end;

Procedure TBaseEvent.EventCall2;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  Handler
end;

Procedure TBaseEvent.EventCall3;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  Handler
end;

Procedure TBaseEvent.EventCall4;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  Handler
end;

Procedure TBaseEvent.EventCall5;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  Handler
end;

Procedure TBaseEvent.EventCall6;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  Handler
end;

Procedure TBaseEvent.EventCall7;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  Handler
end;

Procedure TBaseEvent.EventCall8;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  Handler
end;

Procedure TBaseEvent.EventCall9;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  Handler
end;

Procedure TBaseEvent.EventCall10;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  Handler
end;

Procedure TBaseEvent.EventCall11;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  PointArgs[10] := @A11;
  Handler
end;

Procedure TBaseEvent.EventCall12;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  PointArgs[10] := @A11;
  PointArgs[11] := @A12;
  Handler
end;

Procedure TBaseEvent.EventCall13;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  PointArgs[10] := @A11;
  PointArgs[11] := @A12;
  PointArgs[12] := @A13;
  Handler
end;

Procedure TBaseEvent.EventCall14;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  PointArgs[10] := @A11;
  PointArgs[11] := @A12;
  PointArgs[12] := @A13;
  PointArgs[13] := @A14;
  Handler
end;

Procedure TBaseEvent.EventCall15;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  PointArgs[10] := @A11;
  PointArgs[11] := @A12;
  PointArgs[12] := @A13;
  PointArgs[13] := @A14;
  PointArgs[14] := @A15;
  Handler
end;

Procedure TBaseEvent.EventCall16;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  PointArgs[10] := @A11;
  PointArgs[11] := @A12;
  PointArgs[12] := @A13;
  PointArgs[13] := @A14;
  PointArgs[14] := @A15;
  PointArgs[15] := @A16;
  Handler
end;

Procedure TBaseEvent.EventCall17;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  PointArgs[10] := @A11;
  PointArgs[11] := @A12;
  PointArgs[12] := @A13;
  PointArgs[13] := @A14;
  PointArgs[14] := @A15;
  PointArgs[15] := @A16;
  PointArgs[16] := @A17;
  Handler
end;

Procedure TBaseEvent.EventCall18;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  PointArgs[10] := @A11;
  PointArgs[11] := @A12;
  PointArgs[12] := @A13;
  PointArgs[13] := @A14;
  PointArgs[14] := @A15;
  PointArgs[15] := @A16;
  PointArgs[16] := @A17;
  PointArgs[17] := @A18;
  Handler
end;

Procedure TBaseEvent.EventCall19;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  PointArgs[10] := @A11;
  PointArgs[11] := @A12;
  PointArgs[12] := @A13;
  PointArgs[13] := @A14;
  PointArgs[14] := @A15;
  PointArgs[15] := @A16;
  PointArgs[16] := @A17;
  PointArgs[17] := @A18;
  PointArgs[18] := @A19;
  Handler
end;

Procedure TBaseEvent.EventCall20;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  PointArgs[10] := @A11;
  PointArgs[11] := @A12;
  PointArgs[12] := @A13;
  PointArgs[13] := @A14;
  PointArgs[14] := @A15;
  PointArgs[15] := @A16;
  PointArgs[16] := @A17;
  PointArgs[17] := @A18;
  PointArgs[18] := @A19;
  PointArgs[19] := @A20;
  Handler
end;

Procedure TBaseEvent.EventCall21;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  PointArgs[10] := @A11;
  PointArgs[11] := @A12;
  PointArgs[12] := @A13;
  PointArgs[13] := @A14;
  PointArgs[14] := @A15;
  PointArgs[15] := @A16;
  PointArgs[16] := @A17;
  PointArgs[17] := @A18;
  PointArgs[18] := @A19;
  PointArgs[19] := @A20;
  PointArgs[20] := @A21;
  Handler
end;

Procedure TBaseEvent.EventCall22;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  PointArgs[10] := @A11;
  PointArgs[11] := @A12;
  PointArgs[12] := @A13;
  PointArgs[13] := @A14;
  PointArgs[14] := @A15;
  PointArgs[15] := @A16;
  PointArgs[16] := @A17;
  PointArgs[17] := @A18;
  PointArgs[18] := @A19;
  PointArgs[19] := @A20;
  PointArgs[20] := @A21;
  PointArgs[21] := @A22;
  Handler
end;

Procedure TBaseEvent.EventCall23;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  PointArgs[10] := @A11;
  PointArgs[11] := @A12;
  PointArgs[12] := @A13;
  PointArgs[13] := @A14;
  PointArgs[14] := @A15;
  PointArgs[15] := @A16;
  PointArgs[16] := @A17;
  PointArgs[17] := @A18;
  PointArgs[18] := @A19;
  PointArgs[19] := @A20;
  PointArgs[20] := @A21;
  PointArgs[21] := @A22;
  PointArgs[22] := @A23;
  Handler
end;

Procedure TBaseEvent.EventCall24;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  PointArgs[10] := @A11;
  PointArgs[11] := @A12;
  PointArgs[12] := @A13;
  PointArgs[13] := @A14;
  PointArgs[14] := @A15;
  PointArgs[15] := @A16;
  PointArgs[16] := @A17;
  PointArgs[17] := @A18;
  PointArgs[18] := @A19;
  PointArgs[19] := @A20;
  PointArgs[20] := @A21;
  PointArgs[21] := @A22;
  PointArgs[22] := @A23;
  PointArgs[23] := @A24;
  Handler
end;

Procedure TBaseEvent.EventCall25;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  PointArgs[10] := @A11;
  PointArgs[11] := @A12;
  PointArgs[12] := @A13;
  PointArgs[13] := @A14;
  PointArgs[14] := @A15;
  PointArgs[15] := @A16;
  PointArgs[16] := @A17;
  PointArgs[17] := @A18;
  PointArgs[18] := @A19;
  PointArgs[19] := @A20;
  PointArgs[20] := @A21;
  PointArgs[21] := @A22;
  PointArgs[22] := @A23;
  PointArgs[23] := @A24;
  PointArgs[24] := @A25;
  Handler
end;

Procedure TBaseEvent.EventCall26;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  PointArgs[10] := @A11;
  PointArgs[11] := @A12;
  PointArgs[12] := @A13;
  PointArgs[13] := @A14;
  PointArgs[14] := @A15;
  PointArgs[15] := @A16;
  PointArgs[16] := @A17;
  PointArgs[17] := @A18;
  PointArgs[18] := @A19;
  PointArgs[19] := @A20;
  PointArgs[20] := @A21;
  PointArgs[21] := @A22;
  PointArgs[22] := @A23;
  PointArgs[23] := @A24;
  PointArgs[24] := @A25;
  PointArgs[25] := @A26;
  Handler
end;

Procedure TBaseEvent.EventCall27;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  PointArgs[10] := @A11;
  PointArgs[11] := @A12;
  PointArgs[12] := @A13;
  PointArgs[13] := @A14;
  PointArgs[14] := @A15;
  PointArgs[15] := @A16;
  PointArgs[16] := @A17;
  PointArgs[17] := @A18;
  PointArgs[18] := @A19;
  PointArgs[19] := @A20;
  PointArgs[20] := @A21;
  PointArgs[21] := @A22;
  PointArgs[22] := @A23;
  PointArgs[23] := @A24;
  PointArgs[24] := @A25;
  PointArgs[25] := @A26;
  PointArgs[26] := @A27;
  Handler
end;

Procedure TBaseEvent.EventCall28;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  PointArgs[10] := @A11;
  PointArgs[11] := @A12;
  PointArgs[12] := @A13;
  PointArgs[13] := @A14;
  PointArgs[14] := @A15;
  PointArgs[15] := @A16;
  PointArgs[16] := @A17;
  PointArgs[17] := @A18;
  PointArgs[18] := @A19;
  PointArgs[19] := @A20;
  PointArgs[20] := @A21;
  PointArgs[21] := @A22;
  PointArgs[22] := @A23;
  PointArgs[23] := @A24;
  PointArgs[24] := @A25;
  PointArgs[25] := @A26;
  PointArgs[26] := @A27;
  PointArgs[27] := @A28;
  Handler
end;

Procedure TBaseEvent.EventCall29;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  PointArgs[10] := @A11;
  PointArgs[11] := @A12;
  PointArgs[12] := @A13;
  PointArgs[13] := @A14;
  PointArgs[14] := @A15;
  PointArgs[15] := @A16;
  PointArgs[16] := @A17;
  PointArgs[17] := @A18;
  PointArgs[18] := @A19;
  PointArgs[19] := @A20;
  PointArgs[20] := @A21;
  PointArgs[21] := @A22;
  PointArgs[22] := @A23;
  PointArgs[23] := @A24;
  PointArgs[24] := @A25;
  PointArgs[25] := @A26;
  PointArgs[26] := @A27;
  PointArgs[27] := @A28;
  PointArgs[28] := @A29;
  Handler
end;

Procedure TBaseEvent.EventCall30;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  PointArgs[10] := @A11;
  PointArgs[11] := @A12;
  PointArgs[12] := @A13;
  PointArgs[13] := @A14;
  PointArgs[14] := @A15;
  PointArgs[15] := @A16;
  PointArgs[16] := @A17;
  PointArgs[17] := @A18;
  PointArgs[18] := @A19;
  PointArgs[19] := @A20;
  PointArgs[20] := @A21;
  PointArgs[21] := @A22;
  PointArgs[22] := @A23;
  PointArgs[23] := @A24;
  PointArgs[24] := @A25;
  PointArgs[25] := @A26;
  PointArgs[26] := @A27;
  PointArgs[27] := @A28;
  PointArgs[28] := @A29;
  PointArgs[29] := @A30;
  Handler
end;

Procedure TBaseEvent.EventCall31;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  PointArgs[10] := @A11;
  PointArgs[11] := @A12;
  PointArgs[12] := @A13;
  PointArgs[13] := @A14;
  PointArgs[14] := @A15;
  PointArgs[15] := @A16;
  PointArgs[16] := @A17;
  PointArgs[17] := @A18;
  PointArgs[18] := @A19;
  PointArgs[19] := @A20;
  PointArgs[20] := @A21;
  PointArgs[21] := @A22;
  PointArgs[22] := @A23;
  PointArgs[23] := @A24;
  PointArgs[24] := @A25;
  PointArgs[25] := @A26;
  PointArgs[26] := @A27;
  PointArgs[27] := @A28;
  PointArgs[28] := @A29;
  PointArgs[29] := @A30;
  PointArgs[30] := @A31;
  Handler
end;

Procedure TBaseEvent.EventCall32;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  PointArgs[10] := @A11;
  PointArgs[11] := @A12;
  PointArgs[12] := @A13;
  PointArgs[13] := @A14;
  PointArgs[14] := @A15;
  PointArgs[15] := @A16;
  PointArgs[16] := @A17;
  PointArgs[17] := @A18;
  PointArgs[18] := @A19;
  PointArgs[19] := @A20;
  PointArgs[20] := @A21;
  PointArgs[21] := @A22;
  PointArgs[22] := @A23;
  PointArgs[23] := @A24;
  PointArgs[24] := @A25;
  PointArgs[25] := @A26;
  PointArgs[26] := @A27;
  PointArgs[27] := @A28;
  PointArgs[28] := @A29;
  PointArgs[29] := @A30;
  PointArgs[30] := @A31;
  PointArgs[31] := @A32;
  Handler
end;

Procedure TBaseEvent.EventCall33;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  PointArgs[10] := @A11;
  PointArgs[11] := @A12;
  PointArgs[12] := @A13;
  PointArgs[13] := @A14;
  PointArgs[14] := @A15;
  PointArgs[15] := @A16;
  PointArgs[16] := @A17;
  PointArgs[17] := @A18;
  PointArgs[18] := @A19;
  PointArgs[19] := @A20;
  PointArgs[20] := @A21;
  PointArgs[21] := @A22;
  PointArgs[22] := @A23;
  PointArgs[23] := @A24;
  PointArgs[24] := @A25;
  PointArgs[25] := @A26;
  PointArgs[26] := @A27;
  PointArgs[27] := @A28;
  PointArgs[28] := @A29;
  PointArgs[29] := @A30;
  PointArgs[30] := @A31;
  PointArgs[31] := @A32;
  PointArgs[32] := @A33;
  Handler
end;

Procedure TBaseEvent.EventCall34;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  PointArgs[10] := @A11;
  PointArgs[11] := @A12;
  PointArgs[12] := @A13;
  PointArgs[13] := @A14;
  PointArgs[14] := @A15;
  PointArgs[15] := @A16;
  PointArgs[16] := @A17;
  PointArgs[17] := @A18;
  PointArgs[18] := @A19;
  PointArgs[19] := @A20;
  PointArgs[20] := @A21;
  PointArgs[21] := @A22;
  PointArgs[22] := @A23;
  PointArgs[23] := @A24;
  PointArgs[24] := @A25;
  PointArgs[25] := @A26;
  PointArgs[26] := @A27;
  PointArgs[27] := @A28;
  PointArgs[28] := @A29;
  PointArgs[29] := @A30;
  PointArgs[30] := @A31;
  PointArgs[31] := @A32;
  PointArgs[32] := @A33;
  PointArgs[33] := @A34;
  Handler
end;

Procedure TBaseEvent.EventCall35;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  PointArgs[10] := @A11;
  PointArgs[11] := @A12;
  PointArgs[12] := @A13;
  PointArgs[13] := @A14;
  PointArgs[14] := @A15;
  PointArgs[15] := @A16;
  PointArgs[16] := @A17;
  PointArgs[17] := @A18;
  PointArgs[18] := @A19;
  PointArgs[19] := @A20;
  PointArgs[20] := @A21;
  PointArgs[21] := @A22;
  PointArgs[22] := @A23;
  PointArgs[23] := @A24;
  PointArgs[24] := @A25;
  PointArgs[25] := @A26;
  PointArgs[26] := @A27;
  PointArgs[27] := @A28;
  PointArgs[28] := @A29;
  PointArgs[29] := @A30;
  PointArgs[30] := @A31;
  PointArgs[31] := @A32;
  PointArgs[32] := @A33;
  PointArgs[33] := @A34;
  PointArgs[34] := @A35;
  Handler
end;

Procedure TBaseEvent.EventCall36;
begin
  PointArgs[0] := @A1;
  PointArgs[1] := @A2;
  PointArgs[2] := @A3;
  PointArgs[3] := @A4;
  PointArgs[4] := @A5;
  PointArgs[5] := @A6;
  PointArgs[6] := @A7;
  PointArgs[7] := @A8;
  PointArgs[8] := @A9;
  PointArgs[9] := @A10;
  PointArgs[10] := @A11;
  PointArgs[11] := @A12;
  PointArgs[12] := @A13;
  PointArgs[13] := @A14;
  PointArgs[14] := @A15;
  PointArgs[15] := @A16;
  PointArgs[16] := @A17;
  PointArgs[17] := @A18;
  PointArgs[18] := @A19;
  PointArgs[19] := @A20;
  PointArgs[20] := @A21;
  PointArgs[21] := @A22;
  PointArgs[22] := @A23;
  PointArgs[23] := @A24;
  PointArgs[24] := @A25;
  PointArgs[25] := @A26;
  PointArgs[26] := @A27;
  PointArgs[27] := @A28;
  PointArgs[28] := @A29;
  PointArgs[29] := @A30;
  PointArgs[30] := @A31;
  PointArgs[31] := @A32;
  PointArgs[32] := @A33;
  PointArgs[33] := @A34;
  PointArgs[34] := @A35;
  PointArgs[35] := @A36;

  Handler;
end;

initialization

EventHookObject := TEventHook.Create;

finalization

EventHookObject.Destroy;

end.

...
Рейтинг: 0 / 0
EventHook [32\64]bit
    #39703197
Гирлионайльдо
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Самый большой плюс нового скрипта в том, что можно легко вернуть var аргумент в нужный Кейс

К примеру, когда будем писать в Memo1. То всё время будет буква D

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
procedure TForm1.FormCreate(Sender: TObject);
begin
  EventHookObject.OnBefore :=
      procedure(Base: TBaseEvent; Params: TArray<TValue>)
    begin
      PChar(PPointer(Base.PointArgs[1])^)^ := 'D';
    end;

  EventHookObject.Add(Memo1, 'OnKeyPress');
end;
...
Рейтинг: 0 / 0
EventHook [32\64]bit
    #39703207
Гирлионайльдо
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Достаточно

Код: pascal
1.
 PChar(Base.PointArgs[1]^)^ := 'D';
...
Рейтинг: 0 / 0
EventHook [32\64]bit
    #39703276
Гирлионайльдо
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Продвинутая версия.

Умеет проверять, установлено ли событие

Код: pascal
1.
2.
3.
4.
5.
6.
7.
    function IsSet(aSender: TObject; PropName: string; var Base: TBaseEvent)
      : Boolean; overload;
    function IsSet(aSender: TObject; Prop: TRttiProperty; var Base: TBaseEvent)
      : Boolean; overload;

    function IsSet(aSender: TObject; PropName: string): Boolean; overload;
    function IsSet(aSender: TObject; Prop: TRttiProperty): Boolean; overload;



Умеет устанавливать событие (Последний аргумент Bool - будет ли вызван оригинальный колбэк установленный в Delphi коде)

Код: pascal
1.
2.
3.
4.
    function ESet(aSender: TObject; PropName: string; OrigCall: Boolean = false)
      : Boolean; overload;
    function ESet(aSender: TObject; Prop: TRttiProperty;
      OrigCall: Boolean = false): Boolean; overload;




Умеет добавлять пул - цепочку вызов (Срабатывает сначала OnBefore, потом весь пул по очереди. И только потом оригинальный колбэк - если установлен последний аргумент аналогично ESet)

Код: pascal
1.
2.
3.
4.
    function EAdd(aSender: TObject; PropName: string; Event: TEventBeforeNotify;
      OrigCall: Boolean = false): Boolean; overload;
    function EAdd(aSender: TObject; Prop: TRttiProperty;
      Event: TEventBeforeNotify; OrigCall: Boolean = false): Boolean; overload;



Умеет конечно же удалять весь хук (Восстанавливает оригинальный)
Код: pascal
1.
function ERem(aSender: TObject; PropName: string): Boolean;




Пример
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
procedure TForm3.FormCreate(Sender: TObject);
begin
  EventHookObject.OnBefore :=
      procedure(Base: TBaseEvent; Params: TArray<TValue>)
    begin
      showmessage('Я сработаю первым!');
    end;

  EventHookObject.EAdd(Memo1, 'OnKeyPress',
    procedure(Base: TBaseEvent; Params: TArray<TValue>)
    begin
      showmessage('Я сработаю вторым!');
    end);

  // Устаналиваем последний аргумент в true для Memo1KeyPress
  EventHookObject.EAdd(Memo1, 'OnKeyPress',
    procedure(Base: TBaseEvent; Params: TArray<TValue>)
    begin
      showmessage('Я сработаю третьим!');
    end, true);
end;

procedure TForm3.Memo1KeyPress(Sender: TObject; var Key: Char);
begin
  showmessage('Я сработаю четвёртым!');
end;

...
Рейтинг: 0 / 0
EventHook [32\64]bit
    #39703277
Гирлионайльдо
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Фикс
- Кодеген неудачный был

С
Код: pascal
1.
if OrigCall and (@MethodDefault.Code <> nil) then



На
Код: pascal
1.
if OrigCall and (MethodDefault.Code <> nil) then



Исправление
...
Рейтинг: 0 / 0
EventHook [32\64]bit
    #39703289
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Меня терзают смутные подозрения что ты путаешь этот форум с системой контроля версий.
...
Рейтинг: 0 / 0
EventHook [32\64]bit
    #39703324
Гирлионайльдо
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rgreat,

не путаю. Просто выкладываю своё творение в быт.


Идея проекта с моим скриптом - создать систему отладки, когда нужно знать все шаги - которые сделал пользователь

А именно, пройтись по всем установленным коллбэкам и добавить на них ещё один динамический Event и писать в лог - что в какое время происходит
...
Рейтинг: 0 / 0
EventHook [32\64]bit
    #39703730
white_nigger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вне зависимости от полезности опубликованного: Тебе байты исходников под расписку выделяют или пальцы поистерлись? Что за маразм в названиях EAdd, ESet? Нормально назвать, скажем, AddEvent религия не позволяет?
...
Рейтинг: 0 / 0
EventHook [32\64]bit
    #39703856
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
"Довольно маленький" скрипт превратился в какую-то адову портянку :) Не вчитывался что это и зачем. Но вопрос: нельзя ли как-то код объединить. Там 90% копипасты.
...
Рейтинг: 0 / 0
EventHook [32\64]bit
    #39703866
герли
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
makhaon,

Нельзя. Нельзя для 32 битного кода отдать размер стэка. По этому надо создать функции.


И это максимально оптимизировано. За счёт того что. Просто кладу аргументы в статический массив. По этому это норма



Считая к тому же что полная кроссплатформенность
...
Рейтинг: 0 / 0
EventHook [32\64]bit
    #39703868
чччД__
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Гирлионайльдо...
Идея проекта с моим скриптом - создать систему отладки, когда нужно знать все шаги - которые сделал пользователь

А именно, пройтись по всем установленным коллбэкам и добавить на них ещё один динамический Event и писать в лог - что в какое время происходит
Дичь какая-то.
Конкретно, кому именно и бл* чего именно может понадобиться твой чудесный код?
...
Рейтинг: 0 / 0
EventHook [32\64]bit
    #39703875
герли
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
чччД__,

Если ты придумать не можешь. То это не значит что он бесполезный. Америкосы бы по 2 тысячи долларов брали за систему отладки программы с помощью такого скрипта. А тут даром
...
Рейтинг: 0 / 0
EventHook [32\64]bit
    #39703878
ziv-2014
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
чччД__,
Мне, удобно!
...
Рейтинг: 0 / 0
EventHook [32\64]bit
    #39703900
чччД__
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
герли...Америкосы бы по 2 тысячи долларов брали за систему отладки программы с помощью такого скрипта...
У кого бы "брали"?
...
Рейтинг: 0 / 0
EventHook [32\64]bit
    #39704145
Гирлионайльдо
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
чччД__,

А я думал где же я видел.

21674363

Вот, тут видео. Где подобная система реализована.

Они могут ставить автоматически обработчики на все события (В частности нужные) для того, что бы знать что пользователь клацал - куда мышкой водил. Как водил.

Записывать данные в файлик - отображать через N программу. И даже воспроизводить действия


Мой скрипт позволяет тоже самое делать - на кроссплатформенности.

В добавок, его использование на этом не кончается. Его можно интегрировать в скриптовые движки

Будь это Lua - JS и так далее. Создавая динамические коллбэки, и используя Всю мощь!


А теперь посмотри как тут данное являение реализована - Ох она портянка
https://github.com/astoeckel/andorra/blob/3d303652fd31890bcad2f639c8535c32a0b56bba/src/AdVCLComponentEventConnector.pas#L149


...


https://github.com/eugenekryukov/jskit/blob/e9046c0930f8dbd19fda598aad0d8097be6da8b2/JSK.Base.pas#L175

(Создают куча - статических евентов, в которых вызывают определённые евенты)

- Никакой динамики. Говнокодство !
...
Рейтинг: 0 / 0
21 сообщений из 21, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / EventHook [32\64]bit
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]