[Powershell]

JägerMeister05

Lt. Junior Grade
Registriert
Sep. 2005
Beiträge
451
[Powershell] Event beim minimieren der GUI

Hallo,

ich habe schon viel gesucht, jedoch finde ich die Lösung meines Problems nicht. Ich habe mit Powershell eine Gui gebastelt und möchte jetzt festlegen was passieren soll wenn man den "minimieren"-button drückt am Fensterrand, so wie bei jedem Windows-Fenster oben rechts (da wo auch Maximieren und X ist). Hat jemand ne Ahnung ?

MfG JägerMeister
 
Zuletzt bearbeitet:
Ich gehe mal davon aus du nutzt Windows Forms.
Wenn ja, dann solltest du dich etwas mit Event Handling beschäftigen.

Ich hab dir mal ein kleines Beispiel geschrieben, die Kommentare im Code helfen hoffentlich:
Code:
[Reflection.Assembly]::LoadWithPartialName( "System.Windows.Forms")

# Diese Funktion wird jedes mal ausgeführt, wenn das SizeChanged Event feuert
# (also immer wenn sich auf irgendeine Weise die Größe des Fensters ändert)
function form_SizeChanged
{
    # Prüfen ob das Fenster minimiert wurde, wenn ja irgendwas tun
    if($form.WindowState -eq [Windows.Forms.FormWindowState]"Minimized")
    {
        # TODO: irgendwas
    }
}

$form = New-Object Windows.Forms.Form

# Hier wird ein Event Handler für das SizeChanged Event registriert
# (in diesem Fall die Funktion form_SizeChanged die weiter oben definiert wurde)
$form.add_SizeChanged({form_SizeChanged})

$form.ShowDialog()

Ist zwar etwas unschön, da du so nicht direkt auf den Klick auf den Minimieren Button reagierst, sondern erst, wenn das Fenster schon minimiert wurde, aber besser gehts meines Wissens nach in einem Powershell Script nicht.

Nützliche Links:
Control.SizeChanged-Ereignis
Form.WindowState-Eigenschaft
FormWindowState-Enumeration
 
Zuletzt bearbeitet:
Ja das hat mir weiter geholfen, danke.


//edit: noch eine Frage da du dich ja anscheinend besser auskennst: könntest du mir einen Tipp geben wie ich vielleicht eine GUI in den Hintergrund verschwinden lasse ohne das sie sich dabei schliesst? So das sie weder in der Taskleiste noch sonstwo sichtbar ist. Dafür habe ich nämlich dann ein NotifyIcon.


//edit: sorry mir ist grad aufgefallen das ich den Threadtitel völlig vergessen habe.
 
Zuletzt bearbeitet:
Ich denke das Problem das du hast ist, dass du wohl ShowDialog() zum anzeigen der Form nutzt.
(ist auch dämlich dass ich das in meinem Beispiel so gemacht habe, aber ich war mir nicht sicher auf was du hinaus willst, also hab ich der Einfachheit halber ShowDialgog() genutzt)

ShowDialog() blockiert dein Skript so lange, bis das Fenster geschlossen wird. Ein (modaler) Dialog wird auch geschlossen, wenn er nur (z.B. per Hide()) versteckt wird.
Sobald also der Dialog geschlossen/versteckt wird läuft dein Skript weiter und wenn ShowDialog() die letzte Anweisung im Skript ist, dann endet es.

Soweit so gut.
Nur wie lässt sich das beheben?

Ganz einfach: Man sollte das Fenster nicht als Dialog, sondern als non-modales Fenster anzeigen.
Das Problem ist, dass man nicht einfach Show() aufrufen kann, da Powershell keine message pump/loop erzeugt und das Fenster dadurch nutzlos ist, da es keine Anweisungen verarbeiten kann.
(ShowDialog() hingegen erzeugt eine eigene message loop für den Dialog)

Die Lösung:
Die Application.Run Methode, der man ein Form Objekt übergeben kann.
Die Methode erzeugt eine message loop, assoziiert sie mit der Form und zeigt die Form letztendlich an.

Ich hab das obige Beispiel mal etwas umgebaut und entscheidende Stellen im Code kommentiert:
(kannst du in dieser Form auch als Basis für deine Anwendung mit NotifyIcon nutzen)
Code:
[Reflection.Assembly]::LoadWithPartialName( "System.Windows.Forms")

function form_SizeChanged
{
    if($form.WindowState -eq [Windows.Forms.FormWindowState]"Minimized")
    {
        $form.Hide()
    }
}

function notifyIcon_Click
{
    if($form.Visible)
    {
        $form.Hide()
    }
    else
    {        
        $form.Show()        
        $form.WindowState = [Windows.Forms.FormWindowState]"Normal"
    }
}

    
$form = New-Object Windows.Forms.Form
$form.add_SizeChanged({form_SizeChanged})

$notifyIcon = New-Object Windows.Forms.NotifyIcon
$notifyIcon.Icon = New-Object System.Drawing.Icon("C:\IrgendeinPfad\IrgendeinIcon.ico")
$notifyIcon.Visible = $True
$notifyIcon.add_Click({notifyIcon_Click})

# Dieser Aufruf blockt solange bis das Fenster geschlossen wird.
# Außerdem wird ein message pump/loop für das Fenster gestartet.
[System.Windows.Forms.Application]::Run($form)
    
# wichtig, sonst bleibt das Icon nach dem Beenden im Tray
# und wirft Exceptions beim draufklicken.
$notifyIcon.Dispose()
 
Zuletzt bearbeitet:
Wow du hast endlich mein Problem gelöst, ich habe seit Tagen nach ner Lösung gesucht und hab schon fast aufgegeben. Ich habe nämlich ein kleines Monitoring-tool speziell für meinen Raid-Controller geschrieben was auch schon einwandfrei funktioniert, nur eben diese Sache mit dem Systray und der GUI hat nicht funktioniert so wie ich das wollte. Vielen Dank nochmal.
 
Zurück
Oben