Graphical problem with TAdvBadge

Hi,
I have a strange graphical problem with any component with TAdvBadge (TAdvBadgeLabel, TAdvBadgeButton, etc.) on monitor with 125%, 150%, 200% screen zoom in Display Settings. In order to reproduce it, just place a TAdvBadgeLabel component leaving the "Badge" property empty. Then place a TButton with the code to set the "Badge" property of this component to "1". The result is the one in the following image:

image

The badge is not circular, it has a strange shape. If you change it again to "2", for example, it will be painted correctly.

If the screen is set to 100% in Screen Settings everything works fine.

Any suggestion or is it a bug?

Thank you in advance.

We applied an improvement for this high DPI issue that will be included in the next update.

Great, thank you very much!

Hi,
I updated the TMS VCL UI Pack to version 10.5.6.0 and now it has the opposite bug: it's not painted correctly when changing from "empty" to "1" at runtime. It also seems to be a strange circle now.
I attach an image, it's very easy to replicate: just place a TAdvBadgeButton, leave his badge property empty, place a TButton that sets his "Badge" property to "1".

1

Thank you in advance!

I cannot reproduce this.
What IDE do you use? It might be Delphi version specific.

Delphi 10.4.2, screen at 125%. I attach a sample form.

object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 339
  ClientWidth = 250
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -13
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 120
  TextHeight = 16
  object AdvBadgeLabel1: TAdvBadgeLabel
    Left = 48
    Top = 96
    Width = 97
    Height = 20
    Caption = 'AdvBadgeLabel1'
    TabOrder = 0
  end
  object Button1: TButton
    Left = 48
    Top = 144
    Width = 97
    Height = 49
    Caption = 'Button1'
    TabOrder = 1
    OnClick = Button1Click
  end
end
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, AdvBadge;

type
  TForm1 = class(TForm)
    AdvBadgeLabel1: TAdvBadgeLabel;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  AdvBadgeLabel1.Badge := '3';
end;

end.

Hi,
are you able to reproduce the issue?

We have applied a further improvement that will be included in the next update.

Great, thank you!

Hi,
the problem still persists. I looked at the source code and I found how to fix it.
Just revert the unit "AdvBadge.pas" to v1.1.1.3 and apply these two modifications:

  1. Remove the "Text := '1';" row on TAdvBadge.Create
  2. Change the first row of "TAdvBadge.DoSetRegion" to "rgn := CreateRectRgn(0, 0, Width, Height);"

I tried with 100%, 125%, 150% and 175% and it always works fine. It also does not suffer the bug of the "first drawing" when changing the property from empty to something at runtime.

Then there must be a (subtle) something either missing in the description of the problem or overlooked here. We cannot see an issue with the latest version on different DPI %
Changing the DoSetRegion as you suggest results here in a rectangular badge.

It's important to revert the file AdvBadge.pas to version 1.1.1.3 before applying the above changes.

My question is for steps to reproduce the problem with the latest release.

It's enough to place a TAdvBadgeLabel component and leave the "Badge" property to empty. Then place a TButton that sets the "Badge" property of the TAdvBadgeLabel component to "1" when clicking on it.
This is the result, the text is in the bottom right. If you change again the value at runtime to a different value, it is painted in the center. Anyway the shape is strange when using CreateRoundRectRgn, the old method in v1.1.1.3, that uses GDI+ libraries, paints a nice antialiased shape.

image

I found a better solution: just revert the file to version 1.1.1.3 and override the public method "ScaleForPPI", implementing it with an empty body. There is no need here to let VCL scale because the size is already calculated at runtime in this component with the "DoMeasure" method. In this way it's also fixed another bug that happens when you switch between monitors with different DPI.
I hope it helps.

Thanks! We will check this.

We now investigated this and the rendering is indeed better with this technique.
This will be in the next TMS VCL UI Pack

Glad to hear that. Thank you!