⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch28.htm

📁 MAPI__SAPI__TAPI
💻 HTM
📖 第 1 页 / 共 5 页
字号:
  </b></p>
</blockquote>

<blockquote>
  <tt><font FACE="Courier"><p>Public Sub ClearHandles()<br>
  &nbsp;&nbsp;&nbsp;&nbsp;'<br>
  &nbsp;&nbsp;&nbsp;&nbsp;' set all control handles to zero<br>
  &nbsp;&nbsp;&nbsp;&nbsp;'<br>
  &nbsp;&nbsp;&nbsp;&nbsp;Tapiline1.LineHandle = 0<br>
  &nbsp;&nbsp;&nbsp;&nbsp;Tapiline1.HandleToCall = 0<br>
  &nbsp;&nbsp;&nbsp;&nbsp;Tapiline1.AddressID = 0<br>
  &nbsp;&nbsp;&nbsp;&nbsp;'<br>
  End Sub</font></tt> </p>
</blockquote>

<hr>

<p>These properties are all set when a call is accepted on a line device. Once a call is 
ended, you need to clear these properties in preparation for the next call. </p>

<p>Save the form (<tt><font FACE="Courier">TAPIANS.FRM</font></tt>) and project (<tt><font
FACE="Courier">TAPIANS.VBP</font></tt>) before continuing. </p>

<h4>Adding the <tt><font FACE="Courier">TapiCallBack</font></tt> Event Code</h4>

<p>The next code you need to add to the project relates to detecting and responding to 
TAPI messages (<tt><font FACE="Courier">TapiCallBack</font></tt>). The <tt><font
FACE="Courier">TapiCallBack</font></tt> event of the <tt><font FACE="Courier">TAPILINE</font></tt> 
control receives all messages generated by the TAPI system. As mentioned in earlier 
chapters, there are several different messages, each with their own set of accompanying 
parameters </p>

<p align="center">.</p>
<div align="center"><center>

<table BORDERCOLOR="#000000" BORDER="1" WIDTH="80%">
  <tr>
    <td><b>Note</b></td>
  </tr>
  <tr>
    <td><blockquote>
      <p>For more information on TAPI messages, their use, and meaning, refer to <a
      HREF="ch23.htm">Chapter 23</a>, &quot;TAPI Architecture.&quot; </p>
    </blockquote>
    </td>
  </tr>
</table>
</center></div>

<p>In this example, you need to keep track of only two messages: 

<ul>
  <li><tt><font FACE="Courier">LINE_CALLSTATE</font></tt> </li>
  <li><tt><font FACE="Courier">LINE_CLOSE</font></tt> </li>
</ul>

<p>The <tt><font FACE="Courier">LINE_CALLSTATE</font></tt> message is sent whenever the 
state of the selected line has changed. This program will watch for messages that indicate 
there is a new call on the line (<tt><font FACE="Courier">dwParam1 = LINECALLSTATE_OFFERED</font></tt>) 
or when the party on the other end of the line closed the call unexpectedly (<tt><font
FACE="Courier">dwParam1 = LINECALLSTATE_IDLE</font></tt>). The <tt><font FACE="Courier">LINE_CLOSE</font></tt> 
message is sent whenever the user ends the call normally. </p>

<p>You can monitor the message activity by adding code to the <tt><font FACE="Courier">TapiCallBack</font></tt> 
event that checks each message sent by TAPI. This is done using a <tt><font FACE="Courier">SELECT 
CASE</font></tt> structure to compare the incoming message to a list of messages for which 
you are waiting. The code in Listing 28.7 shows how this is done. Add this code to the <tt><font
FACE="Courier">TapiCallBack</font></tt> event. </p>

<hr>

<blockquote>
  <b><p>Listing 28.7. Adding code to the <tt><font FACE="Courier">TapiCallBack</font></tt> 
  event.<br>
  </b></p>
</blockquote>

<blockquote>
  <tt><font FACE="Courier"><p>Private Sub Tapiline1_TapiCallBack(ByVal hDevice As Long, 
  ByVal dwMessage As Long, <font FACE="ZAPFDINGBATS">&Acirc;</font>ByVal dwInstance As Long, 
  ByVal dwParam1 As Long, ByVal dwParam2 As Long, ByVal <font FACE="ZAPFDINGBATS">&Acirc;</font>dwParam3 
  As Long)<br>
  &nbsp;&nbsp;&nbsp;&nbsp;'<br>
  &nbsp;&nbsp;&nbsp;&nbsp;' handle TAPI messages<br>
  &nbsp;&nbsp;&nbsp;&nbsp;'<br>
  &nbsp;&nbsp;&nbsp;&nbsp;Dim cMsg As String<br>
  &nbsp;&nbsp;&nbsp;&nbsp;'<br>
  &nbsp;&nbsp;&nbsp;&nbsp;' handle call actions<br>
  &nbsp;&nbsp;&nbsp;&nbsp;Select Case dwMessage<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Case LINE_CALLSTATE ' state of call on 
  line changed<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Select Case 
  dwParam1<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Case 
  LINECALLSTATE_OFFERING ' get call handle<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Tapiline1.HandleToCall 
  = hDevice ' update handle to call<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MMControl1.Command 
  = &quot;play&quot; ' ring me!<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Case 
  LINECALLSTATE_IDLE ' they hung up on me!<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Tapiline1.LineDeallocateCall 
  ' dump pointer<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Tapiline1.HandleToCall 
  = 0 ' clear property<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AddText 
  txtStatus, &quot;LineDeallocate Successful&quot;<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;End Select<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Case LINE_CLOSE ' line was closed<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cmdButton_Click 2 
  ' force hangup<br>
  &nbsp;&nbsp;&nbsp;&nbsp;End Select<br>
  &nbsp;&nbsp;&nbsp;&nbsp;'<br>
  &nbsp;&nbsp;&nbsp;&nbsp;' report status to user<br>
  &nbsp;&nbsp;&nbsp;&nbsp;cMsg = TapiCallBackHandler(hDevice, dwMessage, dwInstance, 
  dwParam1, dwParam2, <font FACE="ZAPFDINGBATS">&Acirc;</font>dwParam3)<br>
  &nbsp;&nbsp;&nbsp;&nbsp;AddText txtStatus, cMsg<br>
  &nbsp;&nbsp;&nbsp;&nbsp;'<br>
  End Sub</font></tt> </p>
</blockquote>

<hr>

<p>The code in Listing 28.7 shows the <tt><font FACE="Courier">SELECT CASE</font></tt> 
structure monitoring two messages-<tt><font FACE="Courier">LINE_CALLSTATE</font></tt> and <tt><font
FACE="Courier">LINE_CLOSE</font></tt>. When the <tt><font FACE="Courier">LINE_CALLSTATE</font></tt> 
message appears, additional checking is performed to determine the exact state of the 
call. If a new call is appearing on the line (<tt><font FACE="Courier">LINECALLSTATE_OFFERING</font></tt>), 
the program updates the <tt><font FACE="Courier">HandleToCall</font></tt> property and 
then rings the workstation to tell the user a call is coming in. </p>

<p>If the call state has changed to completed (<tt><font FACE="Courier">LINECALLSTATE_IDLE</font></tt>), 
the routine releases memory allocated to the call and clears the <tt><font FACE="Courier">HandleToCall</font></tt> 
property in preparation for the next incoming call. </p>

<p>When the <tt><font FACE="Courier">LINE_CLOSE</font></tt> message appears, that means 
the user has completed the call. The code here makes a call to the <tt><font
FACE="Courier">cmdButton</font></tt> array that will act as if the user pressed the <tt><font
FACE="Courier">HangUp</font></tt> button (you'll code that in just a moment). </p>

<p>You'll also notice that the routine contains calls to the <tt><font FACE="Courier">TapiCallBackHandler</font></tt> 
function. This function interprets the TAPI message and creates a text string that can be 
shown to the user to indicate the progress of the call. </p>

<h4>Coding the <tt><font FACE="Courier">cmdButton</font></tt> Array</h4>

<p>The last code you need to add will handle the user's actions on the command buttons. 
There are four possible actions that the user can select: 

<ul>
  <li><tt><font FACE="Courier">Start</font></tt> opens the selected line for incoming calls. </li>
  <li><tt><font FACE="Courier">Answer</font></tt> is used to accept an incoming (ringing) 
    call. </li>
  <li><tt><font FACE="Courier">HangUp</font></tt> is used to end a call connection. </li>
  <li><tt><font FACE="Courier">Exit</font></tt> ends TAPI services and stops the program. </li>
</ul>

<p>Listing 28.8 shows the complete code for the <tt><font FACE="Courier">cmdButton_Click</font></tt> 
event. </p>

<hr>

<blockquote>
  <b><p>Listing 28.8. The code for the <tt><font FACE="Courier">cmdButton_Click</font></tt> 
  event.<br>
  </b></p>
</blockquote>

<blockquote>
  <tt><font FACE="Courier"><p>Private Sub cmdButton_Click(Index As Integer)<br>
  &nbsp;&nbsp;&nbsp;&nbsp;'<br>
  &nbsp;&nbsp;&nbsp;&nbsp;' open a line for monitoring<br>
  &nbsp;&nbsp;&nbsp;&nbsp;'<br>
  &nbsp;&nbsp;&nbsp;&nbsp;Dim lRtn As Long<br>
  &nbsp;&nbsp;&nbsp;&nbsp;Dim lPrivilege As Long<br>
  &nbsp;&nbsp;&nbsp;&nbsp;Dim lMediaMode As Long<br>
  &nbsp;&nbsp;&nbsp;&nbsp;'<br>
  &nbsp;&nbsp;&nbsp;&nbsp;' check for start up selection only<br>
  &nbsp;&nbsp;&nbsp;&nbsp;If Index = 0 Then<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;If lstLines.ListIndex = -1 Then<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MsgBox 
  &quot;Select a line first!&quot;, vbInformation<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Exit Sub<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;End If<br>
  &nbsp;&nbsp;&nbsp;&nbsp;End If<br>
  &nbsp;&nbsp;&nbsp;&nbsp;'<br>
  &nbsp;&nbsp;&nbsp;&nbsp;' set line parameters<br>
  &nbsp;&nbsp;&nbsp;&nbsp;lPrivilege = LINECALLPRIVILEGE_OWNER + LINECALLPRIVILEGE_MONITOR<br>
  &nbsp;&nbsp;&nbsp;&nbsp;lMediaMode = LINEMEDIAMODE_INTERACTIVEVOICE <br>
  &nbsp;&nbsp;&nbsp;&nbsp;'<br>
  &nbsp;&nbsp;&nbsp;&nbsp;' react to user selection<br>
  &nbsp;&nbsp;&nbsp;&nbsp;Select Case Index<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Case 0 ' start looking<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lRtn = 
  Tapiline1.LineOpen(lstLines.ListIndex, 0, lPrivilege, <font FACE="ZAPFDINGBATS">&Acirc;</font>lMediaMode) 
  <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;If lRtn &lt; 0 
  Then<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AddText 
  txtStatus, &quot;&lt;&lt;LineOpen ERROR&gt;&gt; &quot; &amp; LineErr(lRtn) <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Else <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AddText 
  txtStatus, &quot;LineOpen Successful&quot;<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AddText 
  txtStatus, &quot;Waiting for an incoming call...&quot;<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;' 
  <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cmdButton(0).Enabled 
  = False<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cmdButton(1).Enabled 
  = True<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cmdButton(2).Enabled 
  = True<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;' 
  <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;End If<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Case 1 ' answer call<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lRtn = 
  Tapiline1.LineAnswer(&quot;&quot;, 0) ' only needed for ISDN <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;If (lRtn &lt; 0) 
  Then<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AddText 
  txtStatus, &quot;&lt;&lt;LineAnswer ERROR&gt;&gt; &quot; &amp; LineErr(lRtn)<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Else <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AddText 
  txtStatus, &quot;LineAnswer Successful&quot;<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;End If<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Case 2 ' disconnect call<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Tapiline1.LineDrop 
  &quot;&quot;, 0 ' no parms unless ISDN!<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Tapiline1.LineClose 
  <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;' <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cmdButton(0).Enabled 
  = True<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cmdButton(1).Enabled 
  = False<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cmdButton(2).Enabled 
  = False<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;' <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ClearHandles ' 
  clean up control handles<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AddText txtStatus, 
  &quot;Line Dropped and Closed&quot;<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Case 3 ' exit program<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Unload Me<br>
  &nbsp;&nbsp;&nbsp;&nbsp;End Select<br>
  &nbsp;&nbsp;&nbsp;&nbsp;'<br>
  End Sub</font></tt> </p>
</blockquote>

<hr>

<p>There's a lot going on in this code section, so it is worth reviewing in greater 
detail. </p>

<p>First, if the user has pressed the <tt><font FACE="Courier">Start</font></tt> button, 
the code checks to make sure a line device has been selected from the list box. If no line 
device was selected, the user gets an error message, and the code exits the procedure (see 
Listing 28.9). </p>

<hr>

<blockquote>
  <b><p>Listing 28.9. Checking for a selected line device.<br>
  </b></p>
</blockquote>

<blockquote>
  <tt><font FACE="Courier"><p>' check for start up selection only<br>
  &nbsp;&nbsp;&nbsp;&nbsp;If Index = 0 Then<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;If lstLines.ListIndex = -1 Then<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MsgBox 
  &quot;Select a line first!&quot;, vbInformation<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Exit Sub<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;End If<br>
  &nbsp;&nbsp;&nbsp;&nbsp;End If</font></tt> </p>
</blockquote>

<hr>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -