Name

TrayIcon? mit Win32::GUI::NotifyIcon

Aufgabe

Bei Windows unten bei der Uhr ein Icon anzeigen.

Erklärung

Ich versuche hier in diesem Text zu erklären wie man per Win32::Gui ein TrayIcon? erstellt. Als erstes müssen sie ein Win32::Gui Hauptfenster erstellen. Den nur ein TrayIcon? geht leider nicht. Dies rufen wir hiermit auf.
Code
main = Win32::GUI::Window->new(
    -name    => 'Main',
    -text    => 'Perl TrayIcon',
    -width   => 0,
    -height  => 0,
    -visible => 0,
);

Bezeichner Bedeutung
-name Gibt die interne Bezeichnung für das Fenster an.
-text Title des Fensters.
-width Breite des Fensters.
-height Höhe des Fensters.
-visible Sichtbarkeit: 0 unsichtbar, 1 sichtbar.

Als nächstes definieren wir was wir als Icon nutzen wollen
Code
my $icon = new Win32::GUI::Icon('server.ICO');

Danach können wir das Icon aufrufen.
Code
my $ni = $main->AddNotifyIcon(
    -name => "systray",
    -id   => $id,
    -icon => $icon,
    -tip  => "tooltip",
);

Bezeichner Bedeutung
-name Gibt die interne Bezeichnung für das Fenster an.
-id Eine eindeutige Bezeichnung für das NotifyIcon? Objekt.
-icon Hier wird der Icon angegeben den wir oben angelegt haben. Siehe „my $icon“
-tip Der Tooltip, der angezeigt wird wenn man mit dem Mauszeiger darüber bleibt.

Wenn man jetzt noch Win32::GUI::Dialog(); im Script angibt ist es eigentlich schon benutzbar, hat aber noch keine Funktion. Hierfür hat NotifyIcon? noch Events parat:

Event Bedeutung
Click() Wird ausgeführt wenn man mit der linken Maustaste draufdrückt.
RightClick?() Wird ausgeführt wenn man mit der rechten Maustaste draufdrückt.
Mouseevent() Selber leider noch nicht genutzt. Soll aber auf bestimmt Mausereignisse reagieren können.

Ich werde hier nur RightClick? erklären da ich dies am meisten genutzt habe und da es den anderen Events sehr ähnlich ist. Als erstes muss erst mal das Menü mit Win32::GUI::Menu definiert werden. Diese muss auf jeden Fall vor "Win32::GUI::Dialog();" gemacht werden sonst werden die Menüpunkte keine Funktion haben.

Code
my $systray_menu = new Win32::GUI::Menu(
        "SystrayMenu Functions" =>"SystrayMenu",
        "> Info"       => "Systray_info",
        "> Dienst"     => "",
        ">> Starten"   => "Systray_start",
        ">> Stoppen"   => "Systray_stop",
        ">> Restart"   => "Systray_restart",
        ">> Pausieren" => "Systray_pause",
        "> Exit"       => "SystrayExit",
    );
My $systray_menu… Erklärung der Parameter:

Parameter Bedeutung
"> Info" => "Systray_info" > bedeutet das es ein Hauptmenüpunkt ist. Und das hinter der => sagt aus welche Subroutine aufgerufen werden soll.
">> Starten" => "Systray_start" >> bedeutet das es ein Untermenüpunkt ist.

Danach wird die Sub angelegt die für das Rechtsklickmenü zuständig ist.
Code
sub systray_RightClick {
    my($x, $y) = Win32::GUI::GetCursorPos();
    $main->TrackPopupMenu($systray_menu->{SystrayMenu},   $x, $y-50);
}

my($x, $y) = Win32::GUI::GetCursorPos();
ließt aus wo sich der Mauszeiger gerade befindet.

$main->TrackPopupMenu($systray_menu->{SystrayMenu}, $x, $y-50);
öffnet das oben angelegte Menü.

Wenn man einen sub einem Menüpunkt zuordnen möchte muss man die wie folgt machen
Code
...
"> Info"       => "Systray_info",
...
sub Systray_info_Click{
print "Ein Test \n";
}
So das wärs auch schon fast.

Jetzt noch ein kleines extra am Ende. NotifyIcon? hat nämlich leider einen kleien Bug. Wenn das Programm beendet wird, wird das Icon leider nicht gelöscht. Dies kann man mit diesen beiden Subs abfangen.
Code
sub Main_Terminate {
    Win32::GUI::NotifyIcon::Delete( $ni, -id =>  $id );
    return -1;    
}
sub systray_Terminate {
    Win32::GUI::NotifyIcon::Delete( $ni, -id =>  $id );
    return -1;
}

Skript

Hier noch mal den ganzen Code zur Veranschaulichung.
tray.pl
#!/usr/bin/perl
use Win32::GUI;
use strict;
use warnings;

my $id = 1;
my $hwnd = GUI::GetPerlWindow(); GUI::Hide($hwnd);
my $icon = new Win32::GUI::Icon('server.ICO';);
my $main = Win32::GUI::Window->new(
    -name   => 'Main',
    -text   => 'Perl',
    -width  => 200,
    -height => 200,
);
my $ni = $main->AddNotifyIcon(
    -name => "systray",
    -id   => $id,
    -icon => $icon,
    -tip  => "Go Back!up",
);
my $systray_menu = new Win32::GUI::Menu(
        "SystrayMenu Functions" => "SystrayMenu",
        #"Go Back!up",
        "> Info"       => "Systray_info",
        "> Dienst"     =>"",
        ">> Starten"    => "Systray_start",
        ">> Stoppen"   => "Systray_stop",
        ">> Restart"   => "Systray_restart",
        ">> Pausieren" => "Systray_pause",
        "> Exit"       => "SystrayExit",
    );
Win32::GUI::Dialog();
Win32::GUI::Show($hwnd);



sub systray_RightClick {
    my($x, $y) = Win32::GUI::GetCursorPos();
    $main->TrackPopupMenu($systray_menu->{SystrayMenu}, $x, $y-50);
}

sub Main_Terminate {
    Win32::GUI::NotifyIcon::Delete( $ni, -id =>  $id );
    return -1;    
}

sub systray_Terminate {
    Win32::GUI::NotifyIcon::Delete( $ni, -id =>  $id );
    return -1;
}

Ergänzungen, Kommentare

So das war mein erstes WiKi?. Ich hoffe ich kann jemandem damit weiterhelfen. Bei Frage könnt ihr euch ja im Forum melden. Da bin ich auch öfters anzutreffen.

In dieses Sinne "Happy Coding" wink

Gruß Serioscha Zipp

Verschönerungen

-- ChristianDuehl - 21 Apr 2005

---### Main.??? - 14 Jul 2003 - Betreff

UtilPerlSkripteSubForm edit

Titel TrayIcon? mit Win32::Gui
Autor SerioschaZipp
Bereich WinSkripte
Topic revision: 2006-05-17, SerioschaZipp
 
Bitte die NutzungsBedingungen beachten.
Bei Vorschlägen, Anfragen oder Problemen mit dem PerlCommunityWiki bitten wir um WebBottomBarExample">Rückmeldung.