Auf SpeechSynthesizer() Ende der Sprachausgabe in einer Sub warten

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

Es gibt 36 Antworten in diesem Thema. Der letzte Beitrag () ist von Westerwälder.

    Auf SpeechSynthesizer() Ende der Sprachausgabe in einer Sub warten

    Guten Morgen,

    programme mir zur Zeit ein kleines Hilfsprogramm mit Sprachausgabe.
    Nun möchte ich in einer Sub auf das Ende der Sprachausgabe warten.
    Die Lösung mit DoEvents gefällt mir nicht wirklich:

    VB.NET-Quellcode

    1. With Sprachausgabe
    2. .Gestartet = True
    3. .Sprachtext = "Hallo " & Anwender.Vorname & " ich bin das Hilfsprogramm, gleich geht es los. Beendet werde ich mit der f 1 taste"
    4. .Sprachgeschwindigkeit = Me.Sprachtempo
    5. .Vorlesen()
    6. End With
    7. Me.Timer_Pruefung.Enabled = True
    8. Do While Sprachausgabe.Gestartet
    9. Application.DoEvents()
    10. Loop
    11. Private Sub Timer_Pruefung_Tick(sender As Object, e As EventArgs) Handles Timer_Pruefung.Tick
    12. If Sprachausgabe.Gestartet = False Then Exit Sub
    13. If Not Me.currentlyAnimating Then Me.Animation_Starten()
    14. If Sprachausgabe.IsWorking = False Then
    15. Me.Timer_Pruefung.Enabled = False
    16. Sprachausgabe.Gestartet = False
    17. End If
    18. End Sub


    wie könnte man das anders lösen?

    Habe gerade festgestellt, dass bei Schliessen der Form mit me.close

    auf der Startform (also andere Form) folgender Fehler produziert wird:

    Ein Ausnahmefehler des Typs "System.ObjectDisposedException" ist in System.Windows.Forms.dll aufgetreten.
    Zusätzliche Informationen: Auf das verworfene Objekt kann nicht zugegriffen werden.

    VB.NET-Quellcode

    1. Private Sub TS_System_Programm_Tour_Click(sender As Object, e As EventArgs) Handles TS_System_Programm_Tour.Click
    2. If Misterdos.Visible Then Exit Sub
    3. Misterdos.Modus = "A"
    4. Misterdos.Show()
    5. End Sub


    Vielleicht stelle ich mal den kompletten Code zur Verfügung

    Spoiler anzeigen


    VB.NET-Quellcode

    1. Public Class Misterdos
    2. Declare Sub mouse_event Lib "user32.dll" (ByVal dwFlags As UInt32, ByVal dx As UInt32, ByVal dy As UInt32, ByVal dwData As UInt32, ByVal dwExtraInfo As IntPtr)
    3. Public Modus As String
    4. Private animatedImage As New Bitmap(Pfade.Diverse.Pfad & "Misterdos.gif")
    5. Private currentlyAnimating As Boolean = False
    6. Private Sprachtempo As Integer
    7. Private Taste_F1 As MBC_Diverse.Hotkey
    8. Private I As Integer
    9. Private PosOben As Integer
    10. Private PlusOben As Integer
    11. Private PosLinks As Integer
    12. Private TS_DDButton As ToolStripDropDownButton
    13. Private TS_ToolstripLabel As ToolStripLabel
    14. Private Sub Misterdos_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
    15. Me.Timer_Pruefung.Enabled = False
    16. Me.Animation_Beenden()
    17. Me.Modus = Nothing
    18. Sprachausgabe.Stopp()
    19. End Sub
    20. Private Sub Misterdos_Load(sender As Object, e As EventArgs) Handles Me.Load
    21. Me.Visible = False
    22. Me.Opacity = 0
    23. Me.Visible = True
    24. Monitor.Form_Initalisieren(Me)
    25. Me.KeyPreview = True
    26. Me.BackColor = Color.White
    27. Me.TransparencyKey = Color.White
    28. Me.PlusOben = 22
    29. Me.Taste_F1 = New MBC_Diverse.Hotkey
    30. Me.Taste_F1.TryRegister(Keys.F1)
    31. AddHandler Taste_F1.Pressed, AddressOf Me.Beendetaste
    32. Me.Timer_Pruefung.Enabled = False
    33. Me.Opacity = 1
    34. Me.BringToFront()
    35. Me.TopMost = True
    36. Me.Animation_Starten()
    37. With Sprachausgabe
    38. .Gestartet = True
    39. .Sprachtext = "Hallo " & Anwender.Vorname & " ich bin das Hilfsprogramm, gleich geht es los. Beendet werde ich mit der f 1 taste"
    40. .Sprachgeschwindigkeit = Me.Sprachtempo
    41. .Vorlesen()
    42. End With
    43. Me.Timer_Pruefung.Enabled = True
    44. Do While Sprachausgabe.Gestartet
    45. Application.DoEvents()
    46. Loop
    47. If Me.Modus = "A" Then Me.Part_Startmenue()
    48. End Sub
    49. Private Sub Beenden()
    50. With Sprachausgabe
    51. .Gestartet = True
    52. .Sprachtext = "Ich hoffe es hat dir gefallen. tschüss"
    53. .Sprachgeschwindigkeit = Me.Sprachtempo
    54. .Vorlesen()
    55. End With
    56. Me.Timer_Pruefung.Enabled = True
    57. Do While Sprachausgabe.Gestartet
    58. Application.DoEvents()
    59. Loop
    60. Me.Close()
    61. End Sub
    62. Private Sub Beendetaste(sender As Object, e As EventArgs)
    63. Me.Close()
    64. End Sub
    65. Private Sub Animation_Starten()
    66. If Not currentlyAnimating Then
    67. ImageAnimator.Animate(animatedImage,
    68. New EventHandler(AddressOf Me.OnFrameChanged))
    69. Me.currentlyAnimating = True
    70. End If
    71. End Sub
    72. Private Sub Animation_Beenden()
    73. ImageAnimator.StopAnimate(animatedImage, New EventHandler(AddressOf Me.OnFrameChanged))
    74. Me.currentlyAnimating = False
    75. End Sub
    76. Private Sub OnFrameChanged(ByVal o As Object, ByVal e As EventArgs)
    77. Me.Invalidate()
    78. End Sub
    79. Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
    80. ImageAnimator.UpdateFrames()
    81. e.Graphics.DrawImage(Me.animatedImage, New Point(0, 0))
    82. End Sub
    83. Private Sub Timer_Pruefung_Tick(sender As Object, e As EventArgs) Handles Timer_Pruefung.Tick
    84. If Sprachausgabe.Gestartet = False Then Exit Sub
    85. If Not Me.currentlyAnimating Then Me.Animation_Starten()
    86. If Sprachausgabe.IsWorking = False Then
    87. Me.Timer_Pruefung.Enabled = False
    88. Sprachausgabe.Gestartet = False
    89. End If
    90. End Sub
    91. Private Sub Vorlesen(ByVal Text As String)
    92. Sprachausgabe.Gestartet = True
    93. Me.Timer_Pruefung.Enabled = False
    94. With Sprachausgabe
    95. .Stopp()
    96. .Sprachtext = Text
    97. .Sprachgeschwindigkeit = Me.Sprachtempo
    98. .Gestartet = True
    99. .Vorlesen()
    100. End With
    101. Me.Timer_Pruefung.Enabled = True
    102. End Sub
    103. Private Sub Bearbeitung_TS_Label(ByVal MeinLabel As ToolStripLabel, ByVal Sprachtext As String)
    104. If Not MeinLabel.Visible Then Exit Sub
    105. Sprachausgabe.Gestartet = True
    106. Me.Timer_Pruefung.Enabled = False
    107. Me.PosOben = 25
    108. Me.PosLinks = MeinLabel.Bounds.Left + MeinLabel.Bounds.Width + 50
    109. Me.Maus_Bewegen(MeinLabel.Bounds.Left + 20, 15)
    110. Me.Top = Me.PosOben
    111. Me.Left = Me.PosLinks
    112. Me.Vorlesen(Sprachtext)
    113. End Sub
    114. Private Sub Bearbeitung_TS_DDButton(ByVal MeinButton As ToolStripDropDownButton,
    115. ByVal MutterItem As ToolStripMenuItem,
    116. ByVal KindItem As ToolStripMenuItem,
    117. ByVal MutterNummer As Integer,
    118. ByVal HatKindItem As Boolean,
    119. ByVal Sprachtext As String)
    120. If Not MeinButton.Visible Then Exit Sub
    121. Sprachausgabe.Gestartet = True
    122. Me.Timer_Pruefung.Enabled = False
    123. If MutterItem Is Nothing AndAlso KindItem Is Nothing Then
    124. Me.PosOben = 25
    125. Me.PosLinks = MeinButton.Bounds.Left + MeinButton.Width + 50
    126. MeinButton.Select()
    127. Me.Maus_Bewegen(MeinButton.Bounds.Left + 20, 15)
    128. Me.Maus_EinfachClick()
    129. Else
    130. If Not MutterItem Is Nothing Then
    131. Me.PosOben = (MutterNummer * Me.PlusOben) + MeinButton.Height
    132. If MeinButton.Width > MutterItem.Width Then
    133. Me.PosLinks = MeinButton.Bounds.Left + MeinButton.Bounds.Width + 50
    134. Else
    135. Me.PosLinks = MeinButton.Bounds.Left + MutterItem.Bounds.Width + 50
    136. End If
    137. MutterItem.Select()
    138. Me.Maus_Bewegen(MeinButton.Bounds.Left + 25, Me.PosOben)
    139. MutterItem.Select()
    140. End If
    141. If Not KindItem Is Nothing Then
    142. Me.PosLinks += KindItem.Width
    143. Me.Maus_Bewegen(MeinButton.Bounds.Left + 25 + MutterItem.Width + KindItem.Width, Me.PosOben)
    144. KindItem.Select()
    145. End If
    146. End If
    147. Me.Top = Me.PosOben
    148. Me.Left = Me.PosLinks
    149. Me.Vorlesen(Sprachtext)
    150. End Sub
    151. Private Sub Maus_Bewegen(ByRef MausLeft As Integer, MausTop As Integer)
    152. Cursor.Position = New Point(MausLeft, MausTop)
    153. End Sub
    154. Private Sub Maus_EinfachClick()
    155. mouse_event(2, 0, 0, 0, New System.IntPtr())
    156. mouse_event(4, 0, 0, 0, New System.IntPtr())
    157. End Sub
    158. Private Sub Maus_DoppelClick()
    159. mouse_event(2, 0, 0, 0, New System.IntPtr())
    160. mouse_event(4, 0, 0, 0, New System.IntPtr())
    161. mouse_event(2, 0, 0, 0, New System.IntPtr())
    162. mouse_event(4, 0, 0, 0, New System.IntPtr())
    163. End Sub
    164. Public Sub Part_Startmenue()
    165. Me.TS_ToolstripLabel = Startmenue.TS_Datum
    166. If Me.TS_ToolstripLabel.Visible Then
    167. Me.Bearbeitung_TS_Label(Me.TS_ToolstripLabel, "Zeigt das aktuelle Datum." &
    168. "Klickst du diesen an, erscheint ein kleiner Kalender.")
    169. Do While Sprachausgabe.Gestartet
    170. Application.DoEvents()
    171. Loop
    172. End If
    173. Me.TS_ToolstripLabel = Startmenue.TS_Uhrzeit
    174. If Me.TS_ToolstripLabel.Visible Then
    175. Me.Bearbeitung_TS_Label(Me.TS_ToolstripLabel, "Zeigt die aktuelle Uhrzeit." &
    176. "Klickst du diesen an, erscheint eine analoge Uhr")
    177. Do While Sprachausgabe.Gestartet
    178. Application.DoEvents()
    179. Loop
    180. End If
    181. Me.TS_DDButton = Startmenue.TS_Menue
    182. If Me.TS_DDButton.Visible Then
    183. Me.TS_DDButton = Startmenue.TS_Menue
    184. If Me.TS_DDButton.Visible Then
    185. Me.Bearbeitung_TS_DDButton(Me.TS_DDButton, Nothing, Nothing, 0, False,
    186. "Anwendungen. hier findest du die Standardprogramme")
    187. Do While Sprachausgabe.Gestartet
    188. Application.DoEvents()
    189. Loop
    190. End If
    191. Me.I = 0
    192. For Each MenueItem As ToolStripMenuItem In Me.TS_DDButton.DropDownItems.OfType(Of ToolStripMenuItem)()
    193. With MenueItem
    194. Me.I += 1
    195. If .Name = "TS_Menue_Astronomie" Then
    196. If .Visible Then
    197. Me.Bearbeitung_TS_DDButton(Me.TS_DDButton, MenueItem, Nothing, Me.I, False,
    198. "Astronomie, Hier findest du Informationen über Sonnensysteme und Sterne")
    199. Do While Sprachausgabe.Gestartet
    200. Application.DoEvents()
    201. Loop
    202. End If
    203. End If
    204. If .Name = "TS_Menue_EMail" Then
    205. If .Visible Then
    206. Me.Bearbeitung_TS_DDButton(Me.TS_DDButton, MenueItem, Nothing, Me.I, True,
    207. "Email")
    208. Do While Sprachausgabe.Gestartet
    209. Application.DoEvents()
    210. Loop
    211. End If
    212. For Each MenueSubItem As ToolStripMenuItem In MenueItem.DropDownItems.OfType(Of ToolStripMenuItem)()
    213. If MenueSubItem.Name = "TS_Menue_EMail_Center" Then
    214. If MenueSubItem.Visible Then
    215. Me.Bearbeitung_TS_DDButton(Me.TS_DDButton, MenueItem, MenueSubItem, Me.I, False,
    216. "Im mailcenter findest Du gesendete und empfange mails")
    217. Do While Sprachausgabe.Gestartet
    218. Application.DoEvents()
    219. Loop
    220. End If
    221. End If
    222. Next
    223. End If
    224. End With
    225. Next
    226. End If
    227. Me.Beenden()
    228. End Sub
    229. End Class




    Gruß Markus

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Westerwälder“ ()

    1. Ich würde die Do while Schleife komplett weglassen inklusive DoEvents.
    2. Beim Schließen der Anwendung Application.exit() benutzen.
    3. Setze einen Public Boolean auf der Startform von Nebenform um Festzustellen ob Form offen (Load Ereignis der nebenform setzt Boolean).
    4. Erst Form öffnen dann auf Form zugreifen.
    Danke, aber was mache ich hier ohne Do while?

    VB.NET-Quellcode

    1. Public Sub Part_Startmenue()
    2. Me.TS_ToolstripLabel = Startmenue.TS_Datum
    3. Me.Bearbeitung_TS_Label(Me.TS_ToolstripLabel, "Zeigt das aktuelle Datum." &
    4. "Klickst du diesen an, erscheint ein kleiner Kalender.")
    5. Do While Sprachausgabe.Gestartet
    6. Application.DoEvents()
    7. Loop
    8. Me.TS_ToolstripLabel = Startmenue.TS_Uhrzeit
    9. Me.Bearbeitung_TS_Label(Me.TS_ToolstripLabel, "Zeigt die aktuelle Uhrzeit." &
    10. "Klickst du diesen an, erscheint eine analoge Uhr")
    11. Do While Sprachausgabe.Gestartet
    12. Application.DoEvents()
    13. Loop
    14. Me.TS_DDButton = Startmenue.TS_Menue
    15. If Me.TS_DDButton.Visible Then
    16. Me.TS_DDButton = Startmenue.TS_Menue
    17. Me.Bearbeitung_TS_DDButton(Me.TS_DDButton, Nothing, Nothing, 0, False,
    18. "Anwendungen. hier findest du die Standardprogramme")
    19. Do While Sprachausgabe.Gestartet
    20. Application.DoEvents()
    21. Loop
    22. Me.I = 0
    23. For Each MenueItem As ToolStripMenuItem In Me.TS_DDButton.DropDownItems.OfType(Of ToolStripMenuItem)()
    24. With MenueItem
    25. Me.I += 1
    26. If .Name = "TS_Menue_Astronomie" Then
    27. Me.Bearbeitung_TS_DDButton(Me.TS_DDButton, MenueItem, Nothing, Me.I, False,
    28. "Astronomie, Hier findest du Informationen über Sonnensysteme und Sterne")
    29. Do While Sprachausgabe.Gestartet
    30. Application.DoEvents()
    31. Loop
    32. End If
    33. If .Name = "TS_Menue_EMail" Then
    34. Me.Bearbeitung_TS_DDButton(Me.TS_DDButton, MenueItem, Nothing, Me.I, True,
    35. "Email")
    36. Do While Sprachausgabe.Gestartet
    37. Application.DoEvents()
    38. Loop
    39. For Each MenueSubItem As ToolStripMenuItem In MenueItem.DropDownItems.OfType(Of ToolStripMenuItem)()
    40. If MenueSubItem.Name = "TS_Menue_EMail_Center" Then
    41. Me.Bearbeitung_TS_DDButton(Me.TS_DDButton, MenueItem, MenueSubItem, Me.I, False,
    42. "Im mailcenter findest Du gesendete und empfange mails")
    43. Do While Sprachausgabe.Gestartet
    44. Application.DoEvents()
    45. Loop
    46. End If
    47. Next
    48. End If
    49. End With
    50. Next
    51. End If
    52. Me.Beenden()
    53. End Sub
    Gruß Markus
    @Westerwälder Wie funktioniert denn die Sprachausgabe?
    Wenn diese selbst bei Beendigung ein Event senden würde, wäre Dein Problem gelöst.
    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!

    Westerwälder schrieb:

    Sprachausgabe.isworking
    wäre nach meinem Verständnis eine Property, die Du pollen müsstest. Ein Event sehe ich da nicht.
    Wenn Du dies in einer Timer-Tick-Routine machtest mit sagen wir 100 Millisekunden Timer-Intervall solte das doch auch besser ablaufen.
    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!
    Arbeite mit einem Timer

    VB.NET-Quellcode

    1. Private Sub Timer_Pruefung_Tick(sender As Object, e As EventArgs) Handles Timer_Pruefung.Tick
    2. If Sprachausgabe.Gestartet = False Then Exit Sub
    3. If Not Me.AnimationisRuning Then Me.Animation_Starten()
    4. If Sprachausgabe.IsWorking = False Then
    5. Me.Timer_Pruefung.Enabled = False
    6. Sprachausgabe.Gestartet = False
    7. End If
    8. End Sub


    Die Computerstimme soll den Text komplett ansagen.
    Solange soll sich die Maus- und Formposition nicht ändern.
    Ist die Ansage fertig, wird das nächste Element im Toolstrip aufgerufen.

    Klar, ich könnte für jedes Element eine eigene Sub machen, aber
    erstens viel Aufwand und
    zweitens ein Rumgebastel wenn irgendwas noch dazu bzw. im Toolstrip wieder entfernt wird.
    Gruß Markus

    Westerwälder schrieb:

    VB.NET-Quellcode

    1. Do While Sprachausgabe.Gestartet
    2. Application.DoEvents()
    3. Loop
    Nö.
    Du machst einen riesigen Misch-Masch-Kauderwelsch. ;(
    Du solltest Deinen Ablauf mal völlig neu durchdenken und das ganze ggf. in eine separate Klasse auslagern, die könnte dann bei Bedarf ein Event senden.
    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!

    Westerwälder schrieb:

    in der Sub
    überhaupt nicht.

    Verinnerliche folgendes Prinzip:
    Du bestellst eine Pizza.
    Du hast zwei Möglichkeiten:
    • Du saust alle 60 Sekunden zur Tür und siehst nach, ob der Pizzabote davor steht.
    • Du siehst Dir einen Film an und wartest auf das Klingeln des Pizzaboten.

    Genau so musst Du es in Deinem Programm machen.
    Wenn das Ende der Sprachausgabe den Start von xyz auslösen soll, musst Du in das Sprachausgabe-Ende-Event xyz starten.
    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!
    @Westerwälder Beschreibe mal mit Worten (ohne Code), wie Dein Ablauf ablaufen soll.
    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 etwa 25 Formen in meinem Projekt.
    Für jede Form soll ein Hilfsprogramm zur Verfügung stehen.

    User clickt irgendwo den Hilfebutton. Über den Modus weis das Hilfeprogramm, um welche Form es sich handelt.

    Erstelle mir nun eine Klasse mit den benötiogen Information,
    - Sprachtext
    - Labelbezeichung
    - Buttonbezeichnung
    usw.

    Von dieser Klasse erstelle ich mir eine List of
    Nun durchlaufe ich alle Elemente im Toolstrip und füge sie der List of bei

    Ist dies erfolgt, starte ich den Timer und hole mir den ersten Index aus der List of
    nun erfolgt Maus- und Formpositionierung sowie Sprachausgabe

    Meldet nun Sprachausgabe.IsWorking = false
    bearbeite ich den nächsten Eintrag der List of
    Gruß Markus

    Westerwälder schrieb:

    Sprachausgabe
    Was wird da akustisch ausgegeben?
    Warum willst / musst Du warten, bis das zu Ende ist?
    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!