Recent

Author Topic: TTrayicon shows wrong (self painted) icon  (Read 185 times)

Germo

  • New member
  • *
  • Posts: 7
TTrayicon shows wrong (self painted) icon
« on: November 29, 2024, 12:31:24 pm »
In my app I use a Trayicon, and to make it clear that there is some action needed i want the image on the Trayicon to display a number.
Creating this image and assigning it to the icon works most of the time. But sometimes there is a wrong number displayed. A number that has already been shown before.

I have been searching for some time now, but i can't seem to find a solution. Anyone here can point me in the right direction?


I created a small test program to display this behaviour.
It has an Image1 that is the default (numberless) icon, and a Image2 that is a faded version of Image1
I binded some click events to ClickVoorGetal procedure.

I am using: Free Pascal Compiler version 3.2.2-r0d122c49 [2024/02/09] for x86_64 on Ubuntu 22.04.5
Code: Pascal  [Select][+][-]
  1. Unit unittesticon;
  2. {$mode objfpc}{$H+}
  3. Interface
  4. Uses
  5.   Classes, Sysutils, Forms, Controls, Graphics, Dialogs, Menus, ExtCtrls,
  6.   StdCtrls;
  7.  
  8. Type
  9.   { TTestForm }
  10.   TTestForm = Class(Tform)
  11.     Image1 : Timage;
  12.     Image2 : Timage;
  13.     Listbox : Tlistbox;
  14.     Trayicon : Ttrayicon;
  15.       PuM_TrayIcon : Tpopupmenu;
  16.         Menuitem1 : Tmenuitem;
  17.       Menuitem2 : Tmenuitem;
  18.     Procedure ClickVoorGetal(Sender : Tobject);
  19.   Public
  20.     Getal : Integer;
  21.     Procedure UpdateTrayIcon;
  22.   End;
  23.  
  24. Var
  25.   TestForm : TTestForm;
  26.  
  27. Implementation
  28. {$R *.lfm}
  29.  
  30. { TTestForm }
  31. Procedure TTestForm.ClickVoorGetal(Sender : Tobject);
  32. Begin
  33.   Getal := Random(1000);
  34.   Caption := IntToStr(Getal);
  35.   Listbox.Items.Add(IntToStr(Getal));
  36.   ListBox.Invalidate;
  37.   UpdateTrayIcon;
  38.   End;
  39.  
  40. Procedure TTestForm.Updatetrayicon;
  41. // Function to create an icon with a number on it
  42. Function NewIcon(Aantal : Integer) : TIcon;
  43. Var
  44.   WorkBitmap : TBitMap = nil;  // Bitmap for creating Image
  45.   CountText : String = '';     // text to display
  46.   DesiredWidth,                // optimal width
  47.   CountTextWidth,              // width after font adjust
  48.   CountTextHeight,             // height after font adjust
  49.   WidthOfset,                  // h-ofset to place text in center
  50.   HeightOfset : Integer;       // v-ofset to place text in center
  51. Begin
  52.   Result := TIcon.Create;      // we have to return an icon
  53.   If Aantal = 0 Then Begin     // Default image as result
  54.     Result.Assign(Image1.Picture.Bitmap);  // standaard icoon
  55.     End
  56.   Else Begin                   // we create our own image
  57.     WorkBitmap := TBitmap.Create;  // create a WorkBitmap
  58.     Try
  59.       WorkBitmap.Assign(Image2.Picture.Bitmap);  // faded icoon as base
  60.       WorkBitmap.Canvas.Brush.Style := bsClear;  // no background with text
  61.       WorkBitmap.Canvas.font.name := 'FreeSans'; // font settings
  62.       WorkBitmap.Canvas.font.Bold := True;
  63.       WorkBitmap.Canvas.font.Size := 60;
  64.       CountText := Format('%d',[Aantal]);      // text we want to display
  65. // we want the text to fill 80% of the icon
  66.       DesiredWidth := Trunc(WorkBitmap.Width * 0.8);
  67. // while text is to small => increase font size
  68.       While (WorkBitmap.Canvas.TextWidth(CountText) < DesiredWidth) And
  69.             (WorkBitmap.Canvas.TextHeight(CountText) < DesiredWidth) Do
  70.         WorkBitmap.Canvas.font.size := WorkBitmap.Canvas.font.size + 2;
  71. // in case the text is to big => decrease font size
  72.       While (WorkBitmap.Canvas.TextWidth(CountText) > DesiredWidth) And
  73.             (WorkBitmap.Canvas.TextHeight(CountText) > DesiredWidth) And
  74.             (WorkBitmap.Canvas.font.size > 10) Do
  75.         WorkBitmap.Canvas.font.size := WorkBitmap.Canvas.font.size - 2;
  76. // calculate position
  77.       CountTextWidth := WorkBitmap.Canvas.TextWidth(CountText);
  78.       CountTextHeight := WorkBitmap.Canvas.TextHeight(CountText);
  79.       WidthOfset := (WorkBitmap.Width - CountTextWidth) Div 2;
  80.       HeightOfset := (WorkBitmap.Height - CountTextHeight) div 2;
  81. // draw text (a little to the topleft) in white
  82.       WorkBitmap.Canvas.font.color := clWhite;
  83.       WorkBitmap.Canvas.TextOut(WidthOfset-8,HeightOfset-8,CountText);
  84. // draw text (a little to the bottomright) in black
  85.       WorkBitmap.Canvas.font.color := clBlack;
  86.       WorkBitmap.Canvas.TextOut(WidthOfset+8,HeightOfset+8,CountText);
  87. // draw the text in red
  88.       WorkBitmap.Canvas.font.color := clRed;
  89.       WorkBitmap.Canvas.TextOut(WidthOfset,HeightOfset,CountText);
  90. // assign the resulting (bitmap) to our function-return
  91.       Result.Assign(WorkBitmap);
  92.     finally
  93. // cleanup our working bitmap
  94.       FreeAndNil(WorkBitmap);
  95.       End;
  96.     End;
  97.   End;
  98.  
  99. Var
  100.   NumberIcon : TICon;
  101. begin
  102. // check-text in menuitem-caption
  103.   Menuitem2.Caption := Format('Aantal = %d',[Getal]);
  104. // create a new icon with a number
  105.   NumberIcon := newicon(Getal);
  106.   Try
  107. // clear the icon in the trayicon
  108.     TrayIcon.Icon.Clear;
  109. // assign our newly created icon
  110.     TrayIcon.Icon.Assign(NumberIcon);
  111. // let TrayIcon update itself
  112.     TrayIcon.InternalUpdate;
  113.   Finally
  114. // cleanup our working icon
  115.     FreeandNil(NumberIcon);
  116.     End;
  117.   end;
  118.  
  119. End.
  120.  

 

TinyPortal © 2005-2018