2012-04-21 29 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