VCP: Trick 2 – Creating components at runtime by Hormon
Most users create templates in an old fashioned way. They take the scene, place required controls and components on template form and write some code. Although it’s nothing wrong with that (I do it all the time) sometimes I’m really frustrated. Mostly because I have to do copy and paste for the tenth time for a similar scene but with some new functionality added. I’m really lazy, so at some point I started to think of a way to construct some kind of a mechanism to do this work for me.
Creating components dynamically
Some of you may have noticed that Content Pilot vbscript implements two interesting methods which allow user to create components while the template is running: CreateVTWComponent and ConnectVTWEvent. If we look into Predefined Function List we get this usage:
CreateVTWComponent(ComponentType, Owner)
ConnectVTWEvent([_scripter], Component, EventName, ScriptEvent)
So we can say it provides us with all we need to dynamically create any supported component from our code. The only thing we should do is to write our functions. It took me just few minutes to end up with following ones:
Following function creates desired component in our template:
Function CreateChildComponent(control_type, top, left, width, height, owner)
Dim newCtrl
newCtrl = CreateVTWComponent(control_type, [_template])
newCtrl.Parent = owner
If (top > -1) Then
newCtrl.Top = top
End If
If (left > -1) Then
newCtrl.Left = left
End If
If (width > -1) Then
newCtrl.Width = width
End If
If (height > -1) Then
newCtrl.Height = height
End If
CreateChildComponent = newCtrl
End Function
Following function removes component from template:
Function DeleteComponent(ctrl_name)
Dim ctrl
ctrl = FindComponent(ctrl_name)
On Error Resume Next
If (Err = 0) Then
ctrl.Free
DeleteComponent = true
Else
DeleteComponent = false
End If
End Function
For my template I use Option Explicit statement at the top of my code. As you can see if I want to create i.e. a Button I just have to invoke first function like this:
Dim myButton
myButton = CreateChildComponent("TTWUniButton", 5, 5, 150, 40, myParentControl)
myButton.Name = "btnTest"
myButton.Caption = "Test"
where myParentControl is either [_template] or any other container control (like Panel) which already exists in template. Now let’s quickly have a click event connected to this button. The only thing we should do is use ConnectVTWEvent function. So let’s assume we have a btnTestClick(Sender) subroutine already written. Now:
dummy = ConnectVTWEvent([_scripter], myButton, "OnClick", "btnTestClick")
and we’re done :-).
How can we make our templates more flexible?
For now everything looks great but what’s the point of all of this? Well I’ll give you one example which I actually use a lot. One of the auditions which we air every day in our virtual set often changes it’s appearance. Most changes are very small – additional directors are added to the stage and I have to provide control for them. The base functionality never changes, so it’s just a copy and paste scenario. All I did (till now) was placing three buttons (Back, Previous and Continue) on template, and attached proper click events to them. But once we know how to create components dynamically we can pass this work to the template itself ( laziness is bliss :-) ).
So I talked with artist and told them that whenever they need additional director to be controlled from template they should give it the name starting with “DYN_” prefix. Next I wrote a small function which queries the scene to get the directors from stage which names start with this prefix. It looks like this:
Sub GetDynamicDirectors()
Dim cmd
cmd = SCENE_NAME & "*STAGE*DIRECTOR GET"
Dim ans, cnt
cnt = 0
Dim directors
ans = SendSingleCmd(txtComp01.UTF8Text, cmd, true)
If (InStr(ans, "ERROR") > 0) Then
MsgBox(ans)
Exit Sub
End If
ans = Mid(ans, InStr(ans, " ") + 1)
directors = Split(ans, " ")
For Each dir In directors
If (dir <> "") Then
If (InStr(dir, dynPrefix) = 1) Then
cnt = cnt + 1
If (cnt > 1) Then
dynamicDirectors = dynamicDirectors & " "
End If
dynamicDirectors = dynamicDirectors & dir
End If
End If
Next
End Sub
What it does is get the list of all directors from scene and then filter those which name doesn’t begin with “DYN_” (stored in global variable dynPrefix). The list of directors which met this criteria is stored inside dynamicDirectors variable declared as global. Last thing I did was to place the call to this function in SC_OnVariantChange event handler. Once I get the list of additional functionality directors, for each of them I created proper controls on my template.
Have a look at the final result below.

Lower panel contains additional functionality directors. This list is refreshed when user changes selected Variant.
That’s it for now. Hope you’ll find it usefull.
GHTime Code(s): 55344