I want to find a way to know that a form was created at run time (or destroyed). This for Delphi or fpc. Many thanks
PS : Is there a way to retrieve that info for all objects ?
I want to have a event that tells me that a new object was just created at run time (or destroyed).
There are no built in events that fire whenever an object is created or destroyed.
Because I like writing code hooks, I offer the following unit. This hooks the _AfterConstruction
method in the System
unit. Ideally it should use a trampoline but I've never learnt how to implement those. If you used a real hooking library you'd be able to do it better. Anyway, here it is:
unit AfterConstructionEvent;
interface
var
OnAfterConstruction: procedure(Instance: TObject);
implementation
uses
Windows;
procedure PatchCode(Address: Pointer; const NewCode; Size: Integer);
var
OldProtect: DWORD;
begin
if VirtualProtect(Address, Size, PAGE_EXECUTE_READWRITE, OldProtect) then
begin
Move(NewCode, Address^, Size);
FlushInstructionCache(GetCurrentProcess, Address, Size);
VirtualProtect(Address, Size, OldProtect, @OldProtect);
end;
end;
type
PInstruction = ^TInstruction;
TInstruction = packed record
Opcode: Byte;
Offset: Integer;
end;
procedure RedirectProcedure(OldAddress, NewAddress: Pointer);
var
NewCode: TInstruction;
begin
NewCode.Opcode := $E9;//jump relative
NewCode.Offset := NativeInt(NewAddress)-NativeInt(OldAddress)-SizeOf(NewCode);
PatchCode(OldAddress, NewCode, SizeOf(NewCode));
end;
function System_AfterConstruction: Pointer;
asm
MOV EAX, offset System.@AfterConstruction
end;
function System_BeforeDestruction: Pointer;
asm
MOV EAX, offset System.@BeforeDestruction
end;
var
_BeforeDestruction: procedure(const Instance: TObject; OuterMost: ShortInt);
function _AfterConstruction(const Instance: TObject): TObject;
begin
try
Instance.AfterConstruction;
Result := Instance;
if Assigned(OnAfterConstruction) then
OnAfterConstruction(Instance);
except
_BeforeDestruction(Instance, 1);
raise;
end;
end;
initialization
@_BeforeDestruction := System_BeforeDestruction;
RedirectProcedure(System_AfterConstruction, @_AfterConstruction);
end.
Assign a handler to OnAfterConstruction
and that handler will be called whenever an object is created.
I leave it as an exercise to the reader to add an OnBeforeDestruction
event handler.
Note that I am not saying that such an approach is a good thing to do. I'm just answering the direct question that you asked. You can decide for yourself whether or not you want to use this. I know I would not do so!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With