Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

How do you toggle the system tray icon using Win32::Gui?

by vroom (His Eminence)
on Oct 01, 2001 at 21:54 UTC ( [id://115924]=perlquestion: print w/replies, xml ) Need Help??

vroom has asked for the wisdom of the Perl Monks concerning the following question:

I haven't done anything with Win32::GUI before. What I'm looking to do is setup a monitor script and then change the system tray icon change when various systems go down.

So far I've been unable to find a method to change the icon once I've set it up. Also the icon in the system tray disappears when I run my mouse over it.

Here's the code I'm starting with;

use Win32::GUI; my $isOn=0; $Test = new Win32::GUI::Icon("on.ico"); $TrayIcon = new Win32::GUI::NotifyIcon( $Main, -name => "Tray", -icon => $Test, ); while(1){ #insert fancy monitoring code here sleep(15); }


vroom | Tim Vroom | vroom@blockstackers.com

Replies are listed 'Best First'.
Re: How do you toggle the system tray icon using Win32::Gui?
by jehuni (Pilgrim) on Oct 01, 2001 at 22:55 UTC

    I started messing with this once, although I didn't get very far. The ActivePerl PPM package of Win32::GUI doesn't seem to install the same docs that you can find on CPAN, but there are some tutorials included with that particular distribution.

    Part 4 of the tutorial covers system tray icons, and the example script there did work for me under 2000. Here's my (very slightly) paraphrased version:

    use Win32::GUI; my $main = Win32::GUI::Window->new( -name => 'main', -text => 'test', -width => 150, -height => 150 ); my $icon = Win32::GUI::Icon->new('test.ico'); my $tray = $main->AddNotifyIcon( -name => 'tray', -icon => $icon, -tip => 'test' ); Win32::GUI::Dialog(); sub tray_Click { $main->Enable(); $main->Show(); 1; } sub main_Terminate { -1; } sub main_Minimize { $main->Disable(); $main->Hide(); 1; }

    Now, if you want to run this as a service, I have no idea how portable it is. Let us know if you get it to work.

    -jehuni

Re: How do you toggle the system tray icon using Win32::Gui?
by $code or die (Deacon) on Oct 02, 2001 at 00:33 UTC
    Ok, this is probably exploiting the very bug that we've been discussing here, but this code seems to work. You need to use the "id" parameter. It seems that if you do AddNotifyIcon() with the same "id" that you used before, it clears the old icon. So you can "effectively" change the icon by having the old one zapped into a black hole (I don't understand where it goes!).

    I'm using info1.ico and info2.ico from The zipfile here, which gives me a yellow and blue "i" - nice!
    # Test Icons from http://www.royaltyfreeart.com/favicons.html use Win32::GUI; use strict; my $okIcon = new Win32::GUI::Icon("info1.ico"); my $badIcon = new Win32::GUI::Icon("info2.ico"); my $lastState = 1; # start off ok my $iconCounter = 1; # maintain an icon count my $main = Win32::GUI::Window->new(); DoIcon($okIcon, $iconCounter); # set the initial icon while(1){ if (int rand 2) # Yeah, This is how I do system monitoring! { unless ($lastState) { # Everything's ok now - it wasn't last time round changeIcon($okIcon); $lastState = 1; } } else { if ($lastState) { # Something's gone down - everything was ok last check changeIcon($badIcon); $lastState = 0; } } sleep(5); } sub DoIcon { my ($icon, $id) = @_; $main->AddNotifyIcon( -name => "Tray", -tip => $id, -icon => $icon, -id => $id, ); } sub changeIcon { my $icon = shift; DoIcon($icon, $iconCounter); # Clear the old Icon DoIcon($icon, ++$iconCounter); # Set the new one and incriment coun +ter }
    Let me know if it works - it might just be a funny bug on my machine. FYI. Win32::GUI version is 0.0.434, I'm running ActivePerl build 629 on Win2k.

    Simon Flack ($code or die)
    $,=reverse'"ro_';s,$,\$,;s,$,lc ref sub{},e;$,
    =~y'_"' ';eval"die";print $_,lc substr$@,0,3;
Re: How do you toggle the system tray icon using Win32::Gui?
by Moonie (Friar) on Oct 01, 2001 at 22:56 UTC
    vroom, take a look at this: example script - it may give you some ideas. Check out this brief tutorial: Win32-GUI-How To - under System Tray Icon. Also, about the icon disappearing - is a bug.
    There is a small bug in this program. The tray icon does not disappear + immediately when the program terminates. Instead, it remains in the +system tray until you point the mouse cursor at it, when it disappear +s. This is a bug in Win32::GUI - when you close your program, you sho +uld explicitly remove any system tray icons you still have displayed. + Win32::GUI does not (yet) have a way of removing a tray icon. Hopefu +lly, this will be fixed in a later version.

    Good Luck,
    - Moon

      I think that this bug actually leaves the icon there even when the app that placed it there has exited. However, at least under 2000, this bug no longer seems to be present.

      -jehuni

        I am running 2000 and I still get this bug. However this doesn't really answer the question of "changing" the icon. The documentation already mentioned says : <blockquot>Win32::GUI does not (yet) have a way of removing a tray icon As far as I can see, there is no way of "changing" the icon either. All you can do is add a new one. But if you can't delete the old one, that's no use either. Try out this code and tell me if the icons still disappear\change as they should (It doesn't on my system):
        use Win32::GUI; my $main = Win32::GUI::Window->new(); my $icon = Win32::GUI::Icon->new('test.ico'); my $tray = $main->AddNotifyIcon( -name => 'tray', -icon => $icon, -id => 0, -tip => 'icon1' ); sleep 5; # hover mouse over icon to see tooltip undef $tray; # try and get rid of old icon $tray = $main->AddNotifyIcon( -name => 'tray', -icon => $icon, -id => 0, -tip => 'icon2' ); sleep 5; # hover mouse over new icon again


        Simon Flack ($code or die)
        $,=reverse'"ro_';s,$,\$,;s,$,lc ref sub{},e;$,
        =~y'_"' ';eval"die";print $_,lc substr$@,0,3;
Re: How do you toggle the system tray icon using Win32::Gui?
by jplindstrom (Monsignor) on Oct 02, 2001 at 05:26 UTC
    Awhile back Jason Bingham wrote (on the win32-gui-users list):

    Don't know how supported it is but this is what I had to do is call Win32::GUI::NotifyIcon::Modify directly (it is located in the GUI.xs file for those with the source). Example works off the click on the tray icon.

    Don't forget to get the -id bit the same across all calls.... Other problem I came across was the limit of 63 chars for the -tip windows doesn't like it and the good doctor will come and visit if you make it too long.

    - snipped example -

    Win32::GUI::NotifyIcon::Modify( $win, -id => 1, -icon => $icoDis, -tip => "Not Recording",

    I would imagine this is the most "correct" way of changing the icon.

    Also, you can't sleep() within a Win32::GUI program, that will freeze the UI for the user.

    What you do is call Win32::GUI::Dialog(), then wait for some event to happen. There is a timer control. Return -1 from an event handler to exit the main event loop.

    /J

      Yeah, OK, this is old, but if I found it someone else may also. Now it's a wiki.

      In current form (ActiveState 5.8.8), the 'Win32::GUI::NotifyIcon::Modify' method is gone and so is the '-id' option. Use of the former will fail and use of the latter will produce a warning.

      'ModifyIcon' has been replaced by a 'Change' method. So to do smooth animation - like what was being attempted here, you do something like:

      our $ni; $ni = $win->AddNotifyIcon ( -icon => $ico[0], -tip => "Look both ways before crossing the street", );

      Then in the timer:

      $ni->Change( -icon => $ico[$index] );

      Sean

Re: How do you toggle the system tray icon using Win32::Gui?
by clintp (Curate) on Oct 02, 2001 at 00:27 UTC
    I can't get the samples to work, much less take a stab at the problem. Apparently under WinNT4 "Your vendor has not implemented the macro AddNotifyIcon." But I had a thought:

    Consider MS KB Article Q162613. In it, there's a description of the API as seen through visual basic. The difference between an "Add", "Change" and "Remove" in the API appears to be 1 argument. The VB call is to "Shell_NotifyIcon" which looks an awful lot like the "NotifyIcon" method call that Win32::GUI uses. Can someone (who can get this to work) hack at the API a little bit to see if these are indeed the same call. And if possible change the argument of "0" (ADD) to "1" (MODIFY). It might get you some of the way there...

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://115924]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chilling in the Monastery: (3)
As of 2024-04-20 01:15 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found