ページ 11

音楽再生

Posted: 2006年7月05日(水) 18:31
by C1000
次のコードで音楽を再生することはできるのですが停止ができません。どこに問題があるのでしょうか?

Re: 音楽再生

Posted: 2006年7月06日(木) 04:17
by NoWest

Posted: 2006年7月06日(木) 19:03
by C1000
> NoWestさん
試してみましたが停止できません。
また、最初のコードでのエラー情報では、「指定されたコマンドを自動的に開かれたデバイスで実行することはできません。」となっています。

原因

Posted: 2006年7月08日(土) 13:25
by C1000
別スレッドでの実行でなくそのまま呼び出したら、うまく動きました。ですが、別スレッドで実行したいので、別スレッドでの実行はどのようすれば良いのでしょうか?

Re: 原因

Posted: 2006年7月08日(土) 21:41
by NoWest
> 別スレッドでの実行でなくそのまま呼び出したら、うまく動きました。ですが、別スレッドで実行したいので、別スレッドでの実行はどのようすれば良いのでしょうか?
ほぉ、あなたもこの妙なWindowsの仕様にはまっていましたか。

実は9X系のWindowsではあるスレッドで開かれたMCIデバイスを別のスレッドから操作可能なのですが、NT系のWindowsの場合、あるスレッドで開かれたMCIデバイスを別のスレッドから操作することはできない仕様になっています。

ですから、この問題を回避するためにはMCIデバイスを予め使いたいスレッド上で開く必要があります。

要するに、例えばMCI_STATUSなんぞで現在の再生位置リアルタイムに取得するスレッドを作成した場合、そのスレッドで内でMCIデバイスを開いておく必要があります。

Posted: 2006年7月09日(日) 14:00
by C1000
デバイスは使いたいスレッドで開いてあるので問題はないのですが、停止のときに同じスレッドで停止用関数を呼び出す方法がわかりません。教えていただけないでしょうか。

Posted: 2006年7月09日(日) 19:26
by NoWest
> デバイスは使いたいスレッドで開いてあるので問題はないのですが、停止のときに同じスレッドで停止用関数を呼び出す方法がわかりません。教えていただけないでしょうか。
色々な実装法があると思いますが、
私の場合は、スレッドの別を考えなくてもよいスレッドセーフなmciSendCommandを作って使っています。

よかったら使ってください。 ~使い方~
グローバル領域にでも

コード: 全て選択

Dim mci As MciSafetySendCommand
として

コード: 全て選択

Dim mop As MCI_OPEN_PARMS
mop.dwCallback=hMainWnd As DWord
mop.lpstrElementName="sound1.wav"
mci.SendCommand(0,MCI_OPEN,MCI_OPEN_ELEMENT,mop)
ってな感じで普段通りのmciSendCommandとして使えます。

仕組みは簡単で全てのMCIコマンドが同一スレッド上で実行されるようにカプセル化しているだけです。

Posted: 2006年7月09日(日) 20:14
by C1000
mciSendCommandをmci.SendCommmandに変えたところエラーはでなくなりましたが、今度は再生ができません。ボタンを押しても音がでずMciNotifyイベントが起こりません。

Posted: 2006年7月09日(日) 21:19
by NoWest
まず、最初にソースに記述ミスがあったことを謝ります。

SendCommmand → SendCommandと直してください。

あと、ついでにSendCommandで戻り値を取得できるように改良しました。
> mciSendCommandをmci.SendCommmandに変えたところエラーはでなくなりましたが、今度は再生ができません。ボタンを押しても音がでずMciNotifyイベントが起こりません。
MciNotifyイベントを発生するにはMCIコマンドにMCI_NOTIFYが追加されていなければなりませんよ。

コード: 全て選択

Dim mpp As MCI_PLAY_PARMS
mpp.dwCallback=hMainWnd
mci.SendCommand(mop.dwDeviceID,MCI_PLAY,MCI_NOTIFY,mpp)

Posted: 2006年7月10日(月) 19:48
by C1000
できました。ちなみに再生されない原因はただIDの指定を忘れただけでした。NoWestさんありがとうございました。