怪事了,见鬼了。单步调试成功,运行却出错!!!

数值 2011-04-12 10:07:38
我编了个背单词的小软件,在真人发音上面遇见个怪问题:以下是发音模块:
Option Explicit

'【播放声音的类 名称:clsSound】
' -=-=-=- 属性 -=-=-=-
' WordName 指明当前单词的名字
' Volume 音量
' -=-=-=- 方法 -=-=-=-=-
' PlayWord <WordName,n> 打开请求的文件 (单词,引擎)引擎:1--Wav、Mp3 文件;2--微软语音;3--Wav 文件、Mp3 文件+微软语音
'-------------------------------------------------------------
Private Declare Function mciSendString Lib "winmm.dll" Alias "mciSendStringA" (ByVal lpstrCommand As String, ByVal lpstrReturnString As String, ByVal uReturnLength As Long, ByVal hwndCallback As Long) As Long
Private sAlias As String

Private sWordName As String '单词名
Private intVolume As Integer '音量

Private Function OutFileName(ByVal nWordName As String) As String '单词转换成路径
Dim S As String
Dim sPathName As String, nPathName As String

On Error GoTo Err_FileName

S = Left(nWordName, 1)
sPathName = IIf(Right$(App.Path, 1) = "\", App.Path, App.Path & "\") & "Voice\" & S & "\" & nWordName

If Dir$(sPathName & ".wav") <> "" Then
nPathName = sPathName & ".wav"
ElseIf Dir$(sPathName & ".Mp3") <> "" Then
nPathName = sPathName & ".Mp3"
Else
nPathName = ""
End If
OutFileName = nPathName
Exit Function
Err_FileName:
OutFileName = ""
End Function

Public Sub PlayWord(ByVal sTheFile As String, ByVal N As Integer) ' PlayWord <WordName,n> 请求的单词文件(单词,引擎)

Dim sFilePath As String '单词文件路径名

sFilePath = OutFileName(sTheFile)

Select Case N ':1--Wav、Mp3 文件;2--微软语音;3--Wav 文件、Mp3 文件+微软语音
Case 1
If sFilePath <> "" Then
Call mmPlay(sFilePath)
End If
Case 2
Call MySpeak(sTheFile)
Case 3
If sFilePath <> "" Then
Call mmPlay(sFilePath)
Else
Call MySpeak(sTheFile)
End If
End Select

End Sub

Private Sub mmPlay(ByVal sTheFile As String) ' mmPlay <WordName> 打开请求的单词文件
Dim nReturn As Long
Dim V As Long

' On Error GoTo Err_Play
If sAlias <> "" Then '
nReturn = mciSendString("Close " & sAlias, vbNullString, 0, 0)
End If
sWordName = sTheFile '指明当前单词的名字

sAlias = Right$(sTheFile, 3) & Minute(Now)
V = intVolume * 10
nReturn = mciSendString("Open " & Chr(34) & sTheFile & Chr(34) & " Alias " & sAlias, vbNullString, 0, 0) ' 打开请求的单词文件
nReturn = mciSendString("Setaudio " & sAlias & " volume to " & V, vbNullString, 0, 0) 'V是设置的音量值volume to factor
nReturn = mciSendString("Play " & sAlias, vbNullString, 0, 0) '播放当前的文件
nReturn = mciSendString("Close " & sAlias, vbNullString, 0, 0) '关闭声音文件
sAlias = ""
sWordName = ""
End Sub
'===============================================================================
'-函数名称: MySpeak
'-功能描述: 朗读文本内容
'-输入参数说明: 参数1: 必选 strSpeak As String 朗读的文本内容
' 参数2: 可选 IntRate As Integer 设置朗读的速度 范围:-10到+10
' 参数3: 可选 intVolume As Integer 设置朗读的音量 范围:0到100
' 参数4: 可选 intVoiceID As Integer 朗读者ID
'-使用语法示例: Call MySpeak ("中华人民共和国")
'-使用注意: 需要引用 Microsoft Speech Object Library
'===============================================================================
Private Function MySpeak(strSpeak As String) As Boolean
On Error GoTo Err_MySpeak
Dim oVoise As New SpeechLib.SpVoice
Dim intTotalSpeech As Integer

intTotalSpeech = oVoise.GetVoices.Count '获取朗读者的数量

If intTotalSpeech = 0 Then Exit Function

'设置朗读音量
If intVolume > 100 Then intVolume = 100
If intVolume < 0 Then intVolume = 0
oVoise.Volume = intVolume

oVoise.Speak strSpeak

MySpeak = True

Exit_MySpeak:
Exit Function

Err_MySpeak:
MySpeak = False
MsgBox Err.Description, 64, "提示"
Resume Exit_MySpeak
End Function


Property Get WordName() As String ' 指明当前单词的名字
WordName = sWordName
End Property

Property Let WordName(ByVal sTheFile As String)
mmOpen sTheFile
End Property

Public Property Let Volume(bintVolume As Integer)
intVolume = bintVolume
End Property


以下是调用:

Private Sub Timer2_Timer() '单词出现的状态 0-直接显示,1-上下滑动,2-左右滑动,3-测试状态

Dim mmDll As New clsSound '此句放在过程内、外一样
'..........................此处省略。。。。。。。。
mmDll.Volume = ScrollVolume
mmDll.PlayWord m_sMatterWord(id).s_English, i_Speech '单词,引擎
Set mmDll = Nothing '此句放在过程内、外一样。省略不省略一样
End Sub



发音类模块是在ActiveX dll 内,调用是在一程序内,两个同时在一工程组内,运行时真人发音不发音,
mciSendString 函数的返回值用不同变量输出显示也都正常(都是0),就是不发音,怪事了,单步调试 mmPlay 过程时,真人发音却完全正常!!!

请问:这是怎么回事?如何解决?
...全文
150 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2011-04-13
  • 打赏
  • 举报
回复
使用SAPI
clear_zero 2011-04-13
  • 打赏
  • 举报
回复
如果你的东西不难,那么把close放在前面也挺好的

数值 2011-04-13
  • 打赏
  • 举报
回复
to clear_zero:
果然如你说的那样,是Play还没完就Close了,加入你的那个延时的循环,时间竟然还是太短,最后在循环内加入一句:Debug.Print nReturn ,问题得到解决。
可我总觉得这样不妥,播放代码内总不能放个耗时、耗资的循环吧?
我于是把Close代码移到Open的前面,变成如下样式:

Private Sub mmPlay(ByVal sTheFile As String) ' mmPlay <WordName> 打开请求的单词文件
Dim nReturn As Long
Dim V As Long

sWordName = sTheFile '指明当前单词的名字
nReturn = mciSendString("Close " & sAlias, vbNullString, 0, 0) '关闭声音文件

sAlias = Right$(sTheFile, 3) & Minute(Now)
V = intVolume * 10
nReturn = mciSendString("Open " & Chr(34) & sTheFile & Chr(34) & " Alias " & sAlias, vbNullString, 0, 0) ' 打开请求的单词文件
nReturn = mciSendString("Setaudio " & sAlias & " volume to " & V, vbNullString, 0, 0) 'V是设置的音量值volume to factor
nReturn = mciSendString("Play " & sAlias, vbNullString, 0, 0) '播放当前的文件
sWordName = ""
End Sub


竟然也能正常播放,但总觉得代码不够严谨,不知如何改正?



to jiashie

时序、异步? 貌似您有更好的解决办法,请指教!!!

jiashie 2011-04-13
  • 打赏
  • 举报
回复
时序、异步
clear_zero 2011-04-12
  • 打赏
  • 举报
回复
Private Sub mmPlay(ByVal sTheFile As String) ' mmPlay <WordName> 打开请求的单词文件
Dim nReturn As Long
Dim V As Long

' On Error GoTo Err_Play
If sAlias <> "" Then '
nReturn = mciSendString("Close " & sAlias, vbNullString, 0, 0)
End If
sWordName = sTheFile '指明当前单词的名字

sAlias = Right$(sTheFile, 3) & Minute(Now)
V = intVolume * 10
nReturn = mciSendString("Open " & Chr(34) & sTheFile & Chr(34) & " Alias " & sAlias, vbNullString, 0, 0) ' 打开请求的单词文件
nReturn = mciSendString("Setaudio " & sAlias & " volume to " & V, vbNullString, 0, 0) 'V是设置的音量值volume to factor
nReturn = mciSendString("Play " & sAlias, vbNullString, 0, 0) '播放当前的文件
dim i as integer
for i=0 to 10000
doevents
next i
nReturn = mciSendString("Close " & sAlias, vbNullString, 0, 0) '关闭声音文件
sAlias = ""
sWordName = ""
End Sub

试试看 ,我觉得是你的play还没完呢就关闭了,可以看看怎么能够让play 正常进行
数值 2011-04-12
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 clear_zero 的回复:]
Private Sub Timer2_Timer() '单词出现的状态 0-直接显示,1-上下滑动,2-左右滑动,3-测试状态
timer2.enabled=false
Dim mmDll As New clsSound '此句放在过程内、外一样
'..........................此处省略。。。。。。。。
mmDll.Volume = ScrollVolum……
[/Quote]

谢谢~~~

试过了,但是你的办法还是:外甥打灯笼--照旧(舅)!!
clear_zero 2011-04-12
  • 打赏
  • 举报
回复
Private Sub Timer2_Timer() '单词出现的状态 0-直接显示,1-上下滑动,2-左右滑动,3-测试状态
timer2.enabled=false
Dim mmDll As New clsSound '此句放在过程内、外一样
'..........................此处省略。。。。。。。。
mmDll.Volume = ScrollVolume
mmDll.PlayWord m_sMatterWord(id).s_English, i_Speech '单词,引擎
Set mmDll = Nothing '此句放在过程内、外一样。省略不省略一样
timer2.enabled=true
End Sub


试试看吧

7,762

社区成员

发帖
与我相关
我的任务
社区描述
VB 基础类
社区管理员
  • VB基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧