Difference between revisions of "Talk:How to use a TrayIcon"
Line 9: | Line 9: | ||
!LeftClick | !LeftClick | ||
!RightClick | !RightClick | ||
+ | !Usable | ||
|- | |- | ||
|18.04 Mate 820 | |18.04 Mate 820 | ||
Line 14: | Line 15: | ||
|Menu | |Menu | ||
|Panel Menu | |Panel Menu | ||
+ | |Yes | ||
|- | |- | ||
|18.04 Mate 821 | |18.04 Mate 821 | ||
Line 19: | Line 21: | ||
|Click | |Click | ||
|Menu | |Menu | ||
+ | |Yes | ||
|- | |- | ||
|18.04 Gnome3 820 | |18.04 Gnome3 820 | ||
Line 24: | Line 27: | ||
|Menu | |Menu | ||
|Menu | |Menu | ||
+ | |Yes | ||
|- | |- | ||
|18.04 Gnome3 821 | |18.04 Gnome3 821 | ||
+ | |No | ||
+ | |, | ||
+ | |, | ||
|No | |No | ||
|- | |- | ||
Line 32: | Line 39: | ||
|Menu | |Menu | ||
|Menu | |Menu | ||
+ | |Yes | ||
|- | |- | ||
|19.04 Gnome3 821 | |19.04 Gnome3 821 | ||
+ | |No | ||
+ | |, | ||
+ | |, | ||
|No | |No | ||
|- | |- | ||
Line 40: | Line 51: | ||
|Menu | |Menu | ||
|Menu | |Menu | ||
+ | |Yes | ||
|- | |- | ||
|Fedora 30 821 | |Fedora 30 821 | ||
Line 45: | Line 57: | ||
|Click | |Click | ||
|Menu but in random location. | |Menu but in random location. | ||
+ | |No | ||
|- | |- | ||
|Debian 9.9 (all) | |Debian 9.9 (all) | ||
Line 50: | Line 63: | ||
|Click | |Click | ||
|Menu | |Menu | ||
+ | |Yes | ||
|- | |- | ||
|Force some space here | |Force some space here |
Revision as of 03:02, 30 September 2019
Linux Problems
In conjunction with bugs 0035723 and 35983 here is a table of what works with (Fixes) release 61820 and 61821 -
Distro | See Icon | LeftClick | RightClick | Usable |
---|---|---|---|---|
18.04 Mate 820 | Yes | Menu | Panel Menu | Yes |
18.04 Mate 821 | Yes | Click | Menu | Yes |
18.04 Gnome3 820 | Yes | Menu | Menu | Yes |
18.04 Gnome3 821 | No | , | , | No |
19.04 Gnome3 820 | Yes | Menu | Menu | Yes |
19.04 Gnome3 821 | No | , | , | No |
Fedora 30 820 | Yes | Menu | Menu | Yes |
Fedora 30 821 | Yes | Click | Menu but in random location. | No |
Debian 9.9 (all) | Yes | Click | Menu | Yes |
Force some space here | And some more here | And some more here | And some more here |
(Fedora 30 has TopIcons installed, without it no TrayIcon shows in either model)
(Thats Plasma and Gnome3, both versions of test app)
Don't have time to put into a table right now and sure need to test some more distros. But note that the current, mainstream, Fedora and Ubuntu are unusable in 61821 and later
Legacy
Could someone expand on this comment "The image of the icon can be altered using a HICON handle. "? As a newbie I don't really know what a HICON handle is or how to use it.
- HICON is a widgetset Icon Handle. The TrayIcon component is quite old, and when I first wrote it there was no real support for the TIcon component is Lazarus, so you could use directly an icon handle instead. Now you should just go for TIcon.
- --Felipe Monteiro de Carvalho 08:41, 25 July 2010 (CEST)
I have found it quite hard to generate icons that will load and display using
SysTrayIcon.LoadFromFile('file.ico'); SysTrayIcon.Show;
- Should work.
- --Felipe Monteiro de Carvalho 08:41, 25 July 2010 (CEST)
I found that the format of the icon in Windows XP is fussy. The icon will only display if it is saved with the parameters "8bpp,1-bit alpha,256-slot palette" in gimp for example.
- Ummm ... that's probably something related to the Free Pascal Windows Icon reading capabilities. 24-bits RGB should work too. Doesn't it work? You can create a test project and attach it to a bug report in the bug tracker. It would also be great if you could find out which formats work and which don't and write this in the wiki.
- --Felipe Monteiro de Carvalho 08:41, 25 July 2010 (CEST)
The next challenge is to modify an icon in memory and then display it. I'm sure my method isn't exactly correct but maybe it will help others. First I tried to create a tbitmap and load an icon into it but fails. Also any attempt to do a SysTrayIcon.Icon.LoadFromBitMapHandles() seems to result in a blank icon.
In the end I did this which works for a 32x32 icon
MemIcon:=TIcon.Create; MemIcon.LoadFromLazarusResource('blankicon'); PByte:=MemIcon.RawImage.Data+100; //PByte now points to the first byte of the first pixel. //Set the top left pixel red Pbyte^:=$00; //green (PByte+1)^:=$FF; //red (PByte+2)^:=$00: //blue SysTrayIcon.Icon:=MemIcon; SysTrayIcon.Show:
Now I have an icon in my system tray with a red dot in the top left corner. Each pixel uses 3 bytes so a procedure like this works to manipulate each 32x32 pixel
procedure TForm1.SetIconPixel(PTRIcon:PIcon;xpos,ypos,red,green,blue:byte); var PByte: ^Byte; begin {xpos and ypos are 0 to 31} PByte:=PtrIcon^.RawImage.Data+100+((xpos+(ypos*32))*3); if PByte<PtrIcon^.RawImage.Data+PtrIcon^.RawImage.DataSize-1 then begin Pbyte^:=green; (PByte+1)^:=red; (PByte+2)^:=blue; end; end;
I have no idea what the first 100 bytes do.
For a 16x16 icon there is no extra 100 bytes and the colour order is different. Same code for a 16x16 icon
procedure TForm1.SetIconPixel(PTRIcon:PIcon;xpos,ypos,red,green,blue:byte); var PByte: ^Byte; begin {xpos and ypos are 0 to 15} PByte:=PtrIcon^.RawImage.Data+((xpos+(ypos*16))*3); if PByte<PtrIcon^.RawImage.Data+PtrIcon^.RawImage.DataSize-1 then begin Pbyte^:=blue; (PByte+1)^:=green; (PByte+2)^:=red; end; end;
To use this procedure you have to load an icon file or resource into a ticon send a pointer to the ticon and the xpos, ypos and colour that you want to the procedure copy the icon to the systrayicon show it
like this
MemIcon:=TIcon.Create; MemIcon.LoadFromFile('16x16.ico'); //draw a black square in the middle for x:=6 to 9 do for y:=6 to 9 do SetIconPixel(@MemIcon,x,y,0,0,0); SystrayIcon.Icon:=MemIcon; SystrayIcon.Show;
- Now about setting an icon pixel, there is a much better way of doing this. The RawImage is completely dependent on the pixel format you are using, but you can also use TLazIntfImage, which is format independent and very fast:
uses Graphics, IntfGraphics; var TempIntfImg: TLazIntfImage; ImgHandle,ImgMaskHandle: HBitmap; px, py: Integer; TempBitmap: TBitmap; begin TempIntfImg:=TLazIntfImage.Create(16,16); TempBitmap:=TBitmap.Create; // Here you can set the pixels for py:=0 to TempIntfImg.Height-1 do for px:=0 to TempIntfImg.Width-1 do SrcIntfImg.Colors[px,py] := clRed; // Now you can copy it to a TBitmap TempIntfImg.CreateBitmaps(ImgHandle,ImgMaskHandle,false); TempBitmap.Handle:=ImgHandle; TempBitmap.MaskHandle:=ImgMaskHandle; // And copy the TBitmap to your Icon SystrayIcon.Icon.Assign(TempBitmap); TempIntfImg.Free; TempBitmap.Free; end;
- That should do it and very 100% format independent.
- --Felipe Monteiro de Carvalho 08:40, 25 July 2010 (CEST)
I can't get TempIntfImg.CreateBitmaps(ImgHandle,ImgMaskHandle,false) to actually run getting FPImageException: Failed to create handles bug 0017031 created dieselnutjob
- For reference, I added a working code here: TrayIcon#Example_2_-_Creating_the_icon_with_TLazIntfImage
- --Felipe Monteiro de Carvalho 17:38, 26 July 2010 (CEST)
Your code works well. I tried it in Linux and Windows XP. just removed the unnecessary "FPRed: TFPColor;" variable thanks dieselnutjob
I am getting a new problem now. With the example code on Linux the red box is scrambled. for an example see http://christiantena.pwp.blueyonder.co.uk/images/redbox.jpg This is laptop running Debian Lenny with KDE desktop. Lazarus is 0.9.28.2-0 beta Date 2009-10-27 FPC 2.2.4 thanks dieselnutjob