【发布时间】:2011-01-06 09:10:27
【问题描述】:
我想将发布的属性添加到 TWinControl。 有没有办法在不需要重新编译基础源代码的情况下做到这一点?
如果没有,有什么方法可以重新编译基础源代码而不用太麻烦?
Tks 建议...
编辑“新想法的原因”
好的,我想做什么我正在尝试覆盖 System.pas 中的 _GetMem 用于类 继承自 TWinControl。 为什么 ?因为我会为对象分配一些额外的空间,足够一个整数。 为什么是整数?因为这样我可以添加任何指向对象的指针。 所以在 TWinControl 的辅助类上,我可以创建一个 Get an Set 函数来访问这个内存空间。 很好不是吗?这个怎么做 ? 覆盖 GetMem 过程我可以使用 FastCode 上使用的相同策略,创建一个到新过程的跳线。
我现在需要的是了解这个内存分配如何通过 InstanceSize 来覆盖它。 我一直在研究 Delphi 是如何做到这一点的......并且要在 DFM 上添加它,我也会这样做,我将创建一个到文件管理器的跳线。
有人想在对象中添加新空间吗?我需要重写什么方法?我知道该怎么做的跳线。
再次感谢。
编辑 = 进化
我认为我做了内存注入。 我需要做更多的测试。 我刚刚做了,我现在不关心优化,如果有人想测试它,这里有代码。 只需将该单元添加为项目的第一个单元即可。
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.
【问题讨论】: