【问题标题】:Delphi XE2 VCL styles, changing window Icon doesn't update on the caption bar until RecreateWndDelphi XE2 VCL 样式,更改窗口图标不会在标题栏上更新,直到 RecreateWnd
【发布时间】:2012-05-02 16:41:48
【问题描述】:

VCL 样式的另一个奇怪故障:

更改表单的图标只会更新其任务栏按钮,除非您使用 RecreateWnd,否则标题中的图标不会更新。 (使用 VCL 样式时)

ImageList3.GetIcon(0,Form1.Icon);

有没有办法在不使用 RecreateWnd 的情况下修复它? (实际上可以创建other issues

【问题讨论】:

    标签: delphi styles delphi-xe2 vcl


    【解决方案1】:

    这是 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
      );
    

    【讨论】:

    • 太棒了,完美,tyvm。将其全部放入一个新单元并将其添加到我需要更改图标的表单中,现在可以完美运行。
    • @warren 是的,我会解决的
    • 有什么方法可以在 64 位上进行这项工作?即使在使用 64 位项目启动时,也根本不会绘制图标。谢谢。
    • 我不明白为什么这在 64 位中不起作用,而且我没有简单的解决方案。
    猜你喜欢
    • 2012-04-18
    • 2012-08-25
    • 1970-01-01
    • 1970-01-01
    • 2012-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多