|
分類:[VB.NET/VB2005 以降]
Visual Studio 2019 CommunityのVBで開発しています。
作成しているプログラムの内容としては、
カウントダウンタイマーで、タイマー終了後に音再生とラベルのフラッシュを行わせています。
また、タイマーは複数押下する場合もあるので終了時に別々の音が再生されるようには出来たと思いますが
終了時に片方の終了ボタンを押すとどちらも停止してしまいます。
終了時にPlaySound(IntPtr.Zero, IntPtr.Zero, PlaySoundFlags.SND_PURGE)としていることから
開始されたものを指定できていないためPlaySound全体が停止してしまうということは理解していますが
これを別々で停止する方法などはないでしょうか?
また、自分では同時再生で別々の音が流れていると思っていますが間違っていましたら
その辺についてもご指摘頂ければありがたいです。
ソースコードは以下の通りです。
-----
Imports System.Threading.Tasks
Public Class Form1
' サウンドを再生するWin32 APIの宣言
Public Enum PlaySoundFlags
SND_SYNC = &H0
SND_ASYNC = &H1
SND_NODEFAULT = &H2
SND_MEMORY = &H4
SND_LOOP = &H8
SND_NOSTOP = &H10
SND_NOWAIT = &H2000
SND_ALIAS = &H10000
SND_ALIAS_ID = &H110000
SND_FILENAME = &H20000
SND_RESOURCE = &H40004
SND_PURGE = &H40
SND_APPLICATION = &H80
End Enum
<Runtime.InteropServices.DllImport("winmm.dll", CharSet:=Runtime.InteropServices.CharSet.Auto)>
Private Shared Function PlaySound(ByVal pszSound As IntPtr, ByVal hmod As IntPtr, ByVal fdwSound As PlaySoundFlags) As Boolean
End Function
Private pH_gcHandle As Runtime.InteropServices.GCHandle
Private NH3_A_gcHandle As Runtime.InteropServices.GCHandle
Private pH_waveBuffer As Byte() = Nothing
Private NH3_A_waveBuffer As Byte() = Nothing
' # カウントダウンタイマー変数
Private pH_dTime As Date ' 水素イオン指数
Private NH3_A_dTime As Date ' アンモニア
' # サウンドリソース変数
Private pH_wav As IO.Stream = My.Resources.pH
Private NH3_A_wav As IO.Stream = My.Resources.NH3_A
' # カウントダウン終了フラッシュ変数
Private pH_Flash_Result As Boolean ' 水素イオン指数
Private NH3_A_Flash_Result As Boolean ' アンモニア
' # WAVEファイルを再生、停止
' 水素イオン指数
Private Sub pH_PlaySound()
If Not pH_waveBuffer Is Nothing Then
pH_StopSound()
End If
' byte配列にする
pH_waveBuffer = New Byte(pH_wav.Length) {}
pH_wav.Read(pH_waveBuffer, 0, pH_waveBuffer.Length)
' GCによって移動されないようにする
pH_gcHandle = Runtime.InteropServices.GCHandle.Alloc(pH_waveBuffer, Runtime.InteropServices.GCHandleType.Pinned)
' 非同期再生
PlaySound(pH_gcHandle.AddrOfPinnedObject(), IntPtr.Zero, PlaySoundFlags.SND_MEMORY Or PlaySoundFlags.SND_LOOP Or PlaySoundFlags.SND_ASYNC)
End Sub
Private Sub pH_StopSound()
If pH_waveBuffer Is Nothing Then
Return
End If
' 再生しているWAVEを停止する
PlaySound(IntPtr.Zero, IntPtr.Zero, PlaySoundFlags.SND_PURGE)
' 解放する
pH_gcHandle.Free()
pH_waveBuffer = Nothing
End Sub
' アンモニア
Private Sub NH3_A_PlaySound()
If Not NH3_A_waveBuffer Is Nothing Then
NH3_A_StopSound()
End If
' byte配列にする
NH3_A_waveBuffer = New Byte(NH3_A_wav.Length) {}
NH3_A_wav.Read(NH3_A_waveBuffer, 0, NH3_A_waveBuffer.Length)
' GCによって移動されないようにする
NH3_A_gcHandle = Runtime.InteropServices.GCHandle.Alloc(NH3_A_waveBuffer, Runtime.InteropServices.GCHandleType.Pinned)
' 非同期再生
PlaySound(NH3_A_gcHandle.AddrOfPinnedObject(), IntPtr.Zero, PlaySoundFlags.SND_MEMORY Or PlaySoundFlags.SND_LOOP Or PlaySoundFlags.SND_ASYNC)
End Sub
Private Sub NH3_A_StopSound()
If NH3_A_waveBuffer Is Nothing Then
Return
End If
' 再生しているWAVEを停止する
PlaySound(IntPtr.Zero, IntPtr.Zero, PlaySoundFlags.SND_PURGE)
' 解放する
NH3_A_gcHandle.Free()
NH3_A_waveBuffer = Nothing
End Sub
' # ラベル点滅
' pH
Private Async Sub pH_Flash(ByVal ObjLabel As Object)
While pH_Flash_Result
Await Task.Delay(100)
ObjLabel.Visible = Not ObjLabel.Visible
End While
ObjLabel.Visible = True
End Sub
Private Async Sub NH3_A_Flash(ByVal ObjLabel As Object)
While NH3_A_Flash_Result
Await Task.Delay(100)
ObjLabel.Visible = Not ObjLabel.Visible
End While
ObjLabel.Visible = True
End Sub
' pH (水素イオン指数)
Private Sub pH_Btn_Click(sender As Object, e As EventArgs) Handles pH_Btn.Click
pH_dTime = pH.Text
If pH_Btn.Text = "開始" Then
pH_Timer.Enabled = True
pH_Btn.Text = "終了"
ElseIf pH_Btn.Text = "終了" Then
pH_StopSound()
pH_Flash_Result = False
pH.BackColor = DefaultBackColor
End If
End Sub
Private Sub pH_Timer_Tick(sender As Object, e As EventArgs) Handles pH_Timer.Tick
pH_dTime = pH_dTime.AddSeconds(-1)
pH.Text = pH_dTime
If pH_dTime = "0:0:0" Then
pH_Timer.Enabled = False
pH_PlaySound()
pH.BackColor = Color.Red
pH_Flash_Result = True
pH_Flash(pH)
Else
pH.BackColor = Color.Yellow
End If
End Sub
' NH3 (アンモニア)
Private Sub NH3_Btn_Click(sender As Object, e As EventArgs) Handles NH3_A_Btn.Click
NH3_A_dTime = NH3_A.Text
If NH3_A_Btn.Text = "開始" Then
NH3_A_Timer.Enabled = True
NH3_A_Btn.Text = "終了"
ElseIf NH3_A_Btn.Text = "終了" Then
NH3_A_StopSound()
NH3_A_Flash_Result = False
NH3_A.BackColor = DefaultBackColor
End If
End Sub
Private Sub NH3_A_Timer_Tick(sender As Object, e As EventArgs) Handles NH3_A_Timer.Tick
NH3_A_dTime = NH3_A_dTime.AddSeconds(-1)
NH3_A.Text = NH3_A_dTime
If NH3_A_dTime = "0:0:0" Then
NH3_A_Timer.Enabled = False
NH3_A_PlaySound()
NH3_A.BackColor = Color.Red
NH3_A_Flash_Result = True
NH3_A_Flash(NH3_A)
Else
NH3_A.BackColor = Color.Yellow
End If
End Sub
End Class
-----
以上、宜しくお願い致します。
|