How to ADD and DELETE VB.Shape controls at RunTime

Hello, I have the following code that instantiates a Single VB.Shape control at runtime:

Dim WithEvents mShape1 As VB.Shape

Private Sub Command1_Click()
   Set mShape1 = Controls.Add("VB.Shape", "mShape1")
   mShape1.Visible = True
End Sub

This crashes when I try adding a second Shape. What I am trying to do is add as many Shapes as needed AND to delete them individually when they are no longer required.

I think I need a Control Array but not sure how to set this up.


Who is Participating?

Improve company productivity with a Business Account.Sign Up

Mike TomlinsonConnect With a Mentor Middle School Assistant TeacherCommented:
To do this with the Shape control you would have to trap the events for the container of your shape controls.  You could add your shapes to a PictureBox for example by adding this line to your shape creation code:
    Set Shapes(intShapes).Container = Picture1

The you can trap the MouseDown event for the PictureBox and check the coordinates against those of your shapes like this:

Private Sub Picture1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
    Dim s As Integer
    For s = 0 To UBound(Shapes)
        If X >= Shapes(s).Left And X <= Shapes(s).Left + Shapes(s).Width Then
            If Y >= Shapes(s).Top And Y <= Shapes(s).Top + Shapes(s).Height Then
                Debug.Print "Shape(" & s & ") Clicked"
                Exit Sub
            End If
        End If
    Next s
End Sub

If you don't want to mess with a control array then simply create the shapes and add them to your form like you are doing but also add a reference to your created shapes into a collection.  Then you can iterate the collection with a For Each...Next loop instead of walking an array by index.


CleffedUpConnect With a Mentor Commented:
Heya... Try this on for size in a new form (Form1) with two Command buttons.

Dim Shapes() As Shape
Dim intShapes As Integer

Private Sub Command1_Click()
    intShapes = intShapes + 1
    ReDim Preserve Shapes(intShapes)
    Set Shapes(intShapes) = Form1.Controls.Add("VB.Shape", "mShape" & intShapes)
    Shapes(intShapes).Top = intShapes * 30
    Shapes(intShapes).Left = intShapes * 30
    Shapes(intShapes).Visible = True
End Sub

Private Sub Command2_Click()
    Form1.Controls.Remove ("mShape" & intShapes)
    intShapes = intShapes - 1
End Sub

Private Sub Form_Load()
    intShapes = 0
End Sub

Incidentally, the problem with your initial code was you were trying to create two objects of the same name, i.e. "mShape1".
Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

const71Author Commented:
Looks good. Is there a way to get events?

Mike TomlinsonMiddle School Assistant TeacherCommented:
There are no events for the shape or line control.  They are only for adding visual components to your interface.

What is it you are trying to do with your program?

const71Author Commented:

I am creating rectangular regions representing fields on a form that can be double-clicked and resized. (Like Acrobat Forms). I can use Labels instead of Shapes if Shapes are not functional enough

Just use control array and then you can trap the event

ie. put the shape control on the form and set index to 0.

Then you should be able to load and unload the shape control and also can handle the event
Mike TomlinsonMiddle School Assistant TeacherCommented:

It doesn't matter if you add your shape controls to a control array or create them dynamically since the shape control doesn't have any events to trap and/or handle in the first place!

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.