皆様よろしくお願いします。winXP Delphi6 Personalです。
いま、音楽ファイルをListboxにフルパスでセットし順番に再生する
プログラムを作成していますが、曲が終わって次の曲にチェンジするのに
WindowsMediaPlayer1PlayStateChangeの終了イベントを使用しているため
ループで待たせています。
途中で画面右上の終了×ボタンで終了すると「Access violation at addressエラー」
がでます。いろいろやってみましたが解決できません。
関係すると思われる部分のコードを少し長くなりますが書いてみます。
Pagecontrolに動的にWindowsMediaPlayer1を貼り付けて終わったら破棄します。
FormにListboxとPagecontrolを貼り付けています。
とんでもないことをやっているから怒られるのですがよろしくお願いします。
type
TTabSheetEx = class(TTabSheet)
public
WindowsMediaPlayer1: TWindowsMediaPlayer;
destructor Destroy; override;
end;
TForm1 = class(TForm)
・・・
var
PlayListNo:integer; //現在再生中のプレイリスト番号
PlayMode:Boolean;//再生中のファイルが終了したイベント受け取り
MovieStopFlag:Boolean; //プレイの終了命令
・・・・
destructor TTabSheetEx.Destroy; // TabsheetExの破棄同時にブラウザの破棄
begin
WindowsMediaPlayer1.Free;
inherited;
end;
・・・・
//動的にタブを作成しWindowsMediaPlayer1を貼り付ける
function TForm1.TabSheetCreate(Category,Title:string):Boolean;
var
TabSheetEx: TTabSheetEx;
begin
Tmode:=Category;
TabSheetEx := TTabSheetEx.Create(Form1.PageControl1);
TabSheetEx.Parent := Form1.PageControl1;
TabSheetEx.PageControl := Form1.PageControl1;
TabSheetEx.Caption:=Title;
Form1.PageControl1.ActivePage := TTabSheet(TabSheetEx);
with (PageControl1.ActivePage as TTabSheetEx) do
begin
WindowsMediaPlayer1:= TWindowsMediaPlayer.Create(self);
WindowsMediaPlayer1.Align:=alClient;
WindowsMediaPlayer1.Parent:=self;
WindowsMediaPlayer1.OnPlayStateChange
:= Form1.WindowsMediaPlayer1PlayStateChange;
end;
result:=true;
end;
//Listboxのアイテムをダブルクリックして開始する
procedure TForm1.ListBox1DblClick(Sender: TObject);
begin
PlayListNo:=ListBox1.ItemIndex;
if TabSheetCreate(tMOVI,'マルチプレイヤー')=false then exit;
MoviePlay
end;
//再生終了のイベント発生したらカウントアップし、falseにしてループを抜ける
procedure TForm1.WindowsMediaPlayer1PlayStateChange(Sender: TObject; NewState: Integer);
begin
if (NewState = wmppsMediaEnded) then
begin Inc(PlayListNo);PlayMode:=false;end;
end;
//プレイヤー。途中でループして曲が終わるのを待つ、曲が無くなるまで繰り返す
procedure TForm1.MoviePlay;
begin
MovieStopFlag:=false;
while (PlayListNo < ListBox1.Items.Count) do//曲が最後になるまで
begin
with (PageControl1.ActivePage as TTabSheetEx) do
begin
WindowsMediaPlayer1.controls.stop;
WindowsMediaPlayer1.currentPlaylist.clear;
WindowsMediaPlayer1.URL:=ListBox1.Items.Strings[PlayListNo];
WindowsMediaPlayer1.controls.play;
end;
PlayMode:=true;
//--------------------曲が終わってMediaEndedイベントでループを抜ける
while PlayMode do
begin
if MovieStopFlag=true then exit;
Application.ProcessMessages;
Sleep(20);
end;
if MovieStopFlag=true then break;
end;
PlayMode:=false;
MovieStopFlag:=true;
end;
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
var i:integer;
begin
MaltiMediaPlay:=true;//一応強制終了したつもり
PlayMode:=false;
for i:=PageControl1.PageCount-1 downto 0 do//タブの削除
TTabSheetEx(Form1.PageControl1.Pages[i]).Free;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
PageControl1.Free;//破棄する
end;
> MaltiMediaPlay:=true;//一応強制終了したつもり
終了してないんでないの?
タブを削除する前に
WindowsMediaPlayer1.Free;
がいるのでは?
あと、ループで待つのではなくて、
WindowsMediaPlayer1PlayStateChange
で次の曲に進むようにしたほうがいいような・・・。
トレース実行やステップ実行を利用すればどこでエラーになるかが分かるかと思います。
WindowsMediaPlayerをFreeするときにPlayModeをFalseにしていますよね。
このときMoviePlayのループは回っている状態です。
で、PlayModeはFalseなので二重ループのうちの内側からは抜けます。
でも外側のループは抜けません。
その結果FreeしたWindowsMediaPlayerをstopさせようとするでエラーが起きます。
皆さん有り難うございます。
ループを抜ける方法を考えてみます。
有り難うございました。
ツイート | ![]() |