Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

runtime control creation 3

Status
Not open for further replies.

nhc

Programmer
Apr 3, 2000
10
AU
Hi,<br><br>I am making a control that will (not always) have children that are of the same control type. It is like a tree structure basically. I cannot create the same control within itself at design time, as I am not allowed (for good reasons).<br><br>So my question is, Can I create an instance of a control at runtime?<br>Or, Is there any other way I could achieve the same effect?<br><br>If anyone needs more information I would be happy to provide it.<br><br>Thanks,<br><br>Nick.<br><A HREF="mailto:nhc@operamail.com">nhc@operamail.com</A> <p>Nicholas Clark<br><a href=mailto:nhc@operamail.com>nhc@operamail.com</a><br><a href= > </a><br>
 
&nbsp;&nbsp;Yes you can. For example:<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Dim button as CommandButton<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set button as Command1 <br><br>&nbsp;&nbsp;&nbsp;This will create a reference to the Command1 button on the form. You can Create multiple instance of Command1 by using a control array. I.E. Command1(0), Command1(1), Command1(2).<br><br>&nbsp;&nbsp;&nbsp;&nbsp;Simply paste a copy of a control that you already have on the from and VB will ask you if you would like to make the control an Array. Simply answer Yes to initiate the array of the specific control. <br><br>&nbsp;Remember to access the control array in code as follows:<br><br>&nbsp;&nbsp;Public Sub Command1_Click(Index as Integer)<br>&nbsp;&nbsp;.<br>&nbsp;&nbsp;.<br>&nbsp;&nbsp;End Sub<br><br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Hope this helps<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;John Stephens<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 
Thanks, but there is a problem in that I cannot paste the control into my usercontrol as they are the same control. VB will not allow me as this would create an infinite loop. So I need to create the first instance of the control at runtime.<br><br>Therefore a control array will not work as it requires the first instance to be present at design time.<br><br>I think I may have reached the limits of VB here. Which is a pain as I don't have the time to develop this control in VC or the knowledge. <p>Nicholas Clark<br><a href=mailto:nhc@operamail.com>nhc@operamail.com</a><br><a href= > </a><br>
 
'Maybe the following stuff will helpHOWTO: Dynamically Add Controls to a Form with Visual Basic 6.0<br><br>SUMMARY<br>Visual Basic 6.0 allows you to dynamically add control to a form at run- time using the new Add method of the Controls collection. <br><br>MORE INFORMATION<br>The following example dynamically adds two intrinsic and one ActiveX control to an application at run-time. The sample shows how to program the events of a dynamically added control. If you are dynamically adding a control that is not referenced in the project, you may need to add the control's License key to the Licenses collection. For more information on the Licenses collection, please see the REFERENCES section of this article. <br><br>When you reference properties of the dynamically-added control, you must use the Object keyword to access the properties of the control. If you don't use the Object keyword, you will only be able to access the extender properties of the control. <br><br>When an ActiveX control is dynamically added using the VBControlExtender object and WithEvents in the declare statement, you will need to use the ObjectEvent method to code all of the control's events. If you declare an intrinsic control WithEvents, you will get all the standard event methods for the type of control you declared. You can see this by adding the following declare statement in the Code window and then checking the Events dropdown for the declared variable in the Code window: <br><br><br>Dim WithEvents cmdMyCommand as VB.CommandButton<br><br>Steps to Create Sample Project<br><br>Create a new Standard EXE project. Form1 is created by default. <br><br>Add the following code to the code window of Form1: <br><br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Option Explicit<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;' If you are adding an ActiveX control at run-time that is<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;' not referenced in your project, you need to declare it<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;' as VBControlExtender.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Dim WithEvents ctlDynamic As VBControlExtender<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Dim WithEvents ctlText As VB.TextBox<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Dim WithEvents ctlCommand As VB.CommandButton<br><br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Private Sub ctlCommand_Click()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ctlText.Text = &quot;You Clicked the Command button&quot;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;End Sub<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Private Sub ctlDynamic_ObjectEvent(Info As EventInfo)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;' test for the click event of the TreeView<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;If Info.Name = &quot;Click&quot; Then<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ctlText.Text = &quot;You clicked &quot; _<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;& ctlDynamic.object.selecteditem.Text<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;End If<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;End Sub<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Private Sub Form_Load()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Dim i As Integer<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;' Add the license for the treeview to the license collection.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;' If the license is already in the collection you will get<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;' the run-time error number 732.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Licenses.Add &quot;MSComctlLib.TreeCtrl&quot;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;' Dynamically add a TreeView control to the form.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;' If you want the control to be added to a different<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;' container such as a Frame or PictureBox, you use the third<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;' parameter of the Controls.Add to specify the container.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set ctlDynamic = Controls.Add(&quot;MSComctlLib.TreeCtrl&quot;, _<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;myctl&quot;, Form1)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;' set the location and size of the control.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ctlDynamic.Move 1, 1, 2500, 3500<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;' Add some nodes to the control.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;For i = 1 To 10<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ctlDynamic.object.nodes.Add Key:=&quot;Test&quot; & Str(i), Text:=&quot;Test&quot; _<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;& Str(i)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ctlDynamic.object.nodes.Add Relative:=&quot;Test&quot; & Str(i), _<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Relationship:=4, Text:=&quot;TestChild&quot; & Str(i)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Next i<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;' Make the control visible.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ctlDynamic.Visible = True<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;' add a textbox<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set ctlText = Controls.Add(&quot;VB.TextBox&quot;, &quot;ctlText1&quot;, Form1)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;' Set the location and size of the textbox<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ctlText.Move (ctlDynamic.Left + ctlDynamic.Width + 50), _<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1, 2500, 100<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;' Change the backcolor.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ctlText.BackColor = vbYellow<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;' Make it visible<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ctlText.Visible = True<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;' Add a CommandButton.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set ctlCommand = Controls.Add(&quot;VB.CommandButton&quot;, _<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;ctlCommand1&quot;, Form1)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;' Set the location and size of the CommandButton.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ctlCommand.Move (ctlDynamic.Left + ctlDynamic.Width + 50), _<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ctlText.Height + 50, 1500, 500<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;' Set the caption<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ctlCommand.Caption = &quot;Click Me&quot;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;' Make it visible<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ctlCommand.Visible = True<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;End Sub<br><br><br>Save and run the project. Try clicking the CommandButton and on different Nodes in the TreeView. The TextBox will show what you click. <br>&nbsp;<br><br>
 
It sounds very promising. I'll try it out.<br><br>Thanks.<br><br>Nick. <p>Nicholas Clark<br><a href=mailto:nhc@operamail.com>nhc@operamail.com</a><br><a href= > </a><br>
 
Thanks it work beautifully except now I need to make an array of such objects as my control may have multiple children.<br><br>&nbsp;&nbsp;&nbsp;&nbsp;set ctlChild = controls.add(&quot;myControl&quot;, &quot;myctl&quot;, frame1<br><br>This works fine.<br><br>&nbsp;&nbsp;&nbsp;&nbsp;colChildren.add ctlchild<br><br>But if I add it to a collection I have a problem.<br><br>&nbsp;&nbsp;&nbsp;&nbsp;ctlchild_objectevent(info as eventinfo)<br><br>This no longer works except for the most recently added child and collections don't support withevents.<br><br>Does anyone know what I can do?<br><br>The answer is probably quite simple but I haven't a clue.<br><br>Thanks. <p>Nicholas Clark<br><a href=mailto:nhc@operamail.com>nhc@operamail.com</a><br><a href= > </a><br>
 
A have a question along these lines. Does anyone know if it is possible to dynamically create a form. I was hoping it would be as simple as:
[tt]
Dim WithEvents ctlForm As VB.Form

Set ctlForm = Controls.Add(&quot;VB.Form&quot;, &quot;frmDetails&quot;)
ctlForm.Show vbModal
[/tt]
But it appears that isn't the case. ANy thoughts would be appreciated. Craig, mailto:sander@cogeco.ca

&quot;Procrastination is the art of keeping up with yesterday.&quot;

I hope my post was helpful!!!
 
The easiest way to do this, Craig, is to add a single blan form to your project. For the sake of the example call it TemplateForm.

Then you can do the following:
[tt]
Dim WithEvents ctlForm As VB.Form

Set ctlForm = New TemplateForm
ctlForm.Caption = &quot;Details&quot;
ctlForm.Show vbModal
[/tt]
The trick is to remember that the forms you create at design time are actually just classes with a visual interface
 
I've gotten around this as I only need 1 extra form. So I created a blank form, but now my problem is I can't add controld to that form from the otehr form. This si the sample Code that is in Form1
[tt]
Dim fld As ADODB.Field
Dim Index As Integer

Load Form2
Form2.Show
Form2.Caption = &quot;Add User&quot;

For Each fld In rs.Fields
Index = Index + 1
Set ctlLabel = Controls.Add(&quot;VB.Label&quot;, &quot;lbl&quot; & fld.Name, Form2)
Set ctlText = Controls.Add(&quot;VB.TextBox&quot;, &quot;txt&quot; & fld.Name, Form2)

Next fld
[/tt]

This code Fails telling me
&quot;Run-time error '721':
'Form2' is not a valid container
Craig, mailto:sander@cogeco.ca

&quot;Procrastination is the art of keeping up with yesterday.&quot;

I hope my post was helpful!!!
 
I found the solution to this. It seems I can't add the controls from Form1 to Form2. I put the Code into Form2 and it works.

Now I have 1 more problem.

How can I add multiple Command Buttons, and have the code recognize the events on each one. Or can I add them with an index?
Craig, mailto:sander@cogeco.ca

&quot;Procrastination is the art of keeping up with yesterday.&quot;

I hope my post was helpful!!!
 
The easiest way to do this is to add one command button to your form at design time. Call it let's say Cmd. Set its Index property to 0. Set other properties as you wish( left,width,top,height,etc...). If you do not want your button to be visible when form loads, set its &quot;Visible&quot; property to false. Thus you have effectively created control array with one element. Then at run time you can do the following:
Load Cmd(1)
Load Cmd(2)
and so on.

This way you create members of control array at run time.You then access properties and methods of these controls by specifying Index, i. e. Cmd(0).Caption, Cmd(1).Left and so on. The same way as if you have created this Control array at design time. As you keep loading control array members, do not forget to adjust their properties. By default they will inherit properties of control array member created at design time. However, &quot;Visible&quot; property of newly created controls is always false. Do not forget to set it to true. You can also do Unload Cmd(1), Unload Cmd(2) and so on, to unload members of control array at run time. This way you release memory as opposed to setting their &quot;Visible&quot; property to False. You cannot unload control array members that you created at design time.
Naturally, since these controls are members of control array, they will share all events. All events will have variable Index as their first parameter.

Private sub Cmd_Click(Index as Integer)
end Sub


Naturally when you click on Cmd(0) Index=0, cmd(1) Index=1 and so on. If you do not want to add Command button to your form at design time you might have a problem.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top