サンプル「サウンドの再生状態を取得する」のまちがえを発見しました

タグの編集
投稿者 トマト  (小学生) 投稿日時 2009/6/28 03:05:01
Visual Basic.NET サンプル集にあるサウンドの再生状態を取得するのサンプルが正しく動きませんでした。

(修正前)
'■再生状態("not ready", "paused", "playing", "stopped", ""のどれか) 
Private Sub Button3_Click(ByVal sender As System.ObjectByVal e As System.EventArgs) Handles Button3.Click

    Dim Buffer As String = New String(" "c, 255)
    Dim Mode As String

    Call mciSendString("status MySound mode", Buffer, Len(Buffer), 0)

    Mode = Replace(Buffer, Chr(0), "")

    MsgBox(Mode)

End Sub

(修正後)
Private Sub Button3_Click(ByVal sender As System.ObjectByVal e As System.EventArgs) Handles Button3.Click

    Dim Buffer As String = New String(" "c, 255)
    Dim Mode As String

    Call mciSendString("status MySound mode", Buffer, Len(Buffer), 0)

    Mode = Replace(Buffer, " """)

    MsgBox(Mode)

End Sub

こんな感じにしないと、メッセージボックスいっぱいまで表示されてしまいます。
投稿者 るきお(管理者)  (社会人) 投稿日時 2009/6/29 02:14:53
こんにちは。ご指摘ありがとうございます。

ご指摘の通りで、このサンプルでは末尾の空白を削除しないと取得したメッセージ・情報に大量の空白が付加された状態になってしまいます。
Replace(Buffer, Chr(0), "")でこのような末尾の空白が削除されることを意図していたのですが、実際はそうではありませんでした。(おそらく私のテスト漏れです。)

そこで、次のように修正しました。
    
'■再生状態("not ready", "paused", "playing", "stopped", ""のどれか) 
Private Sub Button3_Click(ByVal sender As System.ObjectByVal e As System.EventArgs) Handles Button3.Click

    Dim Buffer As String = New String(Chr(0), 255)
    Dim Mode As String

    Call mciSendString("status MySound mode", Buffer, Len(Buffer), 0)

    Mode = Replace(Buffer, Chr(0), "")

    MsgBox(Mode)

End Sub


トマトさんご提案の修正方法とは少し違いますが、これで末尾の無駄な空白等はすべて削除されます。

実は、mciSendString関数はBufferに情報を渡すときに情報の最後に文字コードが0の文字(つまり、Null)をつけて、文字列終了の目印にします。ですので、Mode = Replace(Buffer, " ", "")とした場合、大量の空白を除去するのには効果がありますが、この文字コードがが0の文字は残ってしまいます。
文字コードが0の文字は特殊な文字のためこれではVB内での扱いがやっかいになります。
たとえば、次のコードではメッセージの最後に"ABCDEFG"が表示されません。
    
Private Sub Button3_Click(ByVal sender As System.ObjectByVal e As System.EventArgs) Handles Button3.Click

    Dim Buffer As String = New String(" "c, 255)
    Dim Mode As String

    Call mciSendString("status MySound mode", Buffer, Len(Buffer), 0)

    Mode = Replace(Buffer, " """)

    'ここで「ABCDEFG」が表示されない。 
    MsgBox(Mode & "ABCDEFG")

End Sub


つまり、除去すべきなのは空白(" ")と、文字コードが0の文字の2つとなり、どちらか片方だけでは不完全になってしまいます。
ですでの、今回のような修正を行いました。

今後もよろしくお願いします。
投稿者 トマト  (小学生) 投稿日時 2009/6/30 02:51:10
ありがとうございます。

いくらやっても If PlayState="playing" で引っかからないなと思ったらそういうことだったのですね。

これからも初心者ながらがんばっていきます。