Updated 2017-11-13 17:06:56 by oehhar

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 project is managed at SourceForge as part of the tktable project [1] and pre-compiled binary release and source code can be downloaded from the project site. Bugs can be raised using the sourceforge trackers on this site and documentation is located at http://tktable.sourceforge.net/winico/winico.html

Tom Wilkason describes how to work with an icon in the system tray in System Tray Icon???? , comp.lang.tcl ,2001-09-22

The 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

Misc  edit

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]
        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

Tray Icons using TWAPI edit

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

Microsoft now calls the tray "Notification area" [2].

Winico is able to handle icon files within a starpack. This does not work with twapi. A copy mechanism is required:
proc GetTrayIcon {FileIn} {
    if {    [info exists starkit::topdir]
            && [string equal\
                -length [string length $starkit::topdir]\
                $starkit::topdir $FileIn]
    } {
        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]

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.