winico is a Tk extension for Windows that manages icons for use in the Windows desktop taskbar and for setting an application icon. Part of this extensions functionality has been merged into the Tk core so for Tk 8.4+ this extension is really only useful for managing the taskbar (see wm iconbitmap). The extension works on both Windows 98/ME and Windows NT/2K/XP varieties of windows. Since version 0.5 Tcl 8.4 is required.
The winico package release also contains a demonstration application of a system tray-based application. Another example of an application using winico is the tkchat application found in tclapps.
MG 2004-04-01: I use this for getting menus in the system tray. Works on Win 98, and (I'm told) Win XP.
winico taskbar add $winico -callback {winicoCallback %m %x %y} -text $yourAppName proc winicoCallback {t {x 0} {y 0}} { if { $t == "WM_LBUTTONUP" } { wm deiconify . raise . focus . } elseif { $t == "WM_RBUTTONUP" } { .winicoPopup post $x $y .winicoPopup activate 0 } }
where .winicoPopup is a menu I've already created, and . is the main GUI window of my application. That causes a left-click of the icon to bring the application up to the front, and a right-click to post the menu.
Along with the winico.html documentation referenced immediately above, also be aware of these remarks from KBK and DRH:
"to look 'normal' you need a .ico file with all the sizes. The Windows standards recommend including: 48x48 32bpp, 32x32 32bpp, 16x16 32bpp, 48x48 8bpp, 32x32 8bpp, 16x16 8bpp, (plus same sizes at 4bpp and monochrome). Nowadays, typically only 32bpp and possibly monochrome are relevant because few users use 4- or 8-bit depth color settings.
Windows sometimes reduces the size to 16x16 automatically, but I think you have to give winico a 32x32. The stylized 'Tk' that appears in the upper left is at 16x16. You are also limited to 16 colors, if memory serves."
MG 2007-10-07: Just plugged winico 0.6 into an app (I'd used winico 0.3 before with past apps, I think) and went to test it, and found what seemed to be a bug: whenever I clicked the icon in the system tray when I had a -callback set, the main window (.) was raised and given focus, even though I hadn't told it to be. Had a look in the source to see if I could see the cause for it, and it seems it's deliberate, to work around a Windows bug that occurs when you post a menu from the system tray icon without giving the main window focus first (the menu doesn't disappear if you click another app without first clicking the menu).
Anyone know if it's still totally necessary to do that? I'm using Win XP SP2, and don't see the problem with some other apps (like the latest Windows Live Messenger), so I'm wondering if there's a newer/better/different solution to the problem out there somewhere.
JMN 2007-12-07:
Using winico 0.6, I can't seem to get 'winico taskbar add ..' to behave properly on Vista x64. It adds the icon to the systemtray ok at first, but then it just starts displaying one of the other icons in the panel.
Also 'winico setwindow' only seems to affect the window when maximized. The minimized window on the taskbar shows the default red Tk icon. The same code worked ok on win2k.
2008-03-06: Using png files, Tk 8.5+ and Img - the desired effect for the window and taskbar can be acheived without winico. This displays correctly both minimized & maximized (tested on vista x64)
package require Img image create photo mylabel -file ./ico16.png wm iconphoto . pcm
- Using Winico for the systemtray; it seems it might be important to make sure
you're using a 32x32 version.
e.g if your .ico file contains both a 16x16 & 32x32, you may need to set the -pos argument to 1
SES_home 2010-05-30 11:23:20:
Thanks to package winico and a smart wrapper around it and on top of this a nice & simple GUI to customize the menu, will lead you to more consistent and fast results. To see what I mean, please have a look at : tG2 v1.05.02
HaO 2010-12-21: If an icon file has multiple sizes and color depth, one could search for 16x16 and a colordepth bigger or equal to the current colordepth:
package require Winico set hTaskbarIcon [winico createfrom $iconFile] # > Search for 16x16 and maximum or current colordepth set indexCur 0 set bppMax 0 foreach dPars [winico info $hTaskbarIcon] { if { [dict get $dPars -geometry] eq "16x16" } { set bppCur [dict get $dPars -bpp] if {$bppCur == [winfo depth .]} { set indexCur [dict get $dPars -pos] break } if {$bppCur > $bppMax} { set indexCur [dict get $dPars -pos] set bppMax $bppCur } } } winico taskbar add $hTaskbarIcon -pos $indexCur -text [wm title .]\ -callback [list [namespace code WinicoCallback] %m %x %y]
For starpacks, it is possible to load the starpack icon resource (called TK). For me, this did only load the size 32x32 in 4 bit resolution. This was scaled to 16x16 32bit and looked not so nice.
set hTaskbarIcon [winico load TK [info nameofexecutable]]
If the auto-icon-customization with a tclkit.ico file is used, it is also present in the starpack (why ?). So it might be loaded and you get all sizes and resolutions.
set hTaskbarIcon [winico createfrom [file join $starkit::topdir tclkit.ico]]
MJ 2017-03-28: A 64 bit build for Tcl 8.7 and the MinGW64 build script can be found at: https://fossil.mpcjanssen.nl/winico
HaO 2017-09-26: Magic TWAPI also features tray icon support.
package require twapi_resource package require twapi_shell package require twapi_ui # Create with X set ID [twapi::systemtray addicon [twapi::load_icon_from_system hand] cb] # Change to Triangle twapi::systemtray modifyicon $ID -hicon [twapi::load_icon_from_system bang] # Set tooltip help twapi::systemtray modifyicon $ID -tip "New Tooltip" # Balloon notification (very Windows 10'ish ;-) ) twapi::systemtray modifyicon $ID -balloon "Balloon Text" -balloontitle "Balloon title" -balloonicon error proc cb {ID Message lPos TimeStamp} { lassign $lPos xPos yPos switch $Message { select - keyselect { # click action here } contextmenu { if {![winfo exists .guiWinicoPopup]} { menu .guiWinicoPopup -tearoff 0 .guiWinicoPopup add command -label "CMD1" -command {puts CMD1} } set hWinNotify [::twapi::Twapi_GetNotificationWindow] ::twapi::set_foreground_window $hWinNotify .guiWinicoPopup post $xPos $yPos .guiWinicoPopup activate 0 ::twapi::PostMessage $hWinNotify 0 0 0 } } }
MHo 2020-11-15: Where does ::twapi::Twapi_GetNotificationWindow come from?
Microsoft now calls the tray "Notification area" [L1 ].
Winico is able to handle icon files within a starpack. This does not work with twapi. A copy mechanism is required (the copying is not required for the program icon in "[info nameofexecutable]/tclkit.ico"):
proc GetTrayIcon {FileIn} { if { [info exists starkit::topdir] && [string equal -nocase\ -length [string length $starkit::topdir]\ $starkit::topdir $FileIn] && "[string equal -nocase $FileIn [file normalize [file join $starkit::topdir [info nameofexecutable] tclkit.ico]]] } { set DestName [file join $::tmpFolder [file tail $FileIn]] file copy -force -- $FileIn $DestName set ID [::twapi::load_icon_from_file $DestName] file delete -force -- $DestName return $ID } return [::twapi::load_icon_from_file $FileIn] }
MHo 2020-11-14: The above code contains syntax errors...
MHo 2020-11-14: I think we can use this to use the icon of the current executable:
set ID [twapi::systemtray addicon [load_icon_from_module [get_module_handle] "TK"] cb]
Twapi does not need any code to choose the right resolution index.
With Winico, the context menu did not work with Windows 10. The windows menu was shown instead. This works with twapi.
The following commands clear the taskbar icon. If the icon is loaded from a file.the icon resource may be freed. In the following example, the icon handle (returned by ::twapi::load_icon_from_file) was saved in the variable IconHandle.
Remark that the freeing is catched. The author observed shared resource errors and could not find the reason.
::twapi::systemtray removeicon $ID catch {::twapi::free_icon $IconHandle}