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

📄 ch26.htm

📁 MAPI__SAPI__TAPI
💻 HTM
📖 第 1 页 / 共 5 页
字号:
  &nbsp;&nbsp;&nbsp;&nbsp;'<br>
  &nbsp;&nbsp;&nbsp;&nbsp;Dim cMsg As String<br>
  &nbsp;&nbsp;&nbsp;&nbsp;'<br>
  &nbsp;&nbsp;&nbsp;&nbsp;Select Case dwMessage<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Case LINE_ADDRESSSTATE '(= 0&amp;)<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cMsg = &quot;MSG: 
  Line_AddressState&quot;<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cMsg = cMsg &amp; 
  &quot;...&quot;<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cMsg = cMsg &amp; 
  &quot;AddressID=&quot; &amp; CStr(dwParam1)<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cMsg = cMsg &amp; 
  &quot;, State=&quot; &amp; LineAddressStateMsg(dwParam2) <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Case LINE_CALLINFO '(= 1&amp;)<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cMsg = &quot;MSG: 
  Line_CallInfo&quot;<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Case LINE_CALLSTATE&nbsp;&nbsp;'(= 2&amp;)<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cMsg = &quot;MSG: 
  Line_CallState&quot;<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cMsg = cMsg &amp; 
  &quot;...&quot;<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cMsg = cMsg &amp; 
  &quot;CallState=&quot; &amp; LineCallStateMsg(dwParam1) <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;Select Case 
  dwParam1<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Case 
  LINECALLSTATE_BUSY<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cMsg 
  = cMsg &amp; &quot;, StateDependent=&quot; &amp; <font FACE="ZAPFDINGBATS">&Acirc;</font>LineCallStateBusyMsg(dwParam2) 
  <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Case 
  LINECALLSTATE_DIALTONE<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cMsg 
  = cMsg &amp; &quot;, StateDependent=&quot; &amp; <font FACE="ZAPFDINGBATS">&Acirc;</font>LineCallStateDialtoneMsg(dwParam2) 
  <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Case 
  LINECALLSTATE_DISCONNECTED<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cMsg 
  = cMsg &amp; &quot;, StateDependent=&quot; &amp; <font FACE="ZAPFDINGBATS">&Acirc;</font>LineCallStateDisconnectedMsg(dwParam2) 
  <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Case 
  Else<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cMsg 
  = cMsg &amp; &quot;, StateDependent=&quot; &amp; CStr(dwParam2) <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;End Select<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;cMsg = cMsg &amp; 
  &quot;, Privilege=&quot; &amp; CStr(dwParam3)<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Case LINE_CLOSE '(= 3&amp;)<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cMsg = &quot;MSG: 
  Line_Close&quot;<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Case LINE_DEVSPECIFIC '(= 4&amp;)<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cMsg = &quot;MSG: 
  Line_DevSpecific&quot;<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Case LINE_DEVSPECIFICFEATURE '(= 5&amp;)<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cMsg = &quot;MSG: 
  Line_DevSpecificFeature&quot;<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Case LINE_GATHERDIGITS '(= 6&amp;)<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cMsg = &quot;MSG: 
  Line_GatherDigits&quot;<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Case LINE_GENERATE '(= 7&amp;)<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cMsg = &quot;MSG: 
  Line_Generate&quot;<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Case LINE_LINEDEVSTATE '(= 8&amp;)<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cMsg = &quot;MSG: 
  Line_LineDevState&quot;<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Case LINE_MONITORDIGITS '(= 9&amp;)<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cMsg = &quot;MSG: 
  Line_MonitorDigits&quot;<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Case LINE_MONITORMEDIA '(= 10&amp;)<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cMsg = &quot;MSG: 
  Line_MonitorMedia&quot;<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Case LINE_MONITORTONE '(= 11&amp;)<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cMsg = &quot;MSG: 
  Line_MonitorTone&quot;<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Case LINE_REPLY '(= 12&amp;)<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cMsg = &quot;MSG: 
  Line_Reply...idRequest=&quot; &amp; CStr(dwParam1) &amp; &quot; - Status = &quot; <font
  FACE="ZAPFDINGBATS">&Acirc;</font>&amp; LineErr(dwParam2) <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Case LINE_REQUEST '(= 13&amp;)<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cMsg = &quot;MSG: 
  Line_Request&quot;<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Case Else<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cMsg = &quot;MSG: 
  Unknown Message...&quot; + CStr(dwMessage)<br>
  &nbsp;&nbsp;&nbsp;&nbsp;End Select<br>
  &nbsp;&nbsp;&nbsp;&nbsp;'<br>
  &nbsp;&nbsp;&nbsp;&nbsp;TapiCallBackHandler = cMsg<br>
  &nbsp;&nbsp;&nbsp;&nbsp;'<br>
  End Function</font></tt> </p>
</blockquote>

<hr>

<p>This routine is designed to turn the callback <tt><font FACE="Courier">MessageID</font></tt> 
value and other parameters into a meaningful message to display in a status box on a form. 
In production applications, you could use this same <tt><font FACE="Courier">SELECT CASE</font></tt> 
structure to enclose calls to subroutines and functions that fire appropriate Visual Basic 
code based on the messages received. </p>

<p>You'll also notice that there are several calls to other support routines that 
translate parameters into meaningful strings for extended messages. These routines could 
be replaced by Visual Basic code that performs other tasks based on the parameters passed 
by TAPI into the <tt><font FACE="Courier">TAPICallBack</font></tt> event. </p>

<h3><a NAME="ASampleCallStateMessageFunction">A Sample <tt><font SIZE="4" FACE="Courier">CallState</font></tt><font
SIZE="4"> Message Function</font></a></h3>

<p>There are several functions that convert call-state parameters into messages. These 
routines could be used to fire off Visual Basic code based on the state of the current 
call. Listing 26.9 shows one of these routines. </p>

<hr>

<blockquote>
  <b><p>Listing 26.9. A sample <tt><font FACE="Courier">CallState</font></tt> message 
  function.<br>
  </b></p>
</blockquote>

<blockquote>
  <tt><font FACE="Courier"><p>Public Function LineCallStateDisconnectedMsg(dwParam As Long) 
  As String<br>
  &nbsp;&nbsp;&nbsp;&nbsp;'<br>
  &nbsp;&nbsp;&nbsp;&nbsp;' handle message values<br>
  &nbsp;&nbsp;&nbsp;&nbsp;'<br>
  &nbsp;&nbsp;&nbsp;&nbsp;Dim cReturn As String<br>
  &nbsp;&nbsp;&nbsp;&nbsp;'<br>
  &nbsp;&nbsp;&nbsp;&nbsp;Select Case dwParam<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Case LINEDISCONNECTMODE_NORMAL ' 
  &amp;H1&amp;<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cReturn = 
  &quot;Normal&quot;<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Case LINEDISCONNECTMODE_UNKNOWN ' 
  &amp;H2&amp;<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cReturn = 
  &quot;Unknown&quot;<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Case LINEDISCONNECTMODE_REJECT ' 
  &amp;H4&amp;<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cReturn = 
  &quot;Rejected&quot;<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Case LINEDISCONNECTMODE_PICKUP ' 
  &amp;H8&amp;<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cReturn = 
  &quot;Picked Up&quot;<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Case LINEDISCONNECTMODE_FORWARDED ' 
  &amp;H10&amp;<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cReturn = 
  &quot;Forwarded&quot;<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Case LINEDISCONNECTMODE_BUSY ' 
  &amp;H20&amp;<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cReturn = 
  &quot;Busy&quot;<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Case LINEDISCONNECTMODE_NOANSWER ' 
  &amp;H40&amp;<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cReturn = &quot;No 
  Answer&quot;<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Case LINEDISCONNECTMODE_BADADDRESS ' 
  &amp;H80&amp;<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cReturn = 
  &quot;Invalid Address&quot;<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Case LINEDISCONNECTMODE_UNREAchABLE ' 
  &amp;H100&amp;<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cReturn = 
  &quot;Unreachable&quot;<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Case LINEDISCONNECTMODE_CONGESTION ' 
  &amp;H200&amp;<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cReturn = 
  &quot;Congested Network&quot;<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Case LINEDISCONNECTMODE_IncOMPATIBLE ' 
  &amp;H400&amp;<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cReturn = 
  &quot;Incompatible Equipment&quot;<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Case LINEDISCONNECTMODE_UNAVAIL ' 
  &amp;H800&amp;<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cReturn = 
  &quot;Reason Unavailable&quot;<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Case Else<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cReturn = 
  &quot;Unknown LineCallStateDisconnected Msg [&quot; &amp; CStr(dwParam) &amp; <font
  FACE="ZAPFDINGBATS">&Acirc;</font>&quot;]&quot;<br>
  &nbsp;&nbsp;&nbsp;&nbsp;End Select<br>
  &nbsp;&nbsp;&nbsp;&nbsp;'<br>
  &nbsp;&nbsp;&nbsp;&nbsp;LineCallStateDisconnectedMsg = cReturn <br>
  &nbsp;&nbsp;&nbsp;&nbsp;'<br>
  End Function</font></tt> </p>
</blockquote>

<hr>

<p>This routine handles one of the parameters returned from a line disconnect event. </p>

<h3><a NAME="TheCleanandOffSetFunctions">The <tt><font SIZE="4" FACE="Courier">Clean</font></tt><font
SIZE="4"> and </font><tt><font SIZE="4" FACE="Courier">OffSet</font></tt><font SIZE="4"> 
Functions</font></a></h3>

<p>Some of the TAPI functions return data in variable-length strings. These data strings 
usually contain several items, separated by zeros. You need two routines to help read the 
data in these strings. First, you need a routine to clean out the zero character (0) 
values in a returned string. Second, you need a routine that can pick a block of 
characters out of the data string based on an offset and a string size. This offset and 
size are returned as part of the fixed-size data structure. </p>

<p>The <tt><font FACE="Courier">Clean</font></tt> function removes all character string 0 
values from the returned data. Listing 26.10 shows how this is done. </p>

<hr>

<blockquote>
  <b><p>Listing 26.10. The <tt><font FACE="Courier">Clean</font></tt> function.<br>
  </b></p>
</blockquote>

<blockquote>
  <tt><font FACE="Courier"><p>Function Clean(c As String) As String <br>
  &nbsp;&nbsp;&nbsp;&nbsp;'<br>
  &nbsp;&nbsp;&nbsp;&nbsp;' strip 0s from string<br>
  &nbsp;&nbsp;&nbsp;&nbsp;'<br>
  &nbsp;&nbsp;&nbsp;&nbsp;Dim l As Integer<br>
  &nbsp;&nbsp;&nbsp;&nbsp;Dim x As Integer<br>
  &nbsp;&nbsp;&nbsp;&nbsp;Dim s As String<br>
  &nbsp;&nbsp;&nbsp;&nbsp;Dim n As Integer<br>
  &nbsp;&nbsp;&nbsp;&nbsp;'<br>
  &nbsp;&nbsp;&nbsp;&nbsp;l = Len<br>
  &nbsp;&nbsp;&nbsp;&nbsp;s = &quot;&quot;<br>
  &nbsp;&nbsp;&nbsp;&nbsp;For x = 1 To Len<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;If Mid(c, x, 1) &lt;&gt; Chr(0) Then<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s = s + Mid(c, x, 
  1)<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Else<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s = s + &quot; 
  &quot;<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;End If<br>
  &nbsp;&nbsp;&nbsp;&nbsp;Next<br>
  &nbsp;&nbsp;&nbsp;&nbsp;'<br>
  &nbsp;&nbsp;&nbsp;&nbsp;Clean = s<br>
  End Function</font></tt> </p>
</blockquote>

<hr>

<p>You'll notice that the routine replaces all character zeros with character 32 (space). 
This maintains the original size of the string, but prevents Visual Basic from 
encountering errors when it tries to read a string that contains character 0 values. </p>

<p>The second routine needed to handle the variable strings is one that picks out a 
substring based on the offset and size values found in the fixed data structure. Listing 
26.11 shows how the <tt><font FACE="Courier">GetOffset</font></tt> function works. </p>

<hr>

<blockquote>
  <b><p>Listing 26.11. The <tt><font FACE="Courier">GetOffset</font></tt> function.<br>
  </b></p>
</blockquote>

<blockquote>
  <tt><font FACE="Courier"><p>Public Function GetOffset(lLenStru As Long, lOffset As Long, 
  lSize As Long, <font FACE="ZAPFDINGBATS">&Acirc;</font>cExtraData As String) As String<br>
  &nbsp;&nbsp;&nbsp;&nbsp;'<br>
  &nbsp;&nbsp;&nbsp;&nbsp;' return the data at the offset<br>
  &nbsp;&nbsp;&nbsp;&nbsp;'<br>
  &nbsp;&nbsp;&nbsp;&nbsp;GetOffset = Mid(cExtraData, (lOffset - lLenStru) + 1, lSize)<br>
  &nbsp;&nbsp;&nbsp;&nbsp;'<br>
  End Function</font></tt> </p>
</blockquote>

<hr>

<p>TAPI returns an offset value computed from the start of the original data structure. 
For this reason, the length of the data structure is passed as a first parameter into the 
function. This length is the size of the fixed portion of the data structure. The <tt><font
FACE="Courier">GetOffset</font></tt> routine subtracts the fixed-length amount to get the 
starting position in the <tt><font FACE="Courier">cExtraData</font></tt> string space. 
This position is used to pick out a data string that is the length of <tt><font
FACE="Courier">lSize</font></tt>. The resulting string is then returned to the calling 
program. </p>

⌨️ 快捷键说明

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