在TWinControl类上添加属性

Rod*_*ino 4 delphi vcl

我想将已发布的属性添加到TWinControl中.有没有必要重新编译基本源代码?

如果没有,有一些方法重新编译基本源代码没有太多麻烦?

请咨询......

编辑新思路的原因

Alright, What I'm thinking to do I'm trying to override the _GetMem from System.pas for classes inherited from TWinControl. Why ? 'Cause I'll alloc some extra space to the objects enough to an integer. Why an integer ? 'Cause this way I can add any pointer to object. So on the helper class to TWinControl I can make a Get an Set function to access this space of memory. Good isn't it ? How to do this ? Overrideing the GetMem procedure I can use the same strategy used on FastCode, create a jumper to the new procedure.

What I need now is understand how this memory alloc works InstanceSize to override this. At all I'm studding how do Delphi do this... And to add this on DFM I will do the same way, I'll create a jumper to the filer.

有人有想法在对象中添加新空间吗?我需要覆盖哪种方法?跳线我知道怎么做.

再来一次.

编辑=进化

我认为我注射了记忆.我需要做更多的测试.我刚刚做到了,我现在不关心优化,如果有人想测试它,这里就是代码.只需将该单元添加为项目的第一个单元即可.

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.
Run Code Online (Sandbox Code Playgroud)

Jer*_*ers 9

感谢Smasher,我记得Delphi团队如何使用类帮助程序和设计器技巧为Delphi 2007添加属性,而不会破坏与Delphi 2006的二进制兼容性.

看到这个伟大的文章Hallvard Vassbotn如何做到这一点.

我认为它解决了大部分问题,如果不是全部的话.

在文章中寻找这些东西:

  • TCustomFormHelper = TCustomForm的类助手
  • FPixelsPerInch存储破解
  • 注入设计时属性
  • 定义流媒体属性

但是,当您从外部世界挂钩到TWinControl时,您将不得不以自己的方式进行流式传输,但这也许是可能的.

--jeroen


And*_*dré 5

Delphi2007 及更高版本具有“类助手”。

您可以引入新的函数和属性,但不能引入字段/变量。因此,您必须将新属性的值存储在 .Tag 属性中的额外对象中(通过工厂或其他方式)或(非常难看)...

不知道类助手是否也适用于包/设计时?