Hallo zusammen.
Vorgeschichte: Manche Apps von mir sind für den dauerhaften Betrieb nötig, sodass ich verhindern will, dass jemand sie über das
Meine Aufgabe: Ich will solch minimierte Apps zusätzlich durch ein anderes Programm schließen können, muss also der minimierten App ein Signal geben, dass sie sich schließen soll. Ein
Das Problem: Schicke ich
Der Schließen-Beispiel-Code:
Spoiler anzeigen
Das Setzen von
Vorgeschichte: Manche Apps von mir sind für den dauerhaften Betrieb nötig, sodass ich verhindern will, dass jemand sie über das
[X]
versehentlich schließt. Stattdessen sollen sie nur in den Traybereich verschwinden, genauso wenn man auf Minimieren klickt (also: klickt man auf Minimieren [_]
, verschwindet die App auch im Traybereich). Das tatsächliche Schließen der App geht dann nur über das TrayIcon. Im Anhang ist eine Beispiel-App, Rechtsklick auf das TrayIcon beendet das Programm.Meine Aufgabe: Ich will solch minimierte Apps zusätzlich durch ein anderes Programm schließen können, muss also der minimierten App ein Signal geben, dass sie sich schließen soll. Ein
Kill
ist zu heftig, da dann die App nicht sauber schließt und ggf. Daten verloren gehen.Das Problem: Schicke ich
WM_CLOSE
an die Ziel-App, reagiert diese darauf oder eben nicht. Wird die App nämlich per Minimieren in den Traybereich geschickt, reagiert die App auch auf WM_CLOSE
. Wird sie hingegen per Klick auf [X]
minimiert, reagiert die App nämlich nicht auf WM_CLOSE
, auch wenn danach die App wieder angezeigt und dann per Klick auf [_]
minimiert wird. Beim Klick auf [X]
scheint also was zu geschehen, was das spätere, externe Schließen per WM_CLOSE
-Versand unterbindet. Nur was? Und wie kann man das verhindern oder rückgängig machen?Der Schließen-Beispiel-Code:
VB.NET-Quellcode
- Friend Class FrmMain
- <DllImport("user32.dll", CharSet:=CharSet.Auto)> Private Shared Function FindWindow(className As String, windowName As String) As IntPtr : End Function
- <DllImport("user32.dll", CharSet:=CharSet.Auto)> Private Shared Function SendMessage(hWnd As IntPtr, msg As Integer, wParam As IntPtr, lParam As IntPtr) As IntPtr : End Function
- Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
- Dim NameOfProcess = "WinFormsVbNetFx"
- Dim TitleOfForm = "Hauptformular"
- Dim CountBeforeKill = Diagnostics.Process.GetProcessesByName(NameOfProcess).Length
- If CountBeforeKill = 0 Then MessageBox.Show("ZielApp läuft nicht") : Return
- Dim WindowHandle = FindWindow(Nothing, TitleOfForm)
- If WindowHandle = IntPtr.Zero Then MessageBox.Show("ZielApp läuft nicht") : Return
- Dim WM_CLOSE = &H10
- Dim WM_QUIT = &H12
- Dim WM_DESTROY = &H2
- For Each Message In {WM_CLOSE, WM_QUIT, WM_DESTROY}
- SendMessage(WindowHandle, Message, IntPtr.Zero, IntPtr.Zero)
- Threading.Thread.Sleep(1000)
- Dim CountAfterKill = Diagnostics.Process.GetProcessesByName(NameOfProcess).Length
- If CountBeforeKill > CountAfterKill Then MessageBox.Show(Message.ToString) : Close() : Return
- Next
- MessageBox.Show("das Schließen hat gar nicht funktioniert")
- End Sub
- End Class
Das Setzen von
ControlBox
auf False
und so das Entfernen der entsprechenden Boxen ist natürlich eine Option, aber ich will hier die Abläufe verstehen.Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.
Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „VaporiZed“ ()