Delphi XE2 VCL styles, changing window Icon doesn't update on the caption bar until RecreateWnd

后端 未结 1 824
谎友^
谎友^ 2021-02-10 02:09

Another weird glitch with VCL styles:

Changing a form\'s Icon updates only its taskbar button, the Icon in the caption doesn\'t update unless you use RecreateWnd. (when

相关标签:
1条回答
  • 2021-02-10 02:36

    It's (yet another) bug in VCL styles. The TFormStyleHook.GetIconFast function is returning a stale icon handle. I'd fix it by replacing TFormStyleHook.GetIconFast with TFormStyleHook.GetIcon. Add this to one of your units and all is well again.

    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
      );
    
    0 讨论(0)
提交回复
热议问题