如何安全停止一个API被阻塞的子线程?(300分)

  • 主题发起人 主题发起人 章慧
  • 开始时间 开始时间

章慧

Unregistered / Unconfirmed
GUEST, unregistred user!
我想提供一个方法将我放在文件包中的wav直接播放。
异步比较简单,在实现同步播放时,因我不知wav长短,就采用如下方法:
1。创建播放线程
2。在线程内申请内存
3。将压缩的wav抄到内存
4。使用同步的sndPlaySound播放
5。释放内存
6。向主线程发送消息通知其已结束
这样实现是初步实现了,结果就出现了问题。
在播放线程工作中,如何将其停止?
就像那些RPG游戏里人物说的话被玩家按掉那样?
望大虾不吝赐教!
 
呵呵,这个比较难,不过我正好常做。
一般设一个BOOL,
在线程函数中,
void SomeThreadProc(void *pParam){
while(BOOL){
}
_endthreadex(0);
}
当有事件时将BOOL设成0即可。
有三点要注意:
1:BOOL必须volatile类型的,这样才可以被外部改变。
2:不能用sndPlaySound,用Waveout*等函数。
3:线程函数中尽量少用InitializeCriticalSection等临界区函数。
 
waveout怎么用?大虾可否给个范例?
我现在的线程比较简单,或者能否请您帮忙改一改?
Unit PlaySounds;
Interface
Uses
Windows, Messages, SysUtils, Classes, Controls,
MMSystem;
Type
TPlaySoundThread = Class(TThread)
Private
Procedure NoticeIt;
Published
Procedure Execute;
Override;
Public
FFilename: String;
FHandle: hWnd;
FMsg: Cardinal;
Constructor Create(Filename:String;Handle:hWnd;Msg:Cardinal);
end;
Implementation
Constructor TPlaySoundThread.Create(Filename:String;Handle:hWnd;Msg:Cardinal);
begin
FFilename:=Filename;
FHandle:=Handle;
FMsg:=Msg;
FreeOnTerminate:=True;
Inherited Create(False);
end;

Procedure TPlaySoundThread.Execute;
Var
p,q:PChar;
z:TFilestream;
i,j,k,l,m:integer;
begin
z:=TFileStream.Create(FFilename,fmOpenRead);
i:=z.Size;
p:=AllocMem(i);
q:=p;
j:=i mod 8192;
k:=i div 8192;
for l:=1 to kdo
begin
if l=k then
m:=j else
m:=8192;
z.ReadBuffer(p^,m);
p:=p+m;
end;
z.Free;
sndPlaySound(q,SND_SYNC Or snd_Memory Or Snd_NOSTOP);
//PlaySound(q,0,SND_SYNC Or snd_Memory Or SND_PURGE);
freemem(q,i);
Synchronize(NoticeIt);
end;

Procedure TPlaySoundThread.NoticeIt;
begin
SendMessage(FHandle,FMsg,0,0);
end;

end.
 
WaveOutWrite放把,这样效果更好,同时能控制更多。只是编码麻烦点
 
咋放?大虾给个例子吧
 
后退
顶部