Celebrate National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Dynamic Control Creation VB5

Posted on 2000-03-10
21
Medium Priority
?
432 Views
Last Modified: 2012-06-27
How do I create a control at runtime ie

place a label or textbox on a form

I know it can be done in VB 6
0
Comment
Question by:kevinstone
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 7
  • 4
  • 3
  • +3
21 Comments
 
LVL 14

Expert Comment

by:mcrider
ID: 2604237
With VB5, you must have a control on the form already with the INDEX property set to 0.

For example add a textbox to a form an set the INDEX property to 0 and set the VISIBLE property to FALSE.

Then you can do this to have two new controls:

    Load Text1(1)
    With Text1(1)
         .Visible = True
         .Top = 0
         .Left = 0
    End With

    Load Text1(2)
    With Text1(2)
         .Visible = True
         .Top = 0
         .Left = Text1(1).Width + 120
    End With



Cheers!®©
0
 

Author Comment

by:kevinstone
ID: 2604589
This requires that a control already exist on the form.  If this is the case a new instance of the control can be created with

DIM lable1 AS NEW LABEL1

where LABEL1 exist on the form

I can I achieve control creation where no other instance exist. ie blank form

on event create a control from scratch

0
 
LVL 9

Expert Comment

by:samopal
ID: 2604765
This create a Dynamic Button
   Set cmdObject = Form1.Controls.Add("VB.CommandButton", "cmdOne")
   cmdObject.Visible = True
   cmdObject.Caption = "Dynamic CommandButton"

To create Label, use "VB.Label"

HTH
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 14

Expert Comment

by:mcrider
ID: 2604804
samopal,

That does NOT work in VB5. Read the title of the question again.



kevinstone,

Your question title says "Dynamic Control Creation VB5"

"DIM lable1 AS NEW LABEL1" will NOT work in VB5.  This is VB6 only.

Like I said, the *ONLY* way to do it in VB5 is with objects that already exist on the form and have an INDEX set to 0.

If you want to be able to do "DIM lable1 AS NEW LABEL1" you MUST upgrade to VB6...


P.S. Dont shoot the messenger.  I did not write VB...



Cheers!®©


0
 
LVL 9

Expert Comment

by:samopal
ID: 2604838
I'm SORRY... I saw only VB6 at the end of this question...
0
 
LVL 2

Expert Comment

by:Bodya
ID: 2605380
In VB5 to create a control you must have a control array. That mean that if you want to create labela and TextBoxes, you should place on you form one Label with Index=0 (or more) and one TextBox with Index=0 (or more). The Index propery should be defined to explain to Basic that this is a controll array. Then you can write the following code (perhapes you name controls as 'MyLabel' and 'MyText' )

Load MyLabel(1)
Load MyText(1)

or

Load MyLabel(MyLabel.UBound+1)
Load MyText(MyText.UBound+1)

If you need to load a label from class  module where you have a reference to you form :

Load MyForm.MyLabel(1)

If you have to create other types of controls, you should place at least one instance of each type and set their Index property.

Note, that even in VB 6 controls, loaded in such a way works quiklier then those, loaded with Controls.Add()

best regards
0
 
LVL 14

Expert Comment

by:mcrider
ID: 2605716
Bodya,  It is not proper EE etiquette to steal another's comments and post them as your own answer.  Please remove your answer.
0
 
LVL 15

Expert Comment

by:ameba
ID: 2606099
' try this :)
Option Explicit
Private Declare Function CreateWindowEx Lib "user32.dll" Alias "CreateWindowExA" _
    (ByVal dwExStyle As Long, ByVal lpClassName As String, ByVal lpWindowName As String, _
    ByVal dwStyle As Long, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, _
    ByVal hWndParent As Long, ByVal hMenu As Long, ByVal hInstance As Long, lpParam As Any) As Long
Private Declare Function DestroyWindow Lib "user32" (ByVal hWnd As Long) As Long
Private Const BS_PUSHBUTTON = &H0&
Private Const WS_CHILD = &H40000000
Private Const WS_VISIBLE = &H10000000
Private Const WS_EX_CLIENTEDGE = &H200&
Private Const LVS_REPORT = &H1
Private Const ES_MULTILINE = &H4&
Private Const ES_AUTOVSCROLL = &H40&
Private Const WS_DLGFRAME = &H400000
Private Const WS_BORDER = &H800000
Private m_hButton As Long
Private m_hWndLV As Long
Private m_hEdit As Long
Private m_hLabel As Long

Private Sub Form_Load()
    Dim lngStyle As Long
    ' Define style
    lngStyle = BS_PUSHBUTTON Or WS_CHILD Or WS_VISIBLE
    ' Create the button
    m_hButton = CreateWindowEx(0&, "BUTTON", "Click Me!", _
        lngStyle, 190, 10, 150, 50, Me.hWnd, 0&, App.hInstance, ByVal 0&)
       
    ' Define style
    lngStyle = WS_CHILD Or WS_VISIBLE Or LVS_REPORT
    ' Create the listview
    m_hWndLV = CreateWindowEx(WS_EX_CLIENTEDGE, "SysListView32", vbNullString, _
        lngStyle, 10, 10, 100, 100, Me.hWnd, 0, App.hInstance, ByVal 0&)

    ' Define style
    lngStyle = WS_DLGFRAME Or ES_AUTOVSCROLL Or ES_MULTILINE Or WS_CHILD Or WS_VISIBLE
    ' Create the textbox
    m_hEdit = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "TextBox", _
        lngStyle, 10, 120, 240, 100, Me.hWnd, 0&, App.hInstance, ByVal 0&)

    ' Define style
    lngStyle = WS_BORDER Or WS_CHILD Or WS_VISIBLE
    ' Create the label
    m_hLabel = CreateWindowEx(0&, "STATIC", "Label!", _
        lngStyle, 260, 170, 150, 30, Me.hWnd, 0&, App.hInstance, ByVal 0&)
End Sub

Private Sub Form_Unload(Cancel As Integer)
    ' Cleanup
    Call DestroyWindow(m_hButton)
    Call DestroyWindow(m_hWndLV)
    Call DestroyWindow(m_hEdit)
    Call DestroyWindow(m_hLabel)
End Sub
0
 
LVL 8

Expert Comment

by:stefanx
ID: 2608254
Ameba - that's pretty cool (reminds me of my straig C days). Now how does one process the events? Also, how do you figure out what a legal window (control) type ?

Just for interest's sake....
0
 
LVL 15

Expert Comment

by:ameba
ID: 2608285
Hehe, sometimes you don't need events, e.g. user enters text and you just read content of edit box.
For events, you'll need sublassing (btw, I hate sublassing) to catch messages.
This (Win API controls) is all very complicated, especially for us comfortable VB programmers, but performance is much better than with normal VB controls - I have seen very fast implementations of ListView32 and RichEdit controls.
But, the 'full code' to use events and properties is very large, e.g. see:

http://www.mvps.org/btmtz/enumdeskvb/
"Dynamically create both the treeview and listview common controls at runtime
 
This example is busy. Not only does it create both the treeview and listview common controls at runtime through the API (no Comctl32.ocx); subclass the controls' parent window, a VB Form, allowing the receipt of control window notification messages; ..."
0
 
LVL 15

Expert Comment

by:ameba
ID: 2608288
>sublassing
subclassing :)
0
 
LVL 8

Expert Comment

by:stefanx
ID: 2608359
Heh, I was hoping it was as simple as registering your event to the parent window with an AddressOf(Procedure) operator ;). I remember this kind of stuff from the early Turbo pascal for Windows stuff though...makes us feel old, hey ?
0
 
LVL 15

Expert Comment

by:ameba
ID: 2608383
>makes us feel old, hey ?
I use word 'experienced' instead, it sounds better :)
0
 

Author Comment

by:kevinstone
ID: 2609203
Again this relies on the control already available
0
 
LVL 15

Expert Comment

by:ameba
ID: 2610240
You requested code that will add controls to a blank form, so here it is:

' Form1, no controls on *this* form (i.e. blank form)
Option Explicit
Private Declare Function SetParent Lib "user32" (ByVal hWndChild As Long, ByVal hWndNewParent As Long) As Long

Private Sub Form_Load()
    Dim ctl As Control
    On Error Resume Next
   
    Show
    Load Form2
    For Each ctl In Form2.Controls
        ' SetParent doesn't work for lightweight controls (controls without hwnd)
        If TypeOf ctl Is Label Then
            ' this is replacement for Label control (it's not perfect)
            Me.CurrentX = ctl.Left
            Me.CurrentY = ctl.Top
            Print ctl.Caption
        Else
            SetParent ctl.hWnd, Me.hWnd
        End If
    Next
End Sub

Private Sub Form_Unload(Cancel As Integer)
    Unload Form2
End Sub
0
 
LVL 14

Expert Comment

by:mcrider
ID: 2611144
Ameba, Your last example requires the the controls exist on form2...
0
 
LVL 8

Expert Comment

by:stefanx
ID: 2611382
That may well be, but I think ameba's suggestion is pretty brilliant. Sure, the controls need to be on form2, but if form2 is unloaded, the controls in the "control pool" do not waste any resources. Smart move - I like it !
0
 
LVL 2

Expert Comment

by:Bodya
ID: 2611460
mcrider ,
Sorry I have looked through comments but don't pay attantion to a rejected answer. :(

Kevinstone, I don't understand why do you insist on creating from a scratch ? Finally, all the code you write for this will take more memory then a control on a form. Or, may be, you like programming on pure C ? :)))



0
 
LVL 15

Accepted Solution

by:
ameba earned 200 total points
ID: 2611843
stefanx, thanks

I just wanted to show what is possible.

I don't know if my samples will be used by kevinstone in real world app, or they are only for discussion, but I used both.

For Bodya,
>Kevinstone, I don't understand why do you insist on creating from a scratch ?

Here is one possible scenario:
You have a form with, e.g. 50 misc controls. All controls are with index 0.

You have to present preview of some dialog (e.g. defined in .dlg file).

If your form with all controls has the same style as the dialog you have to show, then no problem.
But if you have to show different form style (different form properties: BorderStyle, ControlBox, MaxButton, MinButton, MDIChild, etc) you cannot change this properties - they are read-only. For changing some properties it is possible to use APIs, like SetWindowLong, to change Form style, but not for all. To cover all combinations (there are 64) you'll have to use many (~16) forms:

    ' TForm1 is UDT, it is filled by reading .dlg file
    fn = selform(TForm1.BORDERSTYLE, TForm1.MaxButton, TForm1.MinButton, TForm1.ControlBox, TForm1.MDIChild)

Function selform(bs As Integer, mx As Integer, mn As Integer, cb As Integer, mdc As Integer) As Integer
    Dim fnum As Integer
    fnum = cb + 2 * mn + 4 * mx + 8 * bs + 16 * mdc
    Select Case fnum
    Case 0 To 7
        Load Form0
    Case 24, 26, 28, 30
        Load Form1
    Case 25, 27, 29, 31
        Load Form2
    Case 8
        Load Form3
    ...
    Case 63
        Load Form15
    End Select
End Function

You can prefill all 16 forms with controls, but having controls on *only one* form means:
- smaller .exe
- easy maintenance (imagine you have to add one more control to your set of supported controls)
0
 

Author Comment

by:kevinstone
ID: 2620129
I tried this and it does exactly what I wanted.  Many Thanks
0
 
LVL 15

Expert Comment

by:ameba
ID: 2620516
Thanks for your points.
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

If you have ever used Microsoft Word then you know that it has a good spell checker and it may have occurred to you that the ability to check spelling might be a nice piece of functionality to add to certain applications of yours. Well the code that…
You can of course define an array to hold data that is of a particular type like an array of Strings to hold customer names or an array of Doubles to hold customer sales, but what do you do if you want to coordinate that data? This article describes…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…
Suggested Courses

730 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question