705 lines
21 KiB
HTML
705 lines
21 KiB
HTML
<! --
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
Copyright (C) 1998-1999 Microsoft Corporation. All rights reserved.
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
TAPI3 Ip Multicast conference participation
|
|
|
|
This sample page demonstrates how to use tapi3 in vbscript to join a multicast conference.
|
|
|
|
NOTE: this page could be used just with IE greater then 5.0
|
|
|
|
NOTE: due to the simple event processing demonstrated in this page,
|
|
your audio (and probably video) might be choppy.
|
|
You can change this by modifying the sample to refresh the contents less often
|
|
(you could implement your custom delay in TAPIOBJ_Event).
|
|
|
|
What is shown:
|
|
1. Tapi initialization
|
|
2. REND usage (connecting to ILS server, conference info extraction)
|
|
3. Call management
|
|
4. Media and Terminal management (including preview window)
|
|
5. Video substreams management
|
|
|
|
What is not shown:
|
|
1. You could improve performance by modifying the sample to react only for those tapi events
|
|
that your app is interested in.
|
|
2. This page does not manage the positioning of video windows.
|
|
(In order to do this, you can change the sample to use an ActiveX control that is able
|
|
to set properties in IVideoWindow. This requires window handle values - HWND - which
|
|
are not available in vbscripting).
|
|
3. This page performs Bind to the conference server using default credentials
|
|
(the credentials of the currently logged on user). If you want to run the script without
|
|
being logged on to a domain (without domain credentials), then remove the Bind call; that
|
|
will work with ILS servers, but won't work with TAPI Active Directory Partitions.
|
|
|
|
-->
|
|
|
|
<HTML>
|
|
<HEAD>
|
|
<META name=VI60_defaultClientScript content=VBScript>
|
|
<META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0">
|
|
<TITLE>
|
|
Conference
|
|
</TITLE>
|
|
</HEAD>
|
|
|
|
<SCRIPT LANGUAGE="JavaScript"><!--
|
|
|
|
var ua = navigator.userAgent;
|
|
var an = navigator.appName;
|
|
|
|
// Is it IE?
|
|
bMSIE = (ua.indexOf("MSIE")>=1);
|
|
if (! bMSIE)
|
|
{
|
|
alert("You need to use IE to run this page");
|
|
window.close;
|
|
}
|
|
//-->
|
|
</SCRIPT>
|
|
|
|
|
|
<SCRIPT LANGUAGE=vbscript>
|
|
|
|
'Constants section
|
|
|
|
'The number of windows (including preview) that are created at startup
|
|
'Note: each window takes a lot of resources, so you need to carefully estimate
|
|
'the required amount
|
|
Const S_MAX_CLIENT_WINDOWS=4
|
|
|
|
|
|
'These constants are taken from tapi3.h, tapi3if.idl, rend.idl and confpriv.idl
|
|
Const TAPIMEDIATYPE_AUDIO = &H08&
|
|
Const TAPIMEDIATYPE_VIDEO = &H8000&
|
|
Const S_MEDIA_AUDIOVIDEO = &H8008&
|
|
Const TD_CAPTURE = 0
|
|
Const TD_RENDER = 1
|
|
Const QSL_NEEDED = 1
|
|
Const LINEADDRESSTYPE_SDP = 2
|
|
Const AS_INSERVICE = 0
|
|
Const DT_ILS = 2
|
|
Const OT_CONFERENCE = 1
|
|
Const DC_NORMAL = 0
|
|
Const PTI_CANONICALNAME = 0
|
|
Const AC_ADDRESSTYPES = 0
|
|
|
|
'Interface IDs for casting
|
|
'Note: you can find the following IID-s in tapi3.h, tapi3if.idl, confpriv.idl, rend.idl or sdpblb.h
|
|
|
|
Const IID_String_ITMediaSupport = "{B1EFC384-9355-11D0-835C-00AA003CCABD}"
|
|
Const IID_String_ITTerminalSupport="{B1EFC385-9355-11D0-835C-00AA003CCABD}"
|
|
Const IID_String_ITStreamControl= "{EE3BD604-3868-11D2-A045-00C04FB6809F}"
|
|
Const IID_String_ITParticipantControl = "{d2ee6684-5a34-11d2-95a0-00a0244d2298}"
|
|
Const IID_String_ITDirectoryObjectConference= "{F1029E5D-CB5B-11D0-8D59-00C04FD91AC0}"
|
|
Const IID_String_ITConferenceBlob= "{C259D7AA-C8AB-11D0-8D58-00C04FD91AC0}"
|
|
Const IID_String_ITAddressCapabilities="{8DF232F5-821B-11d1-BB5C-00C04FB6809F}"
|
|
' IID of IVideoWindow
|
|
' Note: you can find this IID defined in control.h (from your sdk\inc directory),
|
|
' which contains the interface to type library for quartz.dll;
|
|
' (search for the interface IVideoWindow)
|
|
Const IID_String_IVideoWindow = "{56A868B4-0AD4-11CE-B03A-0020AF0BA770}"
|
|
|
|
' The following CLSID is defined in tapi3.h
|
|
'(and it's used for creating a terminal of class "video window terminal")
|
|
Const CLSID_String_VideoWindowTerm = "{F7438990-D6EB-11d0-82A6-00AA00B5CA1B}"
|
|
|
|
|
|
'Definition of page-wide variables
|
|
|
|
'Current ITBasicCallControl: current call
|
|
DIM spITBasicCallControl
|
|
'Current Address - should be address with name "IPCONF LINE"
|
|
DIM spITAddress
|
|
|
|
DIM spITStreamControl
|
|
DIM spITParticipantControl
|
|
|
|
' The variable sintNumParticipants holds the current number of
|
|
' participants. This is recalculated on each refresh cycle.
|
|
DIM sintNumParticipants
|
|
sintNumParticipants = 0
|
|
'Array of ALL participants names
|
|
DIM sPartNames(200)
|
|
|
|
DIM sblnReadyToShow ' Prevent from trying "window operations" while we are not yet ready to show anything
|
|
|
|
'Global var used for error handling
|
|
DIM sbNeedToExit
|
|
sbNeedToExit = False
|
|
|
|
'Error handling routine: display error code, etc
|
|
Sub CheckError(strMsg)
|
|
if not Err.number = 0 Then
|
|
MsgBox strMsg & ":" & Err.number & ";"&Err.description
|
|
sbNeedToExit = True
|
|
Err.Clear
|
|
End If
|
|
End Sub
|
|
|
|
'****************************************************************************
|
|
' Starting procedure:
|
|
' 1. Initialize global variables
|
|
' 2. Find "IPCONF LINE" address
|
|
' 3. Get SDP blob from ILS server
|
|
' 4. Create Call and setup static terminals
|
|
' 5. Create dynamic terminals
|
|
' 6. Set QOS
|
|
' 7. Connect to the conference
|
|
Sub connect_conference
|
|
|
|
' Note: TAPI object SHOULD BE INITIALIZED BEFORE
|
|
' window_onload EVENT. OTHERWISE YOU WILL NOT BE ABLE
|
|
' TO CATCH ANY EVENT.....
|
|
|
|
sbNeedToExit = False
|
|
|
|
if txtILSServer.value="" Then
|
|
MsgBox "Enter ILS server name",0,"Connect"
|
|
Exit Sub
|
|
End If
|
|
|
|
if txtConfName.value="" Then
|
|
MsgBox "Enter conference name",0,"Connect"
|
|
Exit Sub
|
|
End If
|
|
|
|
On Error Resume Next
|
|
|
|
sblnReadyToShow = False
|
|
|
|
window.status = "Obtain conference information..."
|
|
|
|
'First of all we need to obtain the SDP blob related to this conference from ILS Server
|
|
DIM pSDPBlob
|
|
pSDPblob = Select_SDP_blob()
|
|
window.status = "Conference information obtained"
|
|
|
|
if sbNeedToExit Then
|
|
Exit Sub
|
|
End If
|
|
|
|
call CheckError("connect_conference:after select_SDP_blob" )
|
|
|
|
'Walk through the addresses in order to find our IPCONF line
|
|
'Note: another way to find this address would be to look for addresses that support
|
|
'the address type LINEADDRESSTYPE_SDP.
|
|
|
|
blnIsSelected = False
|
|
window.status = "Perform local addresses checking..."
|
|
DIM pITAddress
|
|
|
|
For Each pITAddress in TAPIOBJ.Addresses
|
|
|
|
DIM pITAddressCapabilities
|
|
|
|
Set pITAddressCapabilities = MAPPER.QueryDispatchInterface(IID_String_ITAddressCapabilities,pITAddress)
|
|
call CheckError("Query ITAddress for ITAddressCapabilities")
|
|
|
|
AddressTypes = pITAddressCapabilities.AddressCapability(AC_ADDRESSTYPES)
|
|
call CheckError("Get AddressTypes")
|
|
'Check that this address supportonly SDP blob as an address
|
|
if AddressTypes = LINEADDRESSTYPE_SDP Then
|
|
|
|
'Obtain ITMediaSupport
|
|
DIM pITMediaSupport
|
|
|
|
Set pITMediaSupport = MAPPER.QueryDispatchInterface(_
|
|
IID_String_ITMediaSupport,pITAddress)
|
|
|
|
call CheckError("connect_conference:Query ITAddress for ITMediaSupport" )
|
|
|
|
'Check if both audio and video are supported
|
|
blnSupportVideoAndAudio = _
|
|
pITMediaSupport.QueryMediaType(S_MEDIA_AUDIOVIDEO)
|
|
|
|
call CheckError("connect_conference:ITMediaSupport.QueryMediaType" )
|
|
'Check if this address is in service
|
|
|
|
if blnSupportVideoAndAudio and pITAddress.State = AS_INSERVICE Then
|
|
' This address will be used for conference
|
|
blnIsSelected = True
|
|
Exit For
|
|
End IF
|
|
End If
|
|
Next
|
|
|
|
call CheckError("connect_conference:After cycle on Addresses")
|
|
|
|
|
|
'The address is selected?
|
|
|
|
if not blnIsSelected Then
|
|
MsgBox "You have no IPCONF LINE address that supports both audio and video.Sorry."
|
|
Exit Sub
|
|
End if
|
|
|
|
Set spITAddress = pITAddress
|
|
Set pITAddress = Nothing
|
|
|
|
|
|
'Create a Call
|
|
DIM lngMediaTypes
|
|
|
|
'You can setup the call to be audio only, or video only or audio+video
|
|
lngMediaTypes = S_MEDIA_AUDIOVIDEO
|
|
|
|
'Create call with address type 2 = LINEADDRESSTYPE_SDP (SDP blob)
|
|
Set spITBasicCallControl = spITAddress.CreateCall(pSDPblob,LINEADDRESSTYPE_SDP,lngMediaTypes)
|
|
|
|
call CheckError("connect_conference:CreateCall" )
|
|
|
|
|
|
'Terminal allocation
|
|
Call SetupTerminals()
|
|
|
|
if bNeedToExit Then
|
|
Exit Sub
|
|
End If
|
|
|
|
'Let's try to setup QoS level
|
|
window.status = "Set QOS..."
|
|
|
|
call spITBasicCallControl.SetQOS(TAPIMEDIATYPE_VIDEO,QSL_NEEDED)
|
|
call CheckError("connect_conference:set QOS_REQUIRED for Video" )
|
|
|
|
call spITBasicCallControl.SetQOS(TAPIMEDIATYPE_AUDIO,QSL_NEEDED)
|
|
call CheckError("connect_conference:set QOS_REQUIRED for Audio" )
|
|
|
|
if bNeedToExit Then
|
|
Exit Sub
|
|
End If
|
|
|
|
window.status = "Prepare to connect..."
|
|
|
|
'Connect synchronous
|
|
spITBasicCallControl.Connect(True)
|
|
|
|
if not Err.number = 0 Then
|
|
MsgBox "Unable to connect: error " & Hex(Err.number)
|
|
window.status = "Done."
|
|
Err.Clear
|
|
Exit Sub
|
|
End If
|
|
|
|
window.status = "Connected."
|
|
|
|
Set spITParticipantControl = MAPPER.QueryDispatchInterface( _
|
|
IID_String_ITParticipantControl, spITBasicCallControl )
|
|
|
|
call CheckError("connect_conference: query ITCall for ITPArticipantControl")
|
|
|
|
buttonConnect.disabled = true
|
|
buttonHangup.disabled = False
|
|
|
|
CAll Show_Participants()
|
|
|
|
End Sub
|
|
|
|
'*************************************************************
|
|
'*************************************************************
|
|
' disconnect from the conference
|
|
Sub conference_hangup
|
|
'Just set all global variables to nothing
|
|
On Error resume Next
|
|
sintNumParticipants = 0
|
|
|
|
'The next function call (Disconnect) can eventually fail; this is because we don't check
|
|
'in this sample the current status of the call when we call Disconnect. So we can ignore
|
|
'this error.
|
|
spITBasicCallControl.Disconnect DC_NORMAL
|
|
Err.Clear
|
|
|
|
Set spITBasicCallControl = Nothing
|
|
Set spITAddress = Nothing
|
|
|
|
Set spITStreamControl = Nothing
|
|
Set spITParticipantControl = Nothing
|
|
|
|
buttonConnect.disabled = False
|
|
buttonHangup.disabled = True
|
|
Call DrawParticipantsList()
|
|
End Sub
|
|
|
|
|
|
'*************************************************************
|
|
'*************************************************************
|
|
' Setting up Terminals routine
|
|
' We need to specify a maximum number of participants
|
|
' and create for each possible participant a
|
|
' "video render" terminal
|
|
' In the case of static terminals, we just pick up the default terminal
|
|
' for that particular media + direction.
|
|
Sub SetupTerminals()
|
|
On Error Resume Next
|
|
'Stream module
|
|
Set spITStreamControl = MAPPER.QueryDispatchInterface(_
|
|
IID_String_ITStreamControl,spITBasicCallControl)
|
|
|
|
call CheckError("SetupTerminals:Query ITCall for ITStreamControl" )
|
|
|
|
DIM pITTerminalSupport
|
|
|
|
Set pITTerminalSupport = MAPPER.QueryDispatchInterface(_
|
|
IID_String_ITTerminalSupport,spITAddress)
|
|
|
|
call CheckError("SetupTerminals:Query ITAddress for ITTerminalSuport" )
|
|
|
|
DIM pITStream
|
|
DIM lngMediaType
|
|
DIM lngDirection
|
|
DIM blnIsError
|
|
Dim pIVideoWindow
|
|
Dim pVideoWindow
|
|
|
|
blnIsError = False
|
|
|
|
window.status = "Configuring terminals..."
|
|
|
|
For Each pITStream in spITStreamControl.Streams
|
|
|
|
lngMediaType = pITStream.MediaType
|
|
lngDirection = pITStream.Direction
|
|
|
|
'Try to find the correspondent static terminal
|
|
' Video rendering stream is a special case - this one doesn't have
|
|
' a "default static terminal" - we rather have to create a dynamic terminal for it.
|
|
|
|
if not (lngMediaType = TAPIMEDIATYPE_VIDEO and lngDirection = TD_RENDER) Then
|
|
|
|
Set pITTerminal = pITTerminalSupport.GetDefaultStaticTerminal(lngMediaType,lngDirection)
|
|
|
|
if not (Err.number = 0) Then 'No such terminal?
|
|
blnIsError = True
|
|
Err.Clear
|
|
Else
|
|
blnIsError = False
|
|
pITStream.SelectTerminal(pITTerminal)
|
|
call CheckError("SetupTerminals:SelectTerminal" )
|
|
End if
|
|
|
|
|
|
|
|
if blnIsError Then 'Maybe we could join without this terminal
|
|
|
|
if (lngMediaType = TAPIMEDIATYPE_VIDEO and _
|
|
lngDirection=TD_CAPTURE) Then
|
|
MsgBox "Unable to find video capture device: attach receive video only",0,"Terminal Selection"
|
|
Else
|
|
if (lngMediaType = TAPIMEDIATYPE_AUDIO and lngDirection=TD_CAPTURE) Then
|
|
MsgBox "Unable to find audio capture device: attach receive audio only",0,"Terminal Selection"
|
|
Else
|
|
MsgBox "Unable to attach: even audio playback device is missing",0,"Terminal Selection"
|
|
sbNeedToExit = True
|
|
Exit Sub
|
|
End if
|
|
End if
|
|
Else 'No errors, start this stream!
|
|
|
|
' Create preview window on the video capture stream
|
|
|
|
' Note: we already selected on this stream the default static terminal, which,
|
|
' in case it's present, would basically be a video camera.
|
|
' Here, we do one more thing: on the same "video capture" stream we select a dynamic
|
|
' terminal as well, a video window; this will provide a "preview" window, which will
|
|
' show us the video stream that is being captured by the our local camera and sent to the
|
|
' other participants from the conference.
|
|
|
|
if ((lngMediaType = TAPIMEDIATYPE_VIDEO) and (lngDirection=TD_CAPTURE)) Then
|
|
|
|
'Create Video Terminal
|
|
Set pVideoWindow = pITTerminalSupport.CreateTerminal(CLSID_String_VideoWindowTerm,TAPIMEDIATYPE_VIDEO,TD_RENDER)
|
|
call CheckError("SetupTerminals: Create Terminal")
|
|
|
|
'select on stream
|
|
pITStream.SelectTerminal(pVideoWindow)
|
|
call CheckError("SetupTerminals: SelectTerminal")
|
|
|
|
'Immediately make it visible as soon as stream is active
|
|
Set pIVideoWindow = MAPPER.QueryDispatchInterface(IID_String_IVideoWindow, pVideoWindow)
|
|
call CheckError("SetupTerminals: query for IVideoWindow")
|
|
|
|
pIVideoWindow.AutoShow = TRUE
|
|
call CheckError("SetupTerminals: set visibility")
|
|
End If
|
|
|
|
|
|
End if 'have error
|
|
Else
|
|
'Special case: video rendering stream
|
|
|
|
|
|
For intCount = 1 to S_MAX_CLIENT_WINDOWS-1
|
|
|
|
'Create Terminal
|
|
Set pVideoWindow = pITTerminalSupport.CreateTerminal(CLSID_String_VideoWindowTerm,TAPIMEDIATYPE_VIDEO,TD_RENDER)
|
|
call CheckError("SetupTerminals: Create Terminal")
|
|
'select on stream
|
|
pITStream.SelectTerminal(pVideoWindow)
|
|
call CheckError("SetupTerminals: SelectTerminal")
|
|
|
|
Set pIVideoWindow = MAPPER.QueryDispatchInterface(IID_String_IVideoWindow, pVideoWindow)
|
|
call CheckError("SetupTerminals: query for IVideoWindow")
|
|
|
|
pIVideoWindow.AutoShow = TRUE
|
|
call CheckError("SetupTerminals: set visibility")
|
|
|
|
Next 'for each terminal
|
|
|
|
|
|
End if 'Necessary to check this stream
|
|
|
|
call CheckError("SetupTerminals:GeneralChecking1" )
|
|
|
|
|
|
Next ' End cycle for ITStreams
|
|
|
|
call CheckError("SetupTerminals:Streams enumeration problems" )
|
|
|
|
Set pIVideoWindow = Nothing
|
|
Set pVideoWindow = Nothing
|
|
|
|
End Sub
|
|
|
|
'*************************************************************
|
|
'*************************************************************
|
|
'*************************************************************
|
|
' Obtain from the ILS server the SDP blob that describes the conference
|
|
Function Select_SDP_blob
|
|
On Error Resume Next
|
|
DIM strDirectoryName
|
|
DIM intDirectoryType
|
|
DIM pITDirectory
|
|
DIm pITDirectoryObject
|
|
DIM pITDirectoryObjectConference
|
|
|
|
strDirectoryName = Trim(txtILSServer.value) 'Name and type of server to connect to
|
|
intDirectoryType = DT_ILS
|
|
|
|
|
|
Err.Clear
|
|
|
|
blnConnectFailed = False
|
|
|
|
'REND is an object of type ITRendezvous
|
|
Set pITDirectory = REND.CreateDirectory(intDirectoryType,strDirectoryName)
|
|
call CheckError("select_SDP_blob:CreateDirectory 2" )
|
|
|
|
pITDirectory.Connect false
|
|
|
|
if not Err.number = 0 Then
|
|
MsgBox "Unable to connect to conference server: server down?",0,"Connect"
|
|
sbNeedToExit = True
|
|
Err.Clear
|
|
Exit Function
|
|
End If
|
|
|
|
'
|
|
'The next bind is needed only if you want this code to work with
|
|
'Tapi Active Directory Partitions as well, in addition to ILS servers.
|
|
'If you only want to run this script against ILS servers, then you might
|
|
'as well remove the Bind.
|
|
'Also, you need to remove the Bind if you want the script to run for a user
|
|
'who doesn't have domain credentials (is not logged on to any particular
|
|
'domain).
|
|
'
|
|
'Note that the next Bind is executed using default credentials (the credentials
|
|
'of the currently logged on user); you can modify this source code and
|
|
'add UI elements that allow the user to specify his desired credentials.
|
|
'
|
|
|
|
call pITDirectory.Bind("","","",15)
|
|
|
|
if not Err.number = 0 Then
|
|
MsgBox "Unable to Bind to conference server!",0,"Bind"
|
|
sbNeedToExit = True
|
|
Err.Clear
|
|
Exit Function
|
|
End If
|
|
|
|
|
|
blnIsFound = false
|
|
|
|
For Each pITDirectoryObject_current in pITDirectory.DirectoryObjects(OT_CONFERENCE,txtConfName.value)
|
|
Dim tmpN
|
|
tmpN = escape(pITDirectoryObject_current.name)
|
|
tmpN1 = escape(txtConfName.value)
|
|
|
|
if (tmpN = tmpN1) Then
|
|
blnIsFound = True
|
|
Set pITDirectoryObject = pITDirectoryObject_current
|
|
End if
|
|
Next
|
|
|
|
call CheckError("select_SDP_blob:cycle for DirectoryObjects" )
|
|
|
|
if not blnIsFound then
|
|
MsgBox "Sorry, this conference does not exist or you are not authorized to connect to it",0,"Connect"
|
|
sbNeedToExit = True
|
|
Exit Function
|
|
End if
|
|
|
|
'Obtain ITDirectoryObjectConference
|
|
Set pITDirectoryObjectConference = _
|
|
MAPPER.QueryDispatchInterface(IID_String_ITDirectoryObjectConference,pITDirectoryObject)
|
|
|
|
call CheckError("select_SDP_blob:query ITDirectoryObject for ITDirectoryObjectConference" )
|
|
|
|
' Put properties into form
|
|
|
|
'Obtain ITConferenceBlob
|
|
DIM pITConferenceBlob
|
|
Set pITConferenceBlob = _
|
|
MAPPER.QueryDispatchInterface(IID_String_ITConferenceBlob,pITDirectoryObjectConference)
|
|
|
|
call CheckError("select_SDP_blob:query ITDirectoryObjectConference for ITConferenceBlob" )
|
|
|
|
Select_SDP_blob = pITConferenceBlob.ConferenceBlob
|
|
|
|
call CheckError("select_SDP_blob:pITConferenceBlob.ConferenceBlob" )
|
|
|
|
End Function
|
|
|
|
|
|
'*************************************************************
|
|
'*************************************************************
|
|
'*************************************************************
|
|
'*************************************************************
|
|
'Make list of participants visible
|
|
Sub DrawParticipantsList
|
|
On Error Resume Next
|
|
DIM strPartyList
|
|
DIM intPosition
|
|
strPartyList = ""
|
|
|
|
DIM curIndex
|
|
curIndex = 0
|
|
Dim oOption
|
|
|
|
divPartNum.innerHTML = "Participants("&Cstr(sintNumParticipants)&")"
|
|
|
|
for i = 0 to selParticipants.options.length
|
|
selParticipants.remove(0)
|
|
Next
|
|
|
|
for i=1 to sintNumParticipants
|
|
Set oOption = document.createElement("OPTION")
|
|
oOption.text = Left(sPartNames(i),25)
|
|
oOption.value = Left(sPartNames(i),25)
|
|
selParticipants.add oOption
|
|
Next
|
|
|
|
Err.Clear
|
|
End Sub
|
|
|
|
'*************************************************************
|
|
' Construct list of participants
|
|
Sub Show_participants
|
|
On Error Resume Next
|
|
|
|
window.status = "Update cycle started..."
|
|
|
|
sblnReadyToShow = False
|
|
sintCallspostphoned = 0
|
|
|
|
' Interfaces used here are described in confpriv.idl
|
|
DIM pITParticipant
|
|
DIM pCollectionParticipants
|
|
Set pCollectionParticipants = spITParticipantControl.Participants
|
|
|
|
if not Err.number = 0 Then ' No participants object: conference disconnected?
|
|
Err.Clear
|
|
Exit Sub
|
|
End If
|
|
|
|
sintNumParticipants = 0
|
|
For Each pITParticipant in pCollectionParticipants
|
|
strName = "<unknown>"
|
|
|
|
'Get participant name - this call sometimes could fail (if somebody does not supply name)
|
|
strName = pITParticipant.ParticipantTypedInfo(PTI_CANONICALNAME)
|
|
|
|
If Err.number = 0 Then
|
|
sintNumParticipants = sintNumParticipants + 1
|
|
sPartNames(sintNumParticipants) = strName
|
|
End If 'Could be queried for name
|
|
|
|
'Just clear all errors that could occur
|
|
Err.Clear
|
|
Next
|
|
|
|
Call DrawParticipantsList()
|
|
|
|
sblnReadyToShow = True
|
|
window.status = "Done."
|
|
End Sub
|
|
|
|
'******************************************************************
|
|
' Simplest Event-driving: on a case of ANY event
|
|
' redraw participant list
|
|
Sub TAPIOBJ_Event(tapi_event, pEvent)
|
|
Call show_participants()
|
|
End Sub
|
|
|
|
</SCRIPT>
|
|
|
|
|
|
|
|
<BODY unload="conference_hangup()">
|
|
|
|
<div id=divPartList style="position:absolute;Top:0px;Left:10px;Height:95%;width:150px">
|
|
<div id=divPartNum class="sectionheader" style="BORDER-BOTTOM: black 1px solid; BORDER-LEFT: black 1px solid; BORDER-RIGHT: black 1px solid; BORDER-TOP: black 1px solid; HEIGHT: 30px; LEFT: 0px; TEXT-ALIGN: center; WIDTH: 150px">
|
|
Participants
|
|
</div>
|
|
|
|
<SELECT size=2 id=selParticipants
|
|
style="border:none;left:0px;top:30px;position:absolute;height:200px;width:150px;FONT-SIZE:10px;COLOR:black">
|
|
</SELECT>
|
|
|
|
<div id=divPartyList style="FONT-SIZE:12px;COLOR:blue;position:absolute;Top:40px;Left:10px;width:145px;">
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<p style="position:absolute;top:50px;left:200px">
|
|
ILS Server
|
|
</p>
|
|
<INPUT id=txtILSServer style="position:absolute;top:50px;left:330px;width:200">
|
|
|
|
<p style="position:absolute;top:80px;left:200px"> Conference name </p>
|
|
<INPUT id=txtConfName style="position:absolute;top:80px;left:330px;width:200">
|
|
|
|
<INPUT type=button title="Connect to the conference" style="position:absolute;top:120px;left:260px;width:200px" value="Connect" onclick="Connect_conference()" id=buttonConnect>
|
|
<INPUT type=button disabled style="position:absolute;top:150px;left:260px;width:200px" title="Hangup" value="Hangup" onclick="conference_hangup()" id=buttonHangup>
|
|
|
|
<!-- Listed objects : TAPI(tapi3.h), DispatchMapper(tapi3.h), REND(rend.h-look for ITRendezvous) -->
|
|
|
|
<OBJECT classid=clsid:21D6D48E-A88B-11D0-83DD-00AA003CCABD
|
|
id=TAPIOBJ></OBJECT>
|
|
|
|
<OBJECT classid=clsid:F1029E5B-CB5B-11D0-8D59-00C04FD91AC0
|
|
id=REND></OBJECT>
|
|
|
|
<OBJECT classid=clsid:E9225296-C759-11d1-A02B-00C04FB6809F
|
|
id=MAPPER></OBJECT>
|
|
|
|
<SCRIPT LANGUAGE=vbscript>
|
|
window.status = "Initialization started"
|
|
call TAPIOBJ.Initialize
|
|
TAPIOBJ.EventFilter= &H1FFFF&
|
|
|
|
window.status = "Done."
|
|
|
|
</SCRIPT>
|
|
|
|
</BODY>
|
|
|
|
</HTML>
|
|
|
|
|
|
|