Messagebox Verhalten mit im Hintergrund laufenden Timer

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 12 Antworten in diesem Thema. Der letzte Beitrag () ist von HenryV.

    Messagebox Verhalten mit im Hintergrund laufenden Timer

    Grüß euch,

    Ich bin gerade dabei eine Art "Totmannschalter" für ein Drittprogramm zu erstellen. Das Ganze wurde von mir so erstellt das beim beim starten des Programms das Drittprogramm mitgestartet wird und nach einer gewissen Zeit eine
    MessageBox erscheint die fragt ob man weiterarbeiten möchte. Wenn ja wird der Counter zurückgesetzt, wenn nein oder keine Reaktion des Users wird das mein Programm und das Drittprogramm beendet. Das funktioniert auch alles wunderbar

    Jetzt habe ich folgendes Problem:

    Benutze ich einfach MessageBox.Show(Message) läuft der Counter im Hintergrund weiter.
    Benutze ich aber MessageBox.Show(Message, "Warnung", MessageBoxButtons.YesNo, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly) stoppt der Counter bis mit der MessageBox interagiert wird.
    Ich schätze es liegt an der "MessageBoxOptions.DefaultDesktopOnly"-Option, diese brauche ich aber damit sich das Fenster in den Vordergrund schiebt.
    Gibt es dafür eine Alternative die den Counter weiterlaufen lässt?


    Hier mein Code abgeändert auf notepad :)

    VB.NET-Quellcode

    1. Imports System.ComponentModel
    2. Public Class Form1
    3. Dim reset As Boolean = False
    4. Dim countdown As Integer = 30
    5. Dim CustomProcess As New System.Diagnostics.Process()
    6. Dim Message As String = "Vorsicht Notepad wird in 10 sec geschlossen. Wollen sie weiterarbeiten?"
    7. Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    8. countdown = countdown - 1
    9. TextBox1.Text = countdown
    10. If countdown = 10 Then
    11. MessageBox.Show(Message, "Warnung", MessageBoxButtons.YesNo, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly)
    12. 'MessageBox.Show(Message)
    13. If DialogResult.Yes Then
    14. countdown = 30
    15. ElseIf DialogResult.Yes = False Then
    16. Me.Close()
    17. End If
    18. ElseIf countdown = 0 Then
    19. 'programm schließen
    20. Me.Close()
    21. ElseIf CustomProcess.HasExited = True Then
    22. Me.Close()
    23. End If
    24. End Sub
    25. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
    26. Timer1.Interval = 1000
    27. Timer1.Start()
    28. CustomProcess.StartInfo.FileName = "notepad.exe"
    29. CustomProcess.Start()
    30. 'Me.WindowState.Minimized
    31. End Sub
    32. Private Sub Form1_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing
    33. Try
    34. CustomProcess.Kill()
    35. Catch ex As Exception
    36. End Try
    37. End Sub
    38. End Class


    LG
    Bernsi
    Hallo

    Was mir auf die schnelle einfallen würde wäre:

    Statt MessageBox.Show im TimerTick startest du einen zweiten Timer. Dieser läuft z.b. nach 100ms ab.
    Im Tick stoppt du diesen Timer und zeigst die Messagebox.

    Ich denke das sollte klappen.

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Hi Sascha,

    Danke für deine Antwort.
    Hab das jetzt probiert (sofern ich das richtig verstanden habe) scheint leider nicht zu funktionieren :(

    Hier mein Versuch:

    VB.NET-Quellcode

    1. Imports System.ComponentModel
    2. Public Class Form1
    3. Dim reset As Boolean = False
    4. Dim countdown As Integer = 30
    5. Dim CustomProcess As New System.Diagnostics.Process()
    6. Dim Message As String = "Vorsicht Notepad wird in 10 sec geschlossen. Wollen sie weiterarbeiten?"
    7. Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    8. countdown = countdown - 1
    9. TextBox1.Text = countdown
    10. If countdown = 10 Then
    11. Timer2.Start()
    12. ElseIf countdown = 0 Then
    13. 'programm schließen
    14. Me.Close()
    15. ElseIf CustomProcess.HasExited = True Then
    16. Me.Close()
    17. End If
    18. End Sub
    19. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
    20. Timer1.Interval = 1000
    21. Timer1.Start()
    22. Timer2.Interval = 100
    23. CustomProcess.StartInfo.FileName = "notepad.exe"
    24. CustomProcess.Start()
    25. 'Me.WindowState.Minimized
    26. End Sub
    27. Private Sub Form1_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing
    28. Try
    29. CustomProcess.Kill()
    30. Catch ex As Exception
    31. End Try
    32. End Sub
    33. Private Sub Timer2_Tick(sender As Object, e As EventArgs) Handles Timer2.Tick
    34. Timer2.Stop()
    35. If MessageBox.Show(Message, "Warnung", MessageBoxButtons.YesNo, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly) = DialogResult.Yes Then
    36. countdown = 30
    37. End If
    38. End Sub
    39. End Class


    LG
    Bernsi
    Hallo

    Schade, ein versuch war es Wert.

    Ich würde an deiner Stelle eine Form anzeigen anstatt einer Messagebox. Diese kann ja auch "TopMost" angezeigt werden und da läuft dein Code sicher durch.
    Wobei ich (wenn unter Window 10) eine Nachricht in die Nachrichtenzentrale schmeißen würde, das ist imho effektiver.

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Bernsi schrieb:

    VB.NET-Quellcode

    1. Dim Message As String = "Vorsicht Notepad wird in 10 sec geschlossen. Wollen sie weiterarbeiten?"
    Das ist doch irgendwo suboptimal, denn der User will ganz gewiss weitermachen, nur muss er in diesem Moment ein wichtiges Telefonat tätigen und das Programm ist futsch.
    Das lässt sich doch ganz gewiss mit API.ShowWindow(hWnd, SW_HIDE) erledigen und auf dem Hauptprogramm mit nem Button und API.ShowWindow(hWnd, SW_SHOW) wieder restaurieren.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @RodFromGermany
    Es geht dabei um eine Software zur Werkzeugverwaltung die lizenzgebunden ist und bei der diese Usergruppe nur Viewingrechte hat.
    Der Sinn dahinter ist das nicht permanent Lizenzen von Sessions blockiert werden, die nicht mehr benötigt werden. Wenn ich das Fenster nur verstecke
    dann bleibt die Lizenz dahinter ausgecheckt.

    @ErfinderDesRades
    Gerne wenn du einen Link zu einem Beispiel hast.
    ich hab probiert, und der Zähler läuft auch weiter. Nur wenn die Anwendung schließt bleibt die Messagebox trotzdem geöffnet.
    Und ich find bislang kein Mittel, eine geöffnete Messagebox programmgesteuert zu schließen.
    aber probier selbst:

    VB.NET-Quellcode

    1. Imports System.ComponentModel
    2. Imports System.Threading
    3. Imports System.Threading.Tasks
    4. Public Class Form1
    5. Dim reset As Boolean = False
    6. Dim countdown As Integer = 20
    7. Dim CustomProcess As New System.Diagnostics.Process()
    8. Dim Message As String = "Vorsicht Notepad wird in 10 sec geschlossen. Wollen sie weiterarbeiten?"
    9. Private Async Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    10. countdown = countdown - 1
    11. TextBox1.Text = countdown.ToString
    12. If countdown = 10 AndAlso Await Task.Run(AddressOf MsgBox) = DialogResult.Yes Then countdown = 30
    13. If countdown = 0 OrElse CustomProcess.HasExited Then Me.Close()
    14. End Sub
    15. Private Function MsgBox() As DialogResult
    16. Return MessageBox.Show(Message, "Warnung", MessageBoxButtons.YesNo, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly)
    17. End Function
    18. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
    19. Timer1.Interval = 1000
    20. Timer1.Start()
    21. CustomProcess.StartInfo.FileName = "notepad.exe"
    22. CustomProcess.Start()
    23. End Sub
    24. Private Sub Form1_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing
    25. Try
    26. CustomProcess.Kill()
    27. Catch ex As Exception
    28. End Try
    29. End Sub
    30. End Class




    Übrigens empfehle ich dir dringend Visual Studio - Empfohlene Einstellungen
    Du proggst offsichtlich unter Strict Off, und das ist sehr verheerend, und verbirgt reihenweise Fehler in deim Code.
    @Bernsi Isses da bicht besser festzustellen, ob der User seit n Sekunden das entsprechende Programmteil nicht (mehr) benutzt hat?
    Und dann einen Haken AutoLogout, da wird die Lizenz geschlossen und gut.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    Bernsi schrieb:

    Bin ja noch a bisserl noob was das ganze angeht
    Dann gugst Du vielleicht hier: [Sammelthread] Programmieren, aber was? (Programmideen)
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ich habe die Antwort von @ErfinderDesRades anhand dieses Tipps ergänzt.

    Spoiler anzeigen

    Visual Basic-Quellcode

    1. Imports System.ComponentModel
    2. Public Class Form1
    3. Dim countdown As Integer = 20
    4. Dim CustomProcess As New System.Diagnostics.Process()
    5. Dim Message As String = "Vorsicht Notepad wird in 10 sec geschlossen. Wollen sie weiterarbeiten?"
    6. Dim res As DialogResult '= DialogResult.Yes
    7. Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    8. countdown = countdown - 1
    9. TextBox1.Text = countdown.ToString
    10. If countdown = 10 Then MsgBox()
    11. If countdown = 0 OrElse res = DialogResult.No OrElse CustomProcess.HasExited Then Me.Close()
    12. End Sub
    13. Private Sub MsgBox()
    14. Dim w As Form = New Form() With {.Size = New Size(0, 0), .TopMost = True}
    15. Task.Delay(TimeSpan.FromSeconds(10)).ContinueWith(Sub(t) w.Close(), TaskScheduler.FromCurrentSynchronizationContext())
    16. res = MessageBox.Show(w, Message, "Warnung", MessageBoxButtons.YesNo)
    17. If res = DialogResult.Yes Then countdown = 30
    18. End Sub
    19. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
    20. Timer1.Interval = 1000
    21. Timer1.Start()
    22. CustomProcess.StartInfo.FileName = "notepad.exe"
    23. CustomProcess.Start()
    24. End Sub
    25. Private Sub Form1_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing
    26. Try
    27. CustomProcess.Kill()
    28. Catch ex As Exception
    29. End Try
    30. End Sub
    31. End Class