Click to See Complete Forum and Search --> : Adding controls at runtime


cloud311
October 7th, 2001, 09:25 AM
How do I go about adding a control to my program at runtime? Like if I wanted to add a command button to my form through code. I remember reading about it somewhere, but I can't remember how it was done. Any help appreciated.

urs
October 7th, 2001, 11:21 AM
dim cmd as commandbutton
set cmd=Controls.add("vb.commandbutton","Name")
cmd.visible=true

then u can set its left & top property

cloud311
October 7th, 2001, 01:12 PM
The code keeps giving me "Object doesn't support this property or method" errors. Do you know what's happening?

ramayansunil
October 8th, 2001, 01:10 AM
Hi,
First place the control(ie.,command button). And create a control array for that by changing the property of Index to 0.
Now make the control's visible property to false. In the run time if u want to create the control give the following code:

Load Command1(i)
Command1(i).Visible = True
Command1(i).Top = Command1(i-1).Top + 100

Where i is the static running variable.it starts from 1 on wards.
Have a nice time.
sunil

Cakkie
October 8th, 2001, 01:19 AM
In VB you cannot add controls to a form this way, you MUST use a control array. This involves placing one control on the form at design time, set it's index property to 0. Afterwards, you can create it in code by using the Load sētatement.

Tom Cannaerts
slisse@planetinternet.be

Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning -- Rich Cook

MHK
October 8th, 2001, 03:01 AM
You can load control at runtime by using control array. Say u want to load a TextBox at runtime, you need to have at least one textbox at your form with a index value. Say its name is Text1 and index value is 0. In that case you can try out with following code:

load text1(text1.ubound+1)
text(text1.ubound).move 70,80
text1(text1.ubound+1).visible = true

John G Duffy
October 8th, 2001, 08:10 AM
Here is a method similar to urs' post however the .Controls.Add works only for VB 6.0.
Start a new project. Paste this code into the general declarations section of the form. Run it and you will see a command button appear. The only seriour flaws in this approach is you can not create control arrays in this fashion nor can you dynamically create control names. If you have need to create many controls at run time, there are samples available using classes or callbacks on Planet-Source-Code.com or similar code repository sites. I also have a couple of examples of creating "pseudo" control arrays but they also only work with VB 6.0.

option Explicit

' Declare object variable as CommandButton.
private withevents cmdObject as CommandButton

private Sub Form_Load()
set cmdObject = frmCreate.Controls.Add("VB.CommandButton", "cmdOne")
cmdObject.Visible = true
cmdObject.Caption = "Dynamic Command Button"
cmdObject.Move 1000, 1000, 1000, 1000
End Sub

private Sub cmdObject_Click()
print "This is a dynamically added control"
End Sub

private Sub Form_Unload(Cancel as Integer)
' get rid of created control
me.Controls.Remove cmdObject

End Sub




John G

urs
October 8th, 2001, 11:08 AM
Private Sub Command1_Click()
Dim cmd As CommandButton
Set cmd = Controls.Add("vb.commandbutton", "saf")
cmd.Visible = True
End Sub

i dont know this code is working perfect for me
and i have even suggested to 1 more guy and he rated me 10 points so i think it is working fine with him as well
u search it

cloud311
October 8th, 2001, 02:39 PM
Thanks a bunch, your example worked for me.

Harold2202
October 9th, 2001, 04:27 AM
This works for one button. I've tried to find the answer for the control arrays on PlanetSourceCode but could not find it. Could you please give me the code for the "pseudo: control arrays

John G Duffy
October 9th, 2001, 02:32 PM
Way back on 6/4/2001, a post on this forum received a reply from CImpereli with a nice sample but the post is for some reaason no longer available. Here is Cimpereli's reply

'Of course, this is not as impressive as his example, but that is a lot
'of code, so if you want it, mail me an E-mail where to send a zipped
'txt.
'-----------------------------------------------
'one form
'no controls on it
'-----------------------------------------------
'Two classes:
'ControlItem
'ControlItems
'(code follows)
'-----------------------------------------------
'Form1 code

option Explicit

' the collection of controls added dynamically
Dim withevents ControlItems as ControlItems

private Sub Form_Click()
LoadControls
End Sub

private Sub Form_Resize()
' resize all controls to ensure that they fit in the form
Dim ctrl as Control
Dim ctrlItem as ControlItem

on error resume next

for Each ctrlItem In ControlItems
set ctrl = ctrlItem.Control
ctrl.Width = ctrlItem.Properties("Width")
If ctrl.Left + ctrl.Width > ScaleWidth then
ctrl.Width = ScaleWidth - ctrl.Left
End If
next
End Sub

Sub LoadControls()
'Dim index as Long
Dim intX as Integer
Dim ctrl as Control
Dim ctrlItem as ControlItem
Dim ctrlType as string
Dim Properties as Collection
Dim CustomProperties as Collection
Dim top as Single
Dim propItem as Variant
Dim items() as string


' first, remove all controls added dynamically
on error resume next
' don't try a forward or a for Each loop
for intX = Controls.Count - 1 to 0 step -1
Controls.Remove intX
next
on error GoTo 0

' start with a fresh ControlItems collection
set ControlItems = new ControlItems

' initial value for Top property
top = 100

' add controls corresponding to fields
' this demo program only supports a few field types
for intX = 0 to 10
ctrlType = ""
set Properties = new Collection
set CustomProperties = new Collection
ctrlType = "Vb.Commandbutton"
Properties.Add "Caption=" & "Command" & intX

' now create the control
set ctrl = Controls.Add(ctrlType, "CommandButton" & intX)
ctrl.Move 1900, top, 2000, 315

' set its other properties
for Each propItem In Properties
' split property name and value
items() = Split(propItem, "=")
CallByName ctrl, items(0), VbLet, items(1)
next

ctrl.Visible = true

' add this control to the ControlItems collection
' this will enable to receive events from it
set ctrlItem = ControlItems.Add(ctrl)

' move the actual width into the Custom Width property
' this is used in the Form_Resize event
ctrlItem.Properties.Add ctrl.Width, "Width"

' set its other custom properties
for Each propItem In CustomProperties
' split property name and value
items() = Split(propItem, "=")
ctrlItem.Properties.Add items(1), items(0)
next

' increment top
top = top + ctrl.Height + 80

next

' force a Form_Resize event, to resize longer controls
Call Form_Resize

End Sub

' one control added dynamically is asking for validation
' Item.Control is a reference to the control
' Item.GetProperty(propname) returns a custom property

private Sub ControlItems_Click(Item as ControlItem)
MsgBox "You clicked on " & Item.Control.Caption
End Sub

'-------------------------------------------------------------
'ControlItems Class code

option Explicit

' this class raises an event in the parent form
Event Click(Item as ControlItem)

' The private collection used to hold the real data
private m_ControlItems as new Collection

' Add a new ControlItem item to the collection

public Function Add(ctrl as Control) as ControlItem
Dim newItem as new ControlItem
newItem.Init ctrl, me

' add to the private collection
m_ControlItems.Add newItem
' return the new item to the caller
set Add = newItem
End Function

' Remove an item from the collection

public Sub Remove(index as Variant)
m_ControlItems.Remove index
End Sub

' Return a ControlItem item from the collection

Function Item(index as Variant) as ControlItem
set Item = m_ControlItems.Item(index)
End Function

' Return the number of items in the collection

property get Count() as Long
Count = m_ControlItems.Count
End property

' Remove all items from the collection

public Sub Clear()
set m_ControlItems = new Collection
End Sub

' Implement support for enumeration (for Each)

Function NewEnum() as IUnknown
' delegate to the private collection
set NewEnum = m_ControlItems.[_NewEnum]
End Function

'---------------------------------------------
' friend Subs called when a ControlItem
' receives an event from Visual Basic
'---------------------------------------------

friend Sub Notify_Click(Item as ControlItem)
' raise a Validate event in the parent form
RaiseEvent Click(Item)
End Sub

'-------------------------------------------------------------
'ControlItem class Code:

option Explicit

' a public collection for additional properties
public Properties as new Collection
' the object being monitored - this is same as "Control"
' but it also receives events
public withevents Control as CommandButton

' the parent ControlItems object
Dim m_Parent as ControlItems

' initialize properties

Sub Init(ctrl as CommandButton, parent as ControlItems)
set Control = ctrl
set m_Parent = parent
End Sub

' retrieve a single property

Function GetProperty(PropName as string, optional DefaultValue as Variant) as Variant
on error resume next
GetProperty = Properties(PropName)
If Err And Not IsMissing(DefaultValue) then
GetProperty = DefaultValue
End If
End Function

' the control has raised a Validate event

private Sub Control_Click()
' notify it to the parent ControlItems class
m_Parent.Notify_Click me
End Sub


John G

Cimperiali
October 10th, 2001, 03:51 AM
'CodeGuru seems to move previous old post somewhere else.
'You can stiil reach them with the "search" option if you know
'the title (ie: I entered "example", then looked to find this one)
'Original code comes from Francesco Balena (www.vb2themax.com), who wrote an
'illuminant book on Vb6 programming.
'I adapted his code to be used with commandbuttons collection, but you may use
'quite any control

http://www.codeguru.com/forum/showthread.php?t=20445&highlight=Francesco+Balena


Special thanks to Lothar "the Great" Haensler, Tom Archer, Chris Eastwood, TCartwright, Bruno Paris, Dr_Michael
and all the other wonderful people who made and make Codeguru a great place.
Come back soon, you Gurus.

The Rater

Harold2202
October 10th, 2001, 04:09 AM
Thanks I'm going to try this

John G Duffy
October 10th, 2001, 07:38 AM
When that post originally appeared, I copied it to my hard disk. I still have it. Attempting to use "Search" produced no results. I finally scrolled all the way back to the date on the original post I saved and it is not there.
The original post was titled "collection of class objects" posted by Jean-Guy2000 on 06/04/01 at 12:08pm. Your response is threee or four replies into it. Using the manual scroll method to attempt to locate it shows no such post on that date. Don't know where it went.

John G

karthikvr
March 17th, 2002, 11:42 PM
i want to use dim withevents controlitems as controlitem,what reference should i add to use this.please reply

Andyroo
August 15th, 2002, 09:36 AM
I think the easiest way to add control at runtime is to use VBCOntrolExtender:

Definition
Private WithEvents m_ctl As VBControlExtender

Creation
Set m_ctl = Controls.Add(function_to_get_the_DLL_name (), "m_ctl")

Catch the Event
Private Sub m_ctl_ObjectEvent(Info As EventInfo)

Removal
Controls.Remove ("m_ctl")



Andyroo

Squezy
August 11th, 2004, 06:29 PM
How can you unload a control that was added like this:


load text1(text1.ubound+1)
text(text1.ubound).move 70,80
text1(text1.ubound+1).visible = true


OR, is it possible to set function using the way:

Dim cmd As CommandButton
Set cmd = Controls.Add("vb.commandbutton", "saf")
cmd.Visible = True

I know this thread is old, but please.....

Thanks

urs
August 12th, 2004, 07:59 AM
If your are using Control.Add to add controls at runtime you can use Control.Remove cmd to remove them.

Twodogs
August 12th, 2004, 04:52 PM
Here's an old post of mine where I add control arrays dynamically.
Dynamically add control arrays (http://www.codeguru.com/forum/showthread.php?t=31329&highlight=dynamically+add+controls)

hspc
August 13th, 2004, 03:34 AM
also this can be useful :
http://www.codeguru.com/forum/showthread.php?t=293562

also this :
http://www.codeguru.com/forum/showthread.php?t=293537
to add usercontrols as well

cappy2112
October 5th, 2005, 06:47 PM
I think the easiest way to add control at runtime is to use VBCOntrolExtender:

Definition
Private WithEvents m_ctl As VBControlExtender

Creation
Set m_ctl = Controls.Add(function_to_get_the_DLL_name (), "m_ctl")

Catch the Event
Private Sub m_ctl_ObjectEvent(Info As EventInfo)

Removal
Controls.Remove ("m_ctl")



Andyroo


What DLL name are you referring to in function_to_get_the_DLL_name () ?