5

VCLスタイルのもう1つの奇妙な不具合:

フォームのアイコンを変更すると、タスクバーボタンのみが更新されます。RecreateWndを使用しない限り、キャプションのアイコンは更新されません。(VCLスタイルを使用する場合)

ImageList3.GetIcon(0,Form1.Icon);

RecreateWndを使用せずに修正する方法はありますか?(これは実際に他の問題を引き起こす可能性があります)

4

1 に答える 1

9

これは(さらに別の)VCLスタイルのバグです。このTFormStyleHook.GetIconFast関数は、古いアイコンハンドルを返しています。に置き換えて修正TFormStyleHook.GetIconFastTFormStyleHook.GetIconます。これをユニットの1つに追加すると、すべてが元気になります。

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
  );
于 2012-04-21T14:56:01.420 に答える