FRMUSING.FRM

VERSION 5.00 
Begin VB.Form frmUsing
Caption = "Connect Using"
ClientHeight = 3195
ClientLeft = 60
ClientTop = 345
ClientWidth = 6780
LinkTopic = "Form1"
MaxButton = 0 'False
MinButton = 0 'False
ScaleHeight = 3195
ScaleWidth = 6780
StartUpPosition = 3 'Windows Default
Begin VB.CommandButton pbCancel
Caption = "Cancel"
Height = 375
Left = 5160
TabIndex = 4
Top = 1680
Width = 1335
End
Begin VB.CommandButton pbOK
Caption = "OK"
Height = 375
Left = 5160
TabIndex = 3
Top = 960
Width = 1335
End
Begin VB.ComboBox cmbTerminals
Height = 315
Left = 1200
TabIndex = 2
Top = 2040
Width = 3615
End
Begin VB.ComboBox cmbMediaTypes
Height = 315
Left = 1200
TabIndex = 1
Top = 1320
Width = 3615
End
Begin VB.ComboBox cmbAddresses
Height = 315
Left = 1200
TabIndex = 0
Top = 600
Width = 3615
End
Begin VB.Label lblTerminal
Caption = "Terminal"
Height = 255
Left = 240
TabIndex = 7
Top = 2160
Width = 855
End
Begin VB.Label lblMediaType
Caption = "Media Type"
Height = 255
Left = 240
TabIndex = 6
Top = 1440
Width = 855
End
Begin VB.Label lblAddress
Caption = "Origination Address"
Height = 375
Left = 240
TabIndex = 5
Top = 600
Width = 855
End
End
Attribute VB_Name = "frmUsing"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
'
'frmUsing.frm
'Contains implementation of dialog box that allows user to make
'a selection of tapi objects that are going to be used in making
'the call: the origination address + the mediaterminal to be
'selected on call.
'
'Create/Destroy behaviour:
'This form reads all Tapi objects when it's created, and releases
'all Tapi objects (including Tapi obj itself) when it's destroyed.
'That's why I don't want this dialog to be destroyed every time
'when user closes the window (with Ok, Cancel or control menu).
'Instead, I simply hide it when it is closed by the user (by means
'of Ok, Close or control menu), and I destroy it only when parent
'ActiveX Document terminates. (It also is created by the parent
'ActiveX Document when this one is created.)
'

Option Explicit

'Global variables
Private mnTapiRefCount As Long 'Reference count: incremented when
'InitializeTapiObjects is called
'decremented when
'ReleaseTapiObjects is called

'
'Global variables that don't change along the form's life
'Next arrays have the same dimension = number of addresses
'Each index in each array corresponds to one address
'For address "i":
' - marrobjAddresses(i) contains the address object
' - marrMediaTypesPerAddr(i) contains an arrguidMediaTypes for that address
' - marrTerminalsPerAddr(i) contains an arrobjTerminals for that address
'
Private mobjTapi As TAPI
Private mcollobjAddresses As Collection 'collection of Address objects
Private mcollMediaTypesPerAddr As Collection 'collection of collections of guidMediaTypes
Private mcollTerminalsPerAddr As Collection 'collection of collections of Terminal objects

'
'Global variables that change depending on comboboxes selection
'
Private mobjCrtAddress As Address
Private mobjCrtMediaTerminal As ITMediaTerminal

'next function populates Tapi objects and increments reference count
'Tapi objects are populated only when RefCount becomes 1
Public Sub InitializeTapiObjects()
mnTapiRefCount = mnTapiRefCount + 1

If mnTapiRefCount <> 1 Then
Exit Sub
End If

Call PopulateTapiObjects

'because Tapi objects are now known, UI can also be populated
Call PopulateCmbAddresses
End Sub

'next function releases Tapi objects and decrements reference count
'Tapi objects are released only when RefCount becomes 0
Public Sub ReleaseTapiObjects()
mnTapiRefCount = mnTapiRefCount - 1

If mnTapiRefCount <> 0 Then
Exit Sub
End If

Call DepopulateTapiObjects

End Sub

'Next function returns the selected address
'The returned Address is Nothing if there is something wrong
'with the selection
Public Property Get Address() As Address
Debug.Assert (mnTapiRefCount > 0)

Set Address = mobjCrtAddress

End Property

'next function returns an array with the selected media terminals
'The returned MediaTerminal is Nothing if there is something wrong
'with the selection
Public Property Get MediaTerminals() As Variant
Debug.Assert (mnTapiRefCount > 0)

Dim arrMediaTerminals(1 To 1) As ITMediaTerminal
Set arrMediaTerminals(1) = mobjCrtMediaTerminal

MediaTerminals = arrMediaTerminals

Set arrMediaTerminals(1) = Nothing
End Property

'When User tries to close the dialog, don't destroy the window,
'just hide it.
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
If UnloadMode = vbFormControlMenu Then
Cancel = True
Me.Hide
Debug.Print "Form_QueryUnload: unload refused. Instead, it was just hidden."
Else
Cancel = False
End If
End Sub

'When User tries to close the dialog, don't destroy the window,
'just hide it.
Private Sub pbCancel_Click()
frmUsing.Hide
End Sub

'When User tries to close the dialog, don't destroy the window,
'just hide it.
'Check selection made by user, and if it's wrong, don't let him
'close the dialog
Private Sub pbOK_Click()
'Calling ChangeSelectedObjects() will set new values
'for mobjCrtAddress and mobjCrtMediaTerminal.
'It will also display an error message if new values
'selected by the user are invalid.
If ChangeSelectedObjects() Then
frmUsing.Hide
End If
End Sub

Private Sub Form_Load()
Debug.Print ("frmUsing: Form_Load")
mnTapiRefCount = 0
End Sub

Private Sub Form_Unload(Cancel As Integer)
Debug.Print ("frmUsing: Form_Unload")

'refuse Unload if reference count <> 0, there still exists
'an ActiveXDocument that might want to use the Tapi objects
'from this form.
If mnTapiRefCount <> 0 Then
Dim strMsg
strMsg = "Form_Unload: unload refused, "
strMsg = strMsg & "Tapi reference count still not zero."
Debug.Print strMsg
Cancel = True
End If

End Sub

Private Sub PopulateTapiObjects()
On Error GoTo ErrHandle

'populate Tapi object
Set mobjTapi = New TAPI
mobjTapi.Initialize

'populate collection of Addresses
PopulateAddresses

'populate collection of MediaTypes (one collection for each address)
PopulateMediaTypes

'populate collection of Terminals (one collection for each address)
PopulateTerminals

cleanup:
Exit Sub

ErrHandle:
'On error, I Resume Next, because I want all collections to be
'created, at least as empty collections (with count = 0)

Call PrintError("PopulateTapiObjects", Err)
Resume Next
End Sub

'create a collection that contains all addresses
Private Sub PopulateAddresses()
On Error GoTo ErrHandle

Dim objcollAddresses As ITCollection
Dim nAddrCount As Long
Dim nIterator As Long

'read all addresses from Tapi
Set objcollAddresses = mobjTapi.Addresses
nAddrCount = objcollAddresses.Count

'populate collection of Addresses
Set mcollobjAddresses = New Collection
For nIterator = 1 To nAddrCount
mcollobjAddresses.Add _
Item:=objcollAddresses.Item(nIterator)
Next

cleanup:
Set objcollAddresses = Nothing
Exit Sub

ErrHandle:
'On error, I Resume Next, because I want all collections to be
'created, at least as empty collections (with count = 0)

Call PrintError("PopulateAddresses", Err)
Resume Next
End Sub

'create a collection of collections: a collection for each
'address, each collection containing all media types for that
'address
Private Sub PopulateMediaTypes()
On Error GoTo ErrHandle

Dim objcollAddresses As ITCollection
Dim nAddrCount As Long, nCrtCount As Long
Dim nAddrIndex As Long, nMTIndex As Long

Dim objcrtMediaSupport As ITMediaSupport
Dim collCrtMediaTypes As Collection 'collection of guids
Dim strCrtGuidName As String

'read all addresses from Tapi
Set objcollAddresses = mobjTapi.Addresses
nAddrCount = objcollAddresses.Count

'populate collections of MediaTypes (one collection for each address)

Set mcollMediaTypesPerAddr = New Collection
For nAddrIndex = 1 To nAddrCount
'create a collection with all media types for this address
Set collCrtMediaTypes = New Collection

Set objcrtMediaSupport = objcollAddresses.Item(nAddrIndex)
nCrtCount = 0
nCrtCount = objcrtMediaSupport.MediaTypes.Count
For nMTIndex = 1 To nCrtCount

strCrtGuidName = ""
strCrtGuidName = MTGuidToName( _
objcrtMediaSupport.MediaTypes.Item(nMTIndex))

'reject unknown "guid"s (for which I don't know the name)
If strCrtGuidName <> "" Then
collCrtMediaTypes.Add _
Item:=objcrtMediaSupport.MediaTypes.Item(nMTIndex)
End If
Next nMTIndex

'save collection in array of collections
On Error Resume Next
mcollMediaTypesPerAddr.Add Item:=collCrtMediaTypes
On Error GoTo ErrHandle

If Err.Number <> 0 Then
Call PrintError("PopulateMediaTypes: adding collections", Err)
Err.Clear

'this collection is useless, release it, but first
'remove its items
nCrtCount = 0
nCrtCount = collCrtMediaTypes.Count
For nMTIndex = 1 To nCrtCount
'collections are reindexed automatically,
'so remove the 1st element on each iteration
collCrtMediaTypes.Remove 1
Next
End If

'Cleanup "crt" variables (that change in each iteration)
'Note: don't remove items from CrtCollection, because
'the corresponding items from "collection of collections"
'will also be removed!
Set collCrtMediaTypes = Nothing
Set objcrtMediaSupport = Nothing
Next nAddrIndex

cleanup:
Set objcollAddresses = Nothing
Exit Sub

ErrHandle:
'On error, I Resume Next, because I want all collections to be
'created, at least as empty collections (with count = 0)

Call PrintError("PopulateMediaTypes", Err)
Resume Next
End Sub

'create a collection of collections: a collection for each
'address, each collection containing all terminals for that
'address: static + dynamic + the Null terminal
Private Sub PopulateTerminals()
On Error GoTo ErrHandle

Dim objcollAddresses As ITCollection
Dim nAddrCount As Long, nCrtCount As Long
Dim nAddrIndex As Long, nTerminalIndex As Long, nIndex As Long

Dim objcrtTerminalSupport As ITTerminalSupport
Dim collCrtTerminals As Collection 'collection of Terminal objects
Dim collCrtStaticTerminals As ITCollection
Dim objCrtTerminal As Terminal

'read all addresses from Tapi
Set objcollAddresses = mobjTapi.Addresses
nAddrCount = objcollAddresses.Count

'populate collections of Terminals (one collection for each address)

Set mcollTerminalsPerAddr = New Collection
For nAddrIndex = 1 To nAddrCount
'create a collection with all terminals for this address:
'static + dynamic + the Null terminal
Set collCrtTerminals = New Collection

Set objcrtTerminalSupport = objcollAddresses.Item(nAddrIndex)

'add static terminals
nCrtCount = 0
Set collCrtStaticTerminals = objcrtTerminalSupport.StaticTerminals
nCrtCount = collCrtStaticTerminals.Count
For nTerminalIndex = 1 To nCrtCount

Set objCrtTerminal = collCrtStaticTerminals.Item(nTerminalIndex)

collCrtTerminals.Add Item:=objCrtTerminal

Set objCrtTerminal = Nothing

Next nTerminalIndex
Set collCrtStaticTerminals = Nothing

'add dynamic terminals: create 1 terminal for each dynamic class
nCrtCount = 0
nCrtCount = objcrtTerminalSupport.DynamicTerminalClasses.Count
For nIndex = 1 To nCrtCount

Set objCrtTerminal = _
objcrtTerminalSupport.CreateTerminal( _
objcrtTerminalSupport.DynamicTerminalClasses.Item(nIndex))

collCrtTerminals.Add Item:=objCrtTerminal

Set objCrtTerminal = Nothing

Next nIndex

'add the Null Terminal
collCrtTerminals.Add Item:=Nothing

'save collection in array of collections
On Error Resume Next
mcollTerminalsPerAddr.Add Item:=collCrtTerminals
On Error GoTo ErrHandle

If Err.Number <> 0 Then
Call PrintError("PopulateTerminals: adding collections", Err)
Err.Clear

'this collection is useless, release it, but first
'remove its items
nCrtCount = 0
nCrtCount = collCrtTerminals.Count
For nTerminalIndex = 1 To nCrtCount
'collections are reindexed automatically,
'so remove the 1st element on each iteration
collCrtTerminals.Remove 1
Next
End If

'Cleanup "crt" variables (that change in each iteration)
'Note: don't remove items from CrtCollection, because
'the corresponding items from "collection of collections"
'will also be removed!
Set collCrtTerminals = Nothing
Set objcrtTerminalSupport = Nothing
Next nAddrIndex

cleanup:
Set objcollAddresses = Nothing
Exit Sub

ErrHandle:
'On error, I Resume Next, because I want all collections to be
'created, at least as empty collections (with count = 0)

Call PrintError("PopulateTerminals", Err)
Resume Next
End Sub

Private Sub DepopulateTapiObjects()
On Error GoTo ErrHandle

Dim collCrt As Collection
Dim nIterator As Long, nIndex As Long
Dim nCount As Long, nCrtCount As Long

'depopulate collection of Terminals (one collection for each address)
nCount = 0
nCount = mcollTerminalsPerAddr.Count
For nIterator = 1 To nCount
'collections are reindexed automatically,
'so remove the 1st element on each iteration

Set collCrt = mcollTerminalsPerAddr.Item(1)
nCrtCount = 0
nCrtCount = collCrt.Count
For nIndex = 1 To nCrtCount
collCrt.Remove 1
Next nIndex
Set collCrt = Nothing

mcollTerminalsPerAddr.Remove 1
Next nIterator
Set mcollTerminalsPerAddr = Nothing

'depopulate collection of MediaTypes (one collection for each address)
nCount = 0
nCount = mcollMediaTypesPerAddr.Count
For nIterator = 1 To nCount
'collections are reindexed automatically,
'so remove the 1st element on each iteration

Set collCrt = mcollMediaTypesPerAddr.Item(1)
nCrtCount = 0
nCrtCount = collCrt.Count
For nIndex = 1 To nCrtCount
collCrt.Remove 1
Next nIndex
Set collCrt = Nothing

mcollMediaTypesPerAddr.Remove 1
Next nIterator
Set mcollMediaTypesPerAddr = Nothing

'depopulate collection of Addresses
nCount = 0
nCount = mcollobjAddresses.Count
For nIterator = 1 To nCount
'collections are reindexed automatically,
'so remove the 1st element on each iteration

mcollobjAddresses.Remove 1
Next nIterator
Set mcollobjAddresses = Nothing

'depopulate Tapi object
If Not (mobjTapi Is Nothing) Then
mobjTapi.Shutdown
End If
Set mobjTapi = Nothing

cleanup:
Exit Sub

ErrHandle:
'On error, I Resume Next, because I want all release actions
'to be performed

Call PrintError("DepopulateTapiObjects", Err)
Resume Next
End Sub

'This function is called only once: after dialog is created,
'when it is asked to load the Tapi objects.
'When this function is called, the combo cmbAddresses is
'populated, and the 1st item is selected; this determines
'automatical populate for dependent comboboxes cmbMediaTypes
'and cmbTerminals, and automatical selection of their 1st
'item.
Private Sub PopulateCmbAddresses()
On Error GoTo ErrHandle

Dim nIterator As Long, nCount As Long

'don't need to clean combo of previous contents,
'because this function is called only once
'cmbAddresses.Clear

'populate combobox with names of all addresses from mcollobjAddresses
'attach to each combo item the index of the corresponding address
nCount = 0
nCount = mcollobjAddresses.Count
For nIterator = 1 To nCount
On Error Resume Next
cmbAddresses.AddItem (mcollobjAddresses.Item(nIterator).AddressName)
On Error GoTo ErrHandle
If Err.Number <> 0 Then
'there was an error therefore don't call NewIndex
Call PrintError("PopulateCmbAddresses", Err)
Err.Clear
Else
cmbAddresses.ItemData(cmbAddresses.NewIndex) = nIterator
End If
Next nIterator

'set selection on 1st item
If cmbAddresses.ListCount > 0 Then
cmbAddresses.ListIndex = 0
'This automatically called cmbAddresses_Click

End If

cleanup:
Exit Sub

ErrHandle:
'I resume next, because I want to add as many items as possible

Call PrintError("PopulateCmbAddresses", Err)
Resume Next
End Sub

'Note: cmbMediaTypes depends on cmbAddresses: it is always
'populated only with those media types that correspond
'to the Address currently selected in cmbAddresses
'This is why each time the selection changes in cmbAddresses
'this combo is repopulated. This means that this function is
'called each time when another address is selected; thus it must
'first clear the combo's contents before refilling it.
Private Sub PopulateCmbMediaTypes(nAddrIndex As Long)
On Error GoTo ErrHandle

Dim collguidMediaTypes As Collection
Dim nIterator As Long, nCount As Long

'clean combo of all previous contents, because
'this might be a repopulating action
cmbMediaTypes.Clear

'pick up the media types corresponding to
'the address received as parameter
Set collguidMediaTypes = mcollMediaTypesPerAddr.Item(nAddrIndex)

'populate combobox with the names corresponding to all guids
'from this particular collection of MediaTypes
'attach to each combo item the index of the corresponding media type
nCount = 0
nCount = collguidMediaTypes.Count
For nIterator = 1 To nCount
On Error Resume Next
cmbMediaTypes.AddItem ( _
MTGuidToName(collguidMediaTypes.Item(nIterator)))
On Error GoTo ErrHandle
If Err.Number <> 0 Then
'there was an error therefore don't call NewIndex
Call PrintError("PopulateCmbMediaTypes", Err)
Err.Clear
Else
cmbMediaTypes.ItemData(cmbMediaTypes.NewIndex) = nIterator
End If
Next nIterator

'set selection on 1st item
If cmbMediaTypes.ListCount > 0 Then
cmbMediaTypes.ListIndex = 0
'this automatically called cmbMediaTypes_Click
End If

cleanup:
Set collguidMediaTypes = Nothing
Exit Sub

ErrHandle:
'I resume next, because I want to add as many items as possible

Call PrintError("PopulateCmbMediaTypes", Err)
Resume Next
End Sub

'Note: cmbTerminals depends on cmbAddresses: it is always
'populated only with those terminals that correspond
'to the Address currently selected in cmbAddresses
'This is why each time the selection changes in cmbAddresses
'this combo is repopulated. This means that this function is
'called each time another address is selected; thus it must
'first clear the combo's contents before refilling it.
Private Sub PopulateCmbTerminals(nAddrIndex As Long)
On Error GoTo ErrHandle

Dim collobjTerminals As Collection
Dim nIterator As Long, nCount As Long
Dim objCrtTerminal As Terminal

'clean combo of all previous contents, because
'this might be a repopulating action
cmbTerminals.Clear

'pick up the terminals corresponding to
'the address received as parameter
Set collobjTerminals = mcollTerminalsPerAddr.Item(nAddrIndex)

'populate combobox with the names corresponding to all terminals
'from this particular collection of Terminals
'attach to each combo item the index of the corresponding terminal
nCount = 0
nCount = collobjTerminals.Count
For nIterator = 1 To nCount

'special case: the Null terminal
'(objcrtTerminal = Nothing but Err.Number=0)

On Error Resume Next
Set objCrtTerminal = collobjTerminals.Item(nIterator)
On Error GoTo ErrHandle

If Err.Number <> 0 Then
'there was an error when retrieving item
'therefore there's no item to add
Call PrintError("PopulateCmbTerminals", Err)
Err.Clear
Else
'there was success when retrieving item
'therefore there is a item to add
On Error Resume Next
cmbTerminals.AddItem (TerminalToCompleteName(objCrtTerminal))
On Error GoTo ErrHandle
If Err.Number <> 0 Then
'there was an error therefore don't call NewIndex
Call PrintError("PopulateCmbTerminals", Err)
Err.Clear
Else
cmbTerminals.ItemData(cmbTerminals.NewIndex) = nIterator
End If
End If

Set objCrtTerminal = Nothing
Next nIterator

'set selection on 1st item
If cmbTerminals.ListCount > 0 Then
cmbTerminals.ListIndex = 0
'this automatically called cmbTerminals_Click
End If

cleanup:
Set collobjTerminals = Nothing
Exit Sub

ErrHandle:
'I resume next, because I want to add as many items as possible

Call PrintError("PopulateCmbTerminals", Err)
Resume Next
End Sub

Private Sub cmbAddresses_Click()
On Error GoTo ErrHandle

Dim nSelectedAddrIndex As Long

'each time the address changes, repopulate
'the dependent comboboxes (cmbMediaTypes & cmbTerminals)

'retrieve the index of the selected address
nSelectedAddrIndex = cmbAddresses.ItemData(cmbAddresses.ListIndex)

PopulateCmbMediaTypes (nSelectedAddrIndex)
PopulateCmbTerminals (nSelectedAddrIndex)

cleanup:
Exit Sub

ErrHandle:
'I resume next, because I want to populate
'as many controls (comboboxes) as possible

Call PrintError("cmbAddresses_Click", Err)
Resume Next
End Sub

'ChangeSelectedObjects
'Returns:
'True if valid new values were selected by the user, False otherwise
'Action:
'Each time when OK is pressed, it means that the user
'decided for a new OriginationAddress and MediaTerminal;
'therefore check if the comboboxes have valid values
'then set new values in mobjCrtAddress and mobjCrtMediaTerminal.
'If new values are not valid (they correspond to Null objects)
'leave the old values unchanged.
Private Function ChangeSelectedObjects() As Boolean
On Error GoTo ErrHandle

ChangeSelectedObjects = False

Dim nSelectedAddrIndex As Long
Dim nSelectedMTIndex As Long
Dim nSelectedTerminalIndex As Long

Dim guidMediaType As String
Dim objTerminal As Terminal

Dim objNewAddress As Address
Dim objNewMediaTerminal As ITMediaTerminal

Dim strMsg As String

'pick up the address object that has the name selected in cmbAddresses
nSelectedAddrIndex = cmbAddresses.ItemData(cmbAddresses.ListIndex)
Set objNewAddress = mcollobjAddresses.Item(nSelectedAddrIndex)

'pick up the media type guid that has the name selected in cmbMediaTypes
nSelectedMTIndex = cmbMediaTypes.ItemData(cmbMediaTypes.ListIndex)
guidMediaType = mcollMediaTypesPerAddr.Item( _
nSelectedAddrIndex).Item(nSelectedMTIndex)

'pick up the terminal object that has the name selected in cmbTerminals
nSelectedTerminalIndex = cmbTerminals.ItemData(cmbTerminals.ListIndex)
Set objTerminal = mcollTerminalsPerAddr.Item( _
nSelectedAddrIndex).Item(nSelectedTerminalIndex)

Set objNewMediaTerminal = mobjTapi.CreateMediaTerminal( _
guidMediaType, objTerminal)

If (Not (objNewAddress Is Nothing)) And _
(Not (objNewMediaTerminal Is Nothing)) Then

'release old references
Set mobjCrtAddress = Nothing
Set mobjCrtMediaTerminal = Nothing

'set new values
Set mobjCrtAddress = objNewAddress
Set mobjCrtMediaTerminal = objNewMediaTerminal

'set True in return value
ChangeSelectedObjects = True
Else
If objNewAddress Is Nothing Then
strMsg = "A valid origination address must be selected!"
End If
If objNewMediaTerminal Is Nothing Then
strMsg = "A valid pair Media+Terminal must be selected!"
End If
Call MessageBox(0, strMsg, "Connect Using - Error", MB_OK Or MB_USERICON)
End If

cleanup:
Set objNewAddress = Nothing
Set objNewMediaTerminal = Nothing

Exit Function

ErrHandle:
'I resume Next, because I want to execute the
'same code in case of both types of failures:
'code failure OR user failure (wrong selection)
'In both cases, the same MsgBox is displayed,
'explaining which object could not be created
Call PrintError("ChangeSelectedObjects", Err)
Resume Next
End Function