いつも勉強させてもらってます。
早速ですがdelphi2010のリソースマネージャーにWAVファイルを登録し音を出そうとしてるのですがうまくいきません。どなたかおわかりの方、よろしくお願いします。
直接ファイルを指定すると正常に音が出ます。
procedure TForm1.Button2Click(Sender: TObject);
begin
PlaySound(PChar('Test.wav'),0,SND_FILENAME or SND_ASYNC);
ファイルから時はOK
PlaySound('Resource_2',HInstance, SND_RESOURCE or SND_ASYNC);
リソースから時NG
end;
これはIDEのバグが原因といっても良いと思います。
PlaySoundはリソースタイプがWAVEやSOUNDとなっているリソース「のみ」を再生できるのですが、
リソースマネージャでは画像系のリソース以外はすべて「RCData」というタイプにされてしまいます。
上述の通り、PlaySoundはRCDataの中など探しませんので、結果として再生できません。
この問題を解決するには4つの方法があります。
1.IDEのアップデートを待つ
この問題はすでにQC79935としてバグ報告されています。
しかしながら何故か却下されているため、アップデートはあまり期待できません。
2.リソースを手動で生成する
手動でリソーススクリプトを書き、コンパイルすればコードを修正することなく問題を解決できます。
もちろんリソースマネージャの恩恵は放棄することになります。
3.dprojファイルを書き換える
リソースマネージャのリソースタイプは書き換えが可能なので、一見ここで指定すれば問題解決のように思えます。
しかしすでに定義されているタイプ(Bitmapなど)以外は指定できません。
これを回避するにはdprojを直接編集してリソースタイプをSOUNDもしくはWAVEにします。
しかしマネージャ上でリソース識別子の変更等をすると、不用意に元に戻ってしまう場合があります。
4.コードを書き換える
これが一番現実的な解決方法だと思います。
var rs: TResourceStream;
begin
rs := TResourceStream.Create(HInstance, 'Resource_2', 'RCData');
PlaySound(rs.Memory, 0, SND_MEMORY or SND_ASYNC);
rs.Free;
end;
とメモリ上からの再生にすることで解決できます。
SND_ASYNCを指定しておきながら直後にFreeしてしまうのは危険に思えますが、
この場合のrs.Memoryはメモリ上にロードされたEXEファイルの中を指すポインタですので問題ありません。
LockResource APIなどでも代用できます。
jazzinさん、丁寧な解説でとてもわかりやすかったです。
とりあえず、アップデートで対応されるのを期待しつつ、
4.コードを書き換える
で処理しようと考えております。
適切な解説、本当にありがとうございました。
解決わすれでした。
ツイート | ![]() |