CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 18
  1. #1
    Join Date
    Jul 2003
    Location
    Boston, or Columbus
    Posts
    46

    Unhappy Dynamic controls & collection - pls help

    Here is my code:

    Dim WithEvents kk As TextBox
    Private Sub Form_Load()

    For i = 0 To 5
    Set kk = Controls.Add("vb.textbox", "Doug" & i)

    kk.Width = 1200
    kk.Top = 2500 + i * 300
    kk.Left = 600
    kk.Height = 285
    kk.Text = kk.Name '--> doug
    kk.Visible = True
    Next i

    End Sub

    Private Sub kk_click()
    MsgBox "Thanks for the help", , "hmm"
    End Sub



    ok; what i can do is create controlls and then modify their contents(text,position etc) after they have been created. What i can not do is raiseEvents with the newly created controls. what i would like to do is on _click (or change etc) have that control execute code. Which would be the same as having an array of text1(0)..text1(5) then on

    text1_click(index as integer)
    'do whatever
    end sub

    if you were to copt my code into a from you would see that when you click on the last text box you get a messassage but the other textboxes are 'inactive' --> i want to change this so they will all execuate the same code.

    Someone told me that i need to add each control i created to a class and then do some stuff, but i don't have any knowledge of this.

    If this is unclear in any way let me know.

    Thanks
    -Doug

  2. #2
    Join Date
    Nov 2002
    Location
    Baby Land
    Posts
    646
    You could try control array instead

    Option Explicit
    'Add a textbox named text1 with index property 0
    'and visible property set to false

    Private Sub Form_Load()
    Dim i As Integer
    For i = 1 To 5
    Load Text1(i)
    With Text1(i)
    .Width = 1200
    .Top = 2500 + i * 300
    .Left = 600
    .Height = 285
    .Text = .Name '--> doug
    .Visible = True
    End With
    Next i
    End Sub

    Private Sub Text1_Click(Index As Integer)
    MsgBox "Thanks for the help", , "hmm " & CStr(Index)
    End Sub

  3. #3
    Join Date
    Jul 2003
    Location
    Boston, or Columbus
    Posts
    46
    Thanks, but this code will be used in a module so I don't want to actully create any controls at design time, just though code.
    -i read somewhere that i needed to add them to a collection in a class - but don't know how.

    Thanks
    -Doug

  4. #4
    Join Date
    Nov 2002
    Location
    Baby Land
    Posts
    646
    Take a look at the attachment
    Attached Files Attached Files

  5. #5
    Join Date
    Jul 2003
    Location
    Boston, or Columbus
    Posts
    46
    Thanks, i am currenlty fooling around with your file.

    I have a few questions though since i haven't used classes before (sad i know).

    1. Implements ITextBoxEvent - what does this do - why is implments needed etc

    for anyone else who is reading this i have posted (part) his code below:

    he created a class with name of 'ItextBoxEvent' and in it is:

    Option Explicit
    Sub Click(TextObject As TextBox)
    'Replace this to as Object if this interface made public
    End Sub

    there is a second class called 'cEventHandler' and in it is:

    Option Explicit
    Implements ITextBoxEvent

    Private Sub ITextBoxEvent_Click(TextObject As TextBox)
    MsgBox "TextBox " & TextObject.Name & " Clicked"
    End Sub


    Why isn't there 1 class instead of two? why is the class 'ItextboxEvent' needed when all of the code is 'commetted out?

    I really am unfamiler with this topic so any info would be greatly appreciated.

    Thanks -Doug

  6. #6
    Join Date
    Nov 2002
    Location
    Baby Land
    Posts
    646
    It is a common technique in Object Oriented Programming (OOP).
    Although VB itself is Object Oriented but it only supports limited capability in a concept known as Inheritance.

    In VB, Inheritance (more like encapsulation, I think..), is supported by the keyword Implements, you can define a class module as a 'Skeleton' for other class, this skeleton class only contain a definition of the Interface supported by the skeleton.

    This interface could be in the forms of Sub, Function, or Property. And it does not need to contain codes of the actual program just the definition (that's why you only find comments in the ITextboxEvent class).

    Now the actual code is written in another class module that Implements this skeleton class (cEventHandler). If a class decide to Implement a skeleton then it's like a contract, they have to implements the Interface defined in the skeleton (When you write a new class and use the Implements keyword, the Implements ClassName will be showed in the Top Left ComboBox of your code module window, while the interface will be shown in the right combo if you select the class).

    I use this approach for your problem because you might want to extend the class to not only supports textbox but also other control as well, usually they have similar event like Click, DblClick, etc.

    I know this is not enough to answer all your question, but I think you will have to grasp the concept of OOP before you can decide whether it suits your need or only complicate the matters (As you said before, yes you can use just 1 class and made it public and pass it around as parameters or just declare it globally accessible).

    I would recommend to do some reading in OOP and its use, cause there must be a reason to move C to C++ just so we can have OOP supports right?

  7. #7
    Join Date
    Jul 2003
    Location
    Boston, or Columbus
    Posts
    46
    Thanks for the info, it is still a little hazzy though I should be able to solve my problem; although i don't really know what is going on 'behind the sceens'.

    But still how does the skelton know to call 'cEventHandler'.


    I tried putting:
    Sub Click(TextObject As TextBox)
    'Replace this to as Object if this interface made public
    MsgBox "TextBox " & TextObject.Name & " Changed-Doug"
    End Sub

    the msgbox is in the skelton but nothing happens - to me this is bizzare.

    If you feel that what you said before is an adaqute description then i will have to consult a book. I never had a course on programming hence these 'questions'.

    Thanks
    -Doug

  8. #8
    Join Date
    Jul 2003
    Location
    Boston, or Columbus
    Posts
    46
    Thanks again for your help!

    I altered your code; it's much 'simpler' now although i don't know what the downside is. If you can tell me if i'm making a lethal flaw pls due so, Thanks.

    Here is code for a form (form2 - it could have been a module)
    -------
    Private txtdoug(4) As DtextBox

    Private Sub Command1_Click()
    Me.Controls("dtext1").Visible = True 'works
    End Sub


    Private Sub Form_Load()
    Dim i As Integer
    For i = 0 To 4
    Set txtdoug(i) = New DtextBox
    With txtdoug(i)
    ' Set .EventHandler = D_handler 'without this it will still load
    .MyMake Me, i
    End With
    Module1.Movenow "dtext", i
    Next i

    End Sub

    ------
    the 'move' sub

    Public Sub Movenow(meTextbox As String, i As Integer)
    With Form2.Controls(meTextbox & i) ' TxtAny
    .left = 700
    .top = 700 + 500 * i
    .width = 1240
    .height = 240
    .Text = .Name
    .Visible = True
    End With
    End Sub

    -------

    here is the last section of code in a class

    Private WithEvents txtdoug As TextBox

    Public Sub MyMake(Fname As Form, i As Integer)
    Set txtdoug = Fname.Controls.Add("vb.textbox", "Dtext" & i, Fname)
    End Sub

    Private Sub txtdoug_Click()
    ShoMsg txtdoug
    End Sub
    Private Sub txtdoug_change()
    'ShoMsg txtdoug 'works but is annoying
    End Sub

    Private Sub ShoMsg(txtAny As TextBox)
    MsgBox "TextBox " & txtAny.Name & " Changed-Doug"
    ' Form2.Command1.Caption = "34343" 'works
    End Sub

    ------

    There is all of the code - could't have done it with out you - but what i'm i missing?


    also I tried having the 'move' in a class but was unable to.

    what i would like to do (i know other meathods but..) would be to call a sub in a class called 'left' which would take the object and set its location, I know this seems trivial but I could't figure it out (i know it being 3:10 AM has nothing to do with it)

    Thanks Again.
    -Doug

    Incase you didn't know the answer to life is, 42.

  9. #9
    Join Date
    Nov 2002
    Location
    Baby Land
    Posts
    646
    As I mention before, it is a matter of your preference whether to use implements in VB or not.

    for the Left and move sub, you can place it in your DTextBox class
    like this

    Public Property let Left(NewValue as Single)
    if txtdoug is nothing then exit property
    txtdoug.Left = NewValue
    End Property

  10. #10
    Join Date
    Jul 2003
    Location
    Boston, or Columbus
    Posts
    46
    cool it works;

    what is the difference of: Get, Set, Let?

    -Doug

  11. #11
    Join Date
    May 2002
    Location
    Montreal
    Posts
    450
    Just the first letter... Just kidding.


    Set is to assign an object such as

    Dim cInv as clsInventory
    Set cInv = new Inventory

    You just create a new object 'cInv' that is of the cInventory class.


    Let and Get are used for properties inside a class.

    Let is to assign a class property a value
    cInv.PartNo = '12345'


    Get is to retrieve the value of a class property
    sPartNo = cInv.PartNo


    Look up the help file for the Let Statement. Better explanation in there.
    Cheers,
    Laurent

    For an aviator, the three best things in life are a good landing, a good orgasm, and a good sh*t. A night carrier landing is one of the few opportunities to experience all three at the same time.

  12. #12
    Join Date
    May 2003
    Location
    Australia
    Posts
    155
    Hi,

    If you have solved your problem already, then that is great, but I thought I would offer an explanation as to why your adding controls dynamically wasnt working properly in the first place, and give you a quick guide to adding controls dynamically.

    First of all, which you probably already know, is that you have to add a control to a form. This is the only way it can be displayed, however, your textbox variable declarations dont need to be declared in the form that the control will appear, nor does the code that doest the actual control creation.

    Secondly, and this is probably why you were having problems, is that if you want to create 5 textbox controls at run-time that use the WithEvents keyword, then you must declare 5 different textbox variables, one for each textbox you want to create. Also to be annoying, you cant create an array of textbox's either when you use WithEvents, they have to be separate variable declarations. So in your code sample, only the last textbox you created would have had events working.

    Once you have delcared your 5 textbox variables (in either a class or a form, but not a module - WithEvents is illegal within a bas module), you will notice that there are now 5 textbox's listed in the left combo of your code view. You can put the code you want to execute in these textbox controls events.

    You then need to create your textbox controls at runtime using Controls.Add(), and set the controls properties etc, and you are ready to use the textbox controls on the form.

    Where should your code to create the controls go? This is up to you, it can be in the form, a class, or a bas module, but if you are going to do it in a class or bas module, you will need to pass it a reference to the form (and possibly the container control that you are going to add the textbox control to).

    There is a 3rd parameter to the Controls.Add() function, which is the parent/owner of the control (ie, where do you want me to add this control to?). If you leave it blank, then it will default to the form you are adding it to. But you can specify a frame control or similar if you wanted to.

    With me so far?

    How about an example ...

    The following example uses a class and a form to create 3 textbox controls dynamically.

    In a class called cTextBox, put the following code:
    Code:
      Public WithEvents txtTB1 As TextBox
      Public WithEvents txtTB2 As TextBox
      Public WithEvents txtTB3 As TextBox
    
    Private Sub Class_Terminate()
    
      Set txtTB1 = Nothing
      Set txtTB2 = Nothing
      Set txtTB3 = Nothing
    
    End Sub
    
    Private Sub txtTB1_LostFocus()
    
      MsgBox txtTB1.Text
    
    End Sub
    
    Private Sub txtTB2_LostFocus()
    
      MsgBox txtTB2.Text
    
    End Sub
    
    Private Sub txtTB3_LostFocus()
    
      MsgBox txtTB3.Text
    
    End Sub
    In the form, put the following code:
    Code:
    Option Explicit
    
    Private moTextBox As cTextBox
    
    Private Sub Form_Load()
    
      ' create an instance of the class
      Set moTextBox = New cTextBox
      
      ' add first textbox
      Set moTextBox.txtTB1 = Controls.Add("vb.textbox", "txtTB1", Me)
      moTextBox.txtTB1.Visible = True
      moTextBox.txtTB1.Move 0, 0
      
      ' add second textbox
      Set moTextBox.txtTB2 = Controls.Add("vb.textbox", "txtTB2", Me)
      moTextBox.txtTB2.Visible = True
      moTextBox.txtTB2.Move 0, 500
      
      ' add third textbox
      Set moTextBox.txtTB3 = Controls.Add("vb.textbox", "txtTB3", Me)
      moTextBox.txtTB3.Visible = True
      moTextBox.txtTB3.Move 0, 1000
        
    End Sub
    
    Private Sub Form_Unload(Cancel As Integer)
    
      ' remove textbox controls
      Me.Controls.Remove "txtTB1"
      Me.Controls.Remove "txtTB2"
      Me.Controls.Remove "txtTB3"
      
      ' clear out textbox class
      Set moTextBox = Nothing
    
    End Sub
    This example will place 3 textbox controls on the form, and will display the text of each textbox when the textbox loses focus.

    You could and probably should put the textbox creation code in your class too if you wanted, but it really depends on your project.

    Make sense? Even if you dont need to use the code, its always nice to understand what was going on in the first place

    Cheers,
    Tinbum747
    Zen-Programming:

    If a compiler beeps in the IDE forest, and nobody hears it, was there really a bug?

  13. #13
    Join Date
    Jul 2003
    Location
    Boston, or Columbus
    Posts
    46
    thanks for the info, although in one of the posts there was a attached file in there was a sample.

    In his (file's) meathod you can create a psudo-array so you only need withevents once.

    -Doug

  14. #14
    Join Date
    Apr 2003
    Posts
    322

    Re: Dynamic controls & collection - pls help

    Quote Originally Posted by Luthv
    Take a look at the attachment
    I'm looking at your example. I need to do something similar.
    But I want to create a TextBox & Label pair, on the form, for each line in a text file.

    So this line from the zipfile you posted, won't work in my case.

    Private m_TextBox(4) As cTextBox

    I want to use a ControlArray, but of what type of control?
    What I need is an array (of unknown size) of Class instances, which contain variables to reference a dynamically created text box and Label pair.


    Too bad I can't create a ClassArray which functions like a Control Array.

    Any suggestions?

  15. #15
    Join Date
    Nov 2002
    Location
    Baby Land
    Posts
    646

    Re: Dynamic controls & collection - pls help

    I don't remember much of the sample I've posted. But you can create any class and save it in a dynamic array.
    and you can create any number of runtime controls in that class

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured