I want to add a published property in TWinControl. Is there a way to do this without having to recompile the underlying source code?
If not, is there some way to recompile the basic source code without much trouble?
Tks on the board ...
CHANGE REASONS FOR NEW IDEAS
Well, what I'm going to do, I'm trying to override _GetMem from System.pas for classes inherited from TWinControl. What for? 'Because I allocated extra space for objects sufficient for an integer. Why an integer? Because I can add any pointer to an object. Therefore, in the helper class for TWinControl, I can make the Get Set function to access this memory space. Okay right? How to do it? Overriding the GetMem procedure, I can use the same strategy as on FastCode to create a jumper for the new procedure.
Now I need to understand how this memory distribution InstanceSize works to override this. I generally learn how Delphi does this ... And to add this to DFM, I will do the same, I will create a jumper for the filter.
Does anyone have an idea to add new space to objects? Which method do I need to override? Jumper I know how to do this.
Tks Again.
EDIT = Evolution
I think I injected the memory. I need to do more tests. I just did this, I don't care about optimization at the moment, if someone wants to test it, here is the code. Just add the device as the first block of your project.
unit uMemInjection;
interface
uses
Controls;
type
THelperWinControl = class Helper for TWinControl
private
function RfInstanceSize: Longint;
function GetInteger: Integer;
procedure SetInteger(const Value: Integer);
public
property RfInteger: Integer read GetInteger write SetInteger;
end;
implementation
uses
Windows;
procedure SInstanceSize;
asm
call TWinControl.InstanceSize
end;
function THelperWinControl.GetInteger: Integer;
begin
Result := Integer(PInteger(Integer(Self) + (Self.InstanceSize - SizeOf(Integer)))^);
end;
function THelperWinControl.RfInstanceSize: Longint;
begin
Result := PInteger(Integer(Self) + vmtInstanceSize)^;
Result := Result + SizeOf(Integer);
end;
/////////////////////////////////////////////// FastCode ///////////////////////////////////////////////
type
PJump = ^TJump;
TJump = packed record
OpCode: Byte;
Distance: Pointer;
end;
function FastcodeGetAddress(AStub: Pointer): Pointer;
begin
if PBYTE(AStub)^ = $E8 then
begin
Inc(Integer(AStub));
Result := Pointer(Integer(AStub) + SizeOf(Pointer) + PInteger(AStub)^);
end
else
Result := nil;
end;
procedure FastcodeAddressPatch(const ASource, ADestination: Pointer);
const
Size = SizeOf(TJump);
var
NewJump: PJump;
OldProtect: Cardinal;
begin
if VirtualProtect(ASource, Size, PAGE_EXECUTE_READWRITE, OldProtect) then
begin
NewJump := PJump(ASource);
NewJump.OpCode := $E9;
NewJump.Distance := Pointer(Integer(ADestination) - Integer(ASource) - 5);
FlushInstructionCache(GetCurrentProcess, ASource, SizeOf(TJump));
VirtualProtect(ASource, Size, OldProtect, @OldProtect);
end;
end;
/////////////////////////////////////////////// FastCode ///////////////////////////////////////////////
{ THelperWinControl }
procedure THelperWinControl.SetInteger(const Value: Integer);
begin
PInteger(Integer(Self) + (Self.InstanceSize - SizeOf(Integer)))^ := Value;
end;
initialization
FastcodeAddressPatch(FastcodeGetAddress(@SInstanceSize), @TWinControl.RfInstanceSize);
end.