📄 ch35.htm
字号:
</td>
</tr>
</table>
</center></div>
<p>That is the end of the Assisted TAPI support module. Save this module (<tt><font
FACE="Courier">VTAPI.BAS</font></tt>) and the project (<tt><font FACE="Courier">VPHONE.VBP</font></tt>)
before continuing. </p>
<h3><b><a NAME="TheCallBackModules">The <tt><font SIZE="4" FACE="Courier">CallBack</font></tt><font
SIZE="4"> Modules</font></a></b></h3>
<p>Since this project uses the SAPI Voice Command and Voice Text type libraries, you'll
need to add a class module to your project for each of the two libraries. These classes
were designed to allow high-level languages (like Visual Basic) to register services that
require the use of notification callbacks. The callback module for the TTS engine will not
be used in this project. However, you'll use the SR callback routines to trap and respond
to spoken commands. </p>
<div align="center"><center>
<table BORDERCOLOR="#000000" BORDER="1" WIDTH="80%">
<tr>
<td><b>Warning</b> </td>
</tr>
<tr>
<td><blockquote>
<p>The function names for these callbacks cannot be altered. The OLE libraries for SR and
TTS services are looking for these specific function names. If you use some other names,
the callbacks will not work and you will get an error report when you request TTS or SR
services.</p>
</blockquote>
</td>
</tr>
</table>
</center></div>
<p>First add the TTS callback functions. In this project, the functions will be empty, but
you'll need to register them anyway. Add a class module to your project (<tt><font
FACE="Courier">Insert | Class Module</font></tt>). Set the class name to <tt><font
FACE="Courier">TTSCallBack</font></tt>, set its <tt><font FACE="Courier">Instancing</font></tt>
property to <tt><font FACE="Courier">Creatable, MultiUse</font></tt>, and its <tt><font
FACE="Courier">Public</font></tt> property to <tt><font FACE="Courier">TRUE</font></tt>.
Now add the two functions from Listing 35.5 to the class. </p>
<hr>
<blockquote>
<b><p>Listing 35.5. Adding functions to the <tt><font FACE="Courier">TTSCallBack</font></tt>
class.<br>
</b></p>
</blockquote>
<blockquote>
<tt><font FACE="Courier"><p>Option Explicit<br>
<br>
Public Function SpeakingDone()<br>
'<br>
' this method will execute when the<br>
' TTS engine stops speaking text<br>
'<br>
End Function<br>
<br>
Public Function SpeakingStarted()<br>
'<br>
' this method will execute when the<br>
' TTS engine starts speaking text<br>
'<br>
End Function</font></tt> </p>
</blockquote>
<hr>
<p>When you've completed the functions, save the module as <tt><font FACE="Courier">TTSCBK.CLS</font></tt>.
</p>
<p>Now add a second class module to the project. Set its <tt><font FACE="Courier">Name</font></tt>
property to <tt><font FACE="Courier">SRCallBack</font></tt>, its <tt><font FACE="Courier">Instancing</font></tt>
property to <tt><font FACE="Courier">Createable, MultiUse</font></tt>, and its <tt><font
FACE="Courier">Public</font></tt> property to <tt><font FACE="Courier">TRUE</font></tt>.
Now add the code shown in Listing 35.6 to the class. </p>
<hr>
<blockquote>
<b><p>Listing 35.6. Adding functions to the <tt><font FACE="Courier">SRCallBack</font></tt>
class.<br>
</b></p>
</blockquote>
<blockquote>
<tt><font FACE="Courier"><p>Option Explicit<br>
<br>
Function CommandRecognize(szCommand As String, dwID As Long)<br>
'<br>
' fires off each time a command goes by <br>
'<br>
Dim cToken As String<br>
Dim cContent As String<br>
Dim iSpace As Integer<br>
Dim cReturn As String<br>
'<br>
szCommand = Trim(szCommand) & " "<br>
iSpace = InStr(szCommand, " ") <br>
cToken = UCase(Left(szCommand, iSpace - 1))<br>
cContent = Mid(szCommand, iSpace + 1, 255)<br>
'<br>
Select Case cToken<br>
Case "NEW" <br>
AddRec
'frmVPhone.cmdPhone_Click 0<br>
Case "EDIT" <br>
EditRec cContent<br>
Case "DELETE" <br>
DeleteRec cContent<br>
Case "PLACE" <br>
PlaceCall
frmVPhone.txtDial, ""<br>
Case "FIND" <br>
frmVPhone.txtDial
= LookUp(cContent)<br>
Case "DIAL" <br>
cReturn =
LookUp(cContent)<br>
frmVPhone.txtDial
= cReturn<br>
PlaceCall cReturn,
cContent<br>
End Select<br>
'<br>
End Function<br>
<br>
Function CommandOther(szCommand As String, szApp As String, szState As String)<br>
<br>
End Function</font></tt> </p>
</blockquote>
<hr>
<p>You'll notice that the only routine used is the <tt><font FACE="Courier">CommandRecognize</font></tt>
function. This routine looks at each command that passes through the speech recognition
engine, parses the input and, if it's a known command, executes the appropriate code. </p>
<p>The reason the command line must be parsed is that several of the voice commands will
be in the form of lists. You may remember that you can register command lists with the SR
engine without knowing the members of the list ahead of time. In your project, you'll fill
these lists with the names of people in the user's phone directory at run-time. </p>
<p>After you've entered the code, save this module as <tt><font FACE="Courier">SRCBK.CLS</font></tt>
before continuing with the chapter. </p>
<h2><b><a NAME="BuildingtheLibVPhoneModule"><font SIZE="5" COLOR="#FF0000">Building the </font><tt><font
SIZE="5" COLOR="#FF0000" FACE="Courier">LibVPhone</font></tt><font SIZE="5"
COLOR="#FF0000"> Module</font></a></b></h2>
<p>The <tt><font FACE="Courier">LibVPhone</font></tt> module contains most of the code for
the project. It is here that you'll put the routines that initialize the speech engines,
load the database engine, and handle the processes of adding, editing, and deleting
records from the phone book. </p>
<p>First, add a code module to the project. Set its <tt><font FACE="Courier">Name</font></tt>
property to <tt><font FACE="Courier">LibVPhone</font></tt> and save it as <tt><font
FACE="Courier">VPHONE.BAS</font></tt>. Next, add the project-level declarations shown in
Listing 35.7 to the general declaration section of the module. </p>
<hr>
<blockquote>
<b><p>Listing 35.7. Adding the project-level declarations.<br>
</b></p>
</blockquote>
<blockquote>
<tt><font FACE="Courier"><p>Option Explicit<br>
'<br>
' establish voice command objects<br>
Public objVCmd As Object<br>
Public objVMenu As Object<br>
Public lVMenuIdx As Long<br>
Public objVText As Object<br>
Public iVType As Integer<br>
Public cUserMsgs() As String<br>
'<br>
' spoken message handles<br>
Public Const ttsHello = 0<br>
Public Const ttsVPhone = 1<br>
Public Const ttsList = 2<br>
Public Const ttsExit = 3<br>
Public Const ttsEdit = 4<br>
'<br>
' database objects<br>
Public wsPhone As Workspace<br>
Public dbPhone As Database<br>
Public rsPhone As Recordset</font></tt> </p>
</blockquote>
<hr>
<p>The code here declares the required objects for SAPI and for database services. There
are also several constants that will be used to point to text messages that will be spoken
by the engine at requested times in the program. </p>
<h3><a NAME="AddingtheVoiceCommandRoutines"><b>Adding the Voice Command Routines</b></a></h3>
<p>Next add the routine that will start the SAPI service initialization. Add a subroutine
called <tt><font FACE="Courier">InitVCmd</font></tt> to the project and enter the code
from Listing 35.8. </p>
<hr>
<blockquote>
<b><p>Listing 35.8. Adding the <tt><font FACE="Courier">InitVCmd</font></tt> routine.<br>
</b></p>
</blockquote>
<blockquote>
<tt><font FACE="Courier"><p>Public Sub InitVCmd()<br>
'<br>
' init voice command<br>
Set objVCmd = CreateObject("Speech.VoiceCommand") <br>
objVCmd.Register ""<br>
objVCmd.Awake = True<br>
objVCmd.Callback = App.EXEName & ".SRCallBack" <br>
'<br>
' init voice menu<br>
BuildVMenu<br>
objVMenu.Active = True<br>
'<br>
End Sub</font></tt> </p>
</blockquote>
<hr>
<p>This code initializes the voice command object that will be used to handle speech
recognition services for the program. Notice the line that registers the <tt><font
FACE="Courier">SRCallBack</font></tt> class. The class name is prefixed with the
application name. You must set this application name manually. To do this, select <tt><font
FACE="Courier">Tools | Options | Project</font></tt> and enter <tt><font FACE="Courier">VPHONE</font></tt>
in the <tt><font FACE="Courier">Project Name</font></tt> field. </p>
<div align="center"><center>
<table BORDERCOLOR="#000000" BORDER="1" WIDTH="80%">
<tr>
<td><b>Warning</b> </td>
</tr>
<tr>
<td><blockquote>
<p>You must update the <tt><font FACE="Courier">Project Name</font></tt> field to match
the <tt><font FACE="Courier">App.EXEName</font></tt> value before you attempt to run the
project. If you fail to do this, you will receive errors from the SR engine. </p>
</blockquote>
</td>
</tr>
</table>
</center></div>
<p>The <tt><font FACE="Courier">InitVCmd</font></tt> routine calls another routine to
handle the creation of the command menu. Add a new subroutine to the module called <tt><font
FACE="Courier">BuildVMenu</font></tt> and enter the code shown in Listing 35.9. </p>
<hr>
<blockquote>
<b><p>Listing 35.9. Adding the <tt><font FACE="Courier">BuildVMenu</font></tt> routine.<br>
</b></p>
</blockquote>
<blockquote>
<tt><font FACE="Courier"><p>Public Sub BuildVMenu()<br>
'<br>
' build a voice menu<br>
'<br>
Dim iType As Integer<br>
Dim cState As String<br>
Dim lLangId As Long<br>
Dim cDialect As String<br>
Dim cAppName As String<br>
Dim cVMenu(3) As String<br>
Dim x As Integer<br>
'<br>
' set params<br>
cAppName = App.EXEName<br>
cState = "Voice Phone"<br>
cDialect = ""<br>
lLangId = 1033<br>
iType = vcmdmc_CREATE_TEMP<br>
'<br>
' set menu commands<br>
cVMenu(1) = "New Record"<br>
cVMenu(2) = "Place Call"<br>
cVMenu(3) = "Exit"<br>
'<br>
' now instance menu<br>
Set objVMenu = objVCmd.MenuCreate( _<br>
cAppName, cState, lLangId, cDialect,
iType)<br>
'<br>
' add simple commands to menu<br>
For x = 1 To 3<br>
lVMenuIdx = lVMenuIdx + 1<br>
objVMenu.Add lVMenuIdx, cVMenu(x),
"Voice Phone Commands", "Voice Phone <font FACE="ZAPFDINGBATS">Â</font>Commands"<br>
Next x<br>
<br>
'<br>
' create list commands<br>
lVMenuIdx = lVMenuIdx + 1<br>
objVMenu.Add lVMenuIdx, "Edit <Name>", "Edit
Name", "Edit Name"<br>
'<br>
lVMenuIdx = lVMenuIdx + 1<br>
objVMenu.Add lVMenuIdx, "Delete <Name>",
"Delete Name", "Delete Name"<br>
'<br>
lVMenuIdx = lVMenuIdx + 1<br>
objVMenu.Add lVMenuIdx, "Dial <Name>", "Dial
Name", "Dial Name"<br>
'<br>
lVMenuIdx = lVMenuIdx + 1<br>
objVMenu.Add lVMenuIdx, "Find <Name>", "Find
Name", "Find Name"<br>
'<br>
<br>
End Sub</font></tt> </p>
</blockquote>
<hr>
<p>There's a lot going on in this routine. First, internal variables are declared and set
to their respective values. Next, the menu object is created using the <tt><font
FACE="Courier">MenuCreate</font></tt> method. After the menu object is created, the <tt><font
FACE="Courier">Add</font></tt> method of the menu object is used to add simple voice
commands to the menu. Finally, the list commands are added to the menu (<tt><font
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -