2012-04-21 27 views

回答

9

这是(又一个)VCL样式中的错误。 TFormStyleHook.GetIconFast函数正在返回一个陈旧的图标句柄。我会通过用TFormStyleHook.GetIcon替换TFormStyleHook.GetIconFast来修复它。把它添加到你的单位之一,一切都很好。

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; 

type 
    TFormStyleHookHelper = class helper for TFormStyleHook 
    function GetIconFastAddress: Pointer; 
    function GetIconAddress: Pointer; 
    end; 

function TFormStyleHookHelper.GetIconFastAddress: Pointer; 
var 
    MethodPtr: function: TIcon of object; 
begin 
    MethodPtr := Self.GetIconFast; 
    Result := TMethod(MethodPtr).Code; 
end; 

function TFormStyleHookHelper.GetIconAddress: Pointer; 
var 
    MethodPtr: function: TIcon of object; 
begin 
    MethodPtr := Self.GetIcon; 
    Result := TMethod(MethodPtr).Code; 
end; 

initialization 
    RedirectProcedure(
    Vcl.Forms.TFormStyleHook(nil).GetIconFastAddress, 
    Vcl.Forms.TFormStyleHook(nil).GetIconAddress 
); 
+1

真棒,那完美的作品,tyvm。把它放在一个新的单位,并将其添加到我需要更改图标的形式,现在完美无瑕。 – hikari 2012-04-21 15:13:49

+1

也许登录QC? – 2012-04-21 17:19:31

+0

@warren是的,我会去那 – 2012-04-21 17:28:08