how to create images and shapes in execution time inside a container

Posted on 2010-11-24
Last Modified: 2012-05-10
I had this code:

Public Class Form1

    Inherits System.Windows.Forms.Form


    Private DX, DY As Integer


    ' Declaraciones del API para 32 bits

    Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" _

        (ByVal hwnd As Integer, ByVal nIndex As Integer) As Integer

    Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _

        (ByVal hwnd As Integer, ByVal nIndex As Integer, _

         ByVal dwNewLong As Integer) As Integer

    Private Declare Function SetWindowPos Lib "user32" _

        (ByVal hwnd As Integer, ByVal hWndInsertAfter As Integer, _

         ByVal X As Integer, ByVal Y As Integer, _

         ByVal cX As Integer, ByVal cY As Integer, _

         ByVal wFlags As Integer) As Integer


    ' Constantes para usar con el API

    Const GWL_STYLE As Integer = (-16)

    Const WS_THICKFRAME As Integer = &H40000 ' Con borde redimensionable


    Const SWP_DRAWFRAME As Integer = &H20

    Const SWP_NOMOVE As Integer = &H2

    Const SWP_NOSIZE As Integer = &H1

    Friend WithEvents Label3 As System.Windows.Forms.Label

    Friend WithEvents NumericUpDown2 As System.Windows.Forms.NumericUpDown

    Friend WithEvents NumericUpDown1 As System.Windows.Forms.NumericUpDown

    Friend WithEvents Label2 As System.Windows.Forms.Label

    Friend WithEvents Label1 As System.Windows.Forms.Label

    Friend WithEvents Button1 As System.Windows.Forms.Button

    Const SWP_NOZORDER As Integer = &H4


    '' Este procedimiento no es necesario en Visual Basic .NET,

    '' pero está por si se quiere añadir código

    '' para detectar si ya está en ejecución,

    'Shared Sub Main()

    '    ' Starts the application.

    '    Application.Run(New MoverControles())

    'End Sub

#Region " Windows Form Designer generated code "

    Public Sub New()


        'This call is required by the Windows Form Designer.


        'Add any initialization after the InitializeComponent() call

    End Sub

    'Form overrides dispose to clean up the component list.

    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)

        If disposing Then

            If Not (components Is Nothing) Then


            End If

        End If


    End Sub

    'Required by the Windows Form Designer

    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer

    'It can be modified using the Windows Form Designer.  

    'Do not modify it using the code editor.

    Friend WithEvents GroupBox1 As System.Windows.Forms.GroupBox

    Friend WithEvents ListBox1 As System.Windows.Forms.ListBox

    Friend WithEvents GroupBox2 As System.Windows.Forms.GroupBox

    Friend WithEvents RadioButton1 As System.Windows.Forms.RadioButton

    Friend WithEvents btmCrear As System.Windows.Forms.Button

    Friend WithEvents btmEliminar As System.Windows.Forms.Button

    Friend WithEvents RadioButton2 As System.Windows.Forms.RadioButton

    Friend WithEvents RadioButton3 As System.Windows.Forms.RadioButton

    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()

        Me.GroupBox1 = New System.Windows.Forms.GroupBox

        Me.ListBox1 = New System.Windows.Forms.ListBox

        Me.GroupBox2 = New System.Windows.Forms.GroupBox

        Me.RadioButton3 = New System.Windows.Forms.RadioButton

        Me.RadioButton2 = New System.Windows.Forms.RadioButton

        Me.Label3 = New System.Windows.Forms.Label

        Me.NumericUpDown2 = New System.Windows.Forms.NumericUpDown

        Me.NumericUpDown1 = New System.Windows.Forms.NumericUpDown

        Me.Label2 = New System.Windows.Forms.Label

        Me.Label1 = New System.Windows.Forms.Label

        Me.btmCrear = New System.Windows.Forms.Button

        Me.RadioButton1 = New System.Windows.Forms.RadioButton

        Me.btmEliminar = New System.Windows.Forms.Button

        Me.Button1 = New System.Windows.Forms.Button


        CType(Me.NumericUpDown2, System.ComponentModel.ISupportInitialize).BeginInit()

        CType(Me.NumericUpDown1, System.ComponentModel.ISupportInitialize).BeginInit()





        Me.GroupBox1.Location = New System.Drawing.Point(32, 8)

        Me.GroupBox1.Name = "GroupBox1"

        Me.GroupBox1.Size = New System.Drawing.Size(781, 361)

        Me.GroupBox1.TabIndex = 2

        Me.GroupBox1.TabStop = False

        Me.GroupBox1.Text = "Mi contenedor"




        Me.ListBox1.Location = New System.Drawing.Point(886, 12)

        Me.ListBox1.Name = "ListBox1"

        Me.ListBox1.Size = New System.Drawing.Size(88, 95)

        Me.ListBox1.TabIndex = 7













        Me.GroupBox2.Location = New System.Drawing.Point(32, 375)

        Me.GroupBox2.Name = "GroupBox2"

        Me.GroupBox2.Size = New System.Drawing.Size(296, 149)

        Me.GroupBox2.TabIndex = 8

        Me.GroupBox2.TabStop = False

        Me.GroupBox2.Text = "Crear un Nuevo Control"




        Me.RadioButton3.Location = New System.Drawing.Point(16, 64)

        Me.RadioButton3.Name = "RadioButton3"

        Me.RadioButton3.Size = New System.Drawing.Size(128, 16)

        Me.RadioButton3.TabIndex = 13

        Me.RadioButton3.Text = "Button"




        Me.RadioButton2.Location = New System.Drawing.Point(16, 40)

        Me.RadioButton2.Name = "RadioButton2"

        Me.RadioButton2.Size = New System.Drawing.Size(128, 16)

        Me.RadioButton2.TabIndex = 12

        Me.RadioButton2.Text = "Label"




        Me.Label3.Location = New System.Drawing.Point(184, 64)

        Me.Label3.Name = "Label3"

        Me.Label3.Size = New System.Drawing.Size(72, 16)

        Me.Label3.TabIndex = 11

        Me.Label3.Text = "Posicion"




        Me.NumericUpDown2.Increment = New Decimal(New Integer() {10, 0, 0, 0})

        Me.NumericUpDown2.Location = New System.Drawing.Point(208, 104)

        Me.NumericUpDown2.Maximum = New Decimal(New Integer() {110, 0, 0, 0})

        Me.NumericUpDown2.Name = "NumericUpDown2"

        Me.NumericUpDown2.Size = New System.Drawing.Size(48, 20)

        Me.NumericUpDown2.TabIndex = 10

        Me.NumericUpDown2.Value = New Decimal(New Integer() {20, 0, 0, 0})




        Me.NumericUpDown1.Increment = New Decimal(New Integer() {10, 0, 0, 0})

        Me.NumericUpDown1.Location = New System.Drawing.Point(208, 80)

        Me.NumericUpDown1.Maximum = New Decimal(New Integer() {330, 0, 0, 0})

        Me.NumericUpDown1.Name = "NumericUpDown1"

        Me.NumericUpDown1.Size = New System.Drawing.Size(48, 20)

        Me.NumericUpDown1.TabIndex = 9

        Me.NumericUpDown1.Value = New Decimal(New Integer() {10, 0, 0, 0})




        Me.Label2.Location = New System.Drawing.Point(192, 104)

        Me.Label2.Name = "Label2"

        Me.Label2.Size = New System.Drawing.Size(16, 16)

        Me.Label2.TabIndex = 8

        Me.Label2.Text = "Y"




        Me.Label1.Location = New System.Drawing.Point(192, 80)

        Me.Label1.Name = "Label1"

        Me.Label1.Size = New System.Drawing.Size(16, 16)

        Me.Label1.TabIndex = 7

        Me.Label1.Text = "X"




        Me.btmCrear.Location = New System.Drawing.Point(16, 104)

        Me.btmCrear.Name = "btmCrear"

        Me.btmCrear.Size = New System.Drawing.Size(96, 32)

        Me.btmCrear.TabIndex = 2

        Me.btmCrear.Text = "Crear"




        Me.RadioButton1.Checked = True

        Me.RadioButton1.Location = New System.Drawing.Point(16, 16)

        Me.RadioButton1.Name = "RadioButton1"

        Me.RadioButton1.Size = New System.Drawing.Size(128, 24)

        Me.RadioButton1.TabIndex = 1

        Me.RadioButton1.TabStop = True

        Me.RadioButton1.Text = "TextBox"




        Me.btmEliminar.Location = New System.Drawing.Point(886, 116)

        Me.btmEliminar.Name = "btmEliminar"

        Me.btmEliminar.Size = New System.Drawing.Size(88, 24)

        Me.btmEliminar.TabIndex = 9

        Me.btmEliminar.Text = "Eliminar"




        Me.Button1.Location = New System.Drawing.Point(527, 411)

        Me.Button1.Name = "Button1"

        Me.Button1.Size = New System.Drawing.Size(188, 44)

        Me.Button1.TabIndex = 10

        Me.Button1.Text = "Button1"

        Me.Button1.UseVisualStyleBackColor = True




        Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)

        Me.ClientSize = New System.Drawing.Size(997, 572)






        Me.Name = "Form1"

        Me.Text = "Winform Controls"


        CType(Me.NumericUpDown2, System.ComponentModel.ISupportInitialize).EndInit()

        CType(Me.NumericUpDown1, System.ComponentModel.ISupportInitialize).EndInit()


    End Sub

#End Region

    ''iContador se utilizará para evitar duplicar los nombre de los

    ''nuevos controles

    Dim iContador As Integer

    ''Este procedimiento es el que crea los controles dentro del 


    Private Sub btmCrear_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btmCrear.Click

        ''Variable de mi nuevo objeto

        Dim MyNewObject As Control

        ''Creo una nueva instancia del control seleccionado

        If RadioButton1.Checked Then

            MyNewObject = New TextBox ''Nuevo TextBox

        ElseIf RadioButton2.Checked Then

            MyNewObject = New Label   ''Nueva Etiqueta

        ElseIf RadioButton3.Checked Then

            MyNewObject = New Button  ''Nuevo Botón

        End If

        ''Levanto el tipo del nuevo objeto

        Dim MyTipo As System.Type = MyNewObject.GetType

        ''Con el nombre del tipo y el contador le doy un nombre

        MyNewObject.Name = MyTipo.Name & Convert.ToString(iContador)

        ''En la propiedad Text le pongo el nombre del nuevo control

        ''(solo para que se vea bien en el ejemplo)

        MyNewObject.Text = MyNewObject.Name

        ''Ubico el nuevo control segun indicado

        MyNewObject.Location = New System.Drawing.Point(NumericUpDown1.Value, NumericUpDown2.Value)

        MyNewObject.Width = 100

        ''Le agrego al evento Click de mi nuevo control el evento ClickEvent

        ''Aqui se podría agregar un manejador a cualquier evento que uno quiera

        'AddHandler MyNewObject.Click, AddressOf ClickEvent

        AddHandler MyNewObject.MouseDown, AddressOf Me.Control_MouseDown

        AddHandler MyNewObject.MouseMove, AddressOf Me.Control_MouseMove

        AddHandler MyNewObject.MouseEnter, AddressOf Me.Control_MouseEnter

        ''Agrego el control al contenedor 

        ''(que podría claramente ser Me.controls, en vez de GroupBox1.control ¿no?)


        ''Para que el ejemplo sea claro cambio algunas variables

        'Agrego 1 al contador

        iContador += 1

        'Pongo el nombre de mi nuevo control en el listbox

        'para poder borrarlo


        'Muevo los valores para que no se sobreescriban los proximos controles

        If NumericUpDown1.Value + 50 <= NumericUpDown1.Maximum Then

            NumericUpDown1.Value += 50


            NumericUpDown1.Value = 10

            If NumericUpDown2.Value + 20 <= NumericUpDown2.Maximum Then

                NumericUpDown2.Value += 20

            End If

        End If

    End Sub

    ''Este es el evento que vamos a atar al evento click de los nuevos controles

    Private Sub ClickEvent(ByVal sender As System.Object, ByVal e As System.EventArgs)

        ''A modo de ejemplo muestro un messagebox con el nombre de control que lo llamó


    End Sub


    Private Sub Control_MouseDown( _

        ByVal sender As Object, _

        ByVal e As System.Windows.Forms.MouseEventArgs)

        ' Cuando se pulsa con el ratón

        DX = e.X

        DY = e.Y

        ' Al pulsar con el botón derecho, 

        ' cambiar el estilo entre redimensionable y normal

        'lblStatus.Text = "Control: " & CType(sender, Control).Name

        If e.Button = MouseButtons.Right Then

            CambiarEstilo(CType(sender, Control))


            ' Cuando se pulsa en un control, posicionarlo encima del resto

            CType(sender, Control).BringToFront()

        End If

    End Sub


    Private Sub Control_MouseMove( _

            ByVal sender As Object, _

            ByVal e As System.Windows.Forms.MouseEventArgs)

        ' Cuando se mueve el ratón y se pulsa el botón izquierdo... mover el control

        If e.Button = MouseButtons.Left Then

            CType(sender, Control).Left = e.X + CType(sender, Control).Left - DX

            CType(sender, Control).Top = e.Y + CType(sender, Control).Top - DY

        End If

    End Sub


    Private Sub Control_MouseEnter( _

            ByVal sender As Object, _

            ByVal e As System.EventArgs)

        'lblStatus.Text = "Control: " & CType(sender, Control).Name

    End Sub

    Private Sub CambiarEstilo(ByVal aControl As Control)

        ' Hacer este control redimensionable, usando el API

        ' Pone o quita el estilo dimensionable

        Dim Style As Integer


        ' Si se produce un error, no hacer nada...


            Style = GetWindowLong(aControl.Handle.ToInt32, GWL_STYLE)

            If (Style And WS_THICKFRAME) = WS_THICKFRAME Then

                ' Si ya lo tiene, lo quita

                Style = Style Xor WS_THICKFRAME


                ' Si no lo tiene, lo pone

                Style = Style Or WS_THICKFRAME

            End If

            SetWindowLong(aControl.Handle.ToInt32, GWL_STYLE, Style)

            SetWindowPos(aControl.Handle.ToInt32, Me.Handle.ToInt32, 0, 0, 0, 0, SWP_NOZORDER Or SWP_NOSIZE Or SWP_NOMOVE Or SWP_DRAWFRAME)

        Catch 'e As Exception

            'MsgBox("El control " & queControl.Name & " no permite que se redimensione", MsgBoxStyle.Information)

            'Exit Sub

        End Try

    End Sub


    ''Elimino un control

    Private Sub btmEliminar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btmEliminar.Click

        ''Chequeo si el listbox tiene algo seleccionado

        If Not Me.ListBox1.SelectedItem Is Nothing Then

            'Recorro todos los controles del GroupBox1 buscando el control

            'que deseo eliminar 

            Dim Eliminar As Control

            For Each Eliminar In Me.GroupBox1.Controls

                If Eliminar.Name = ListBox1.SelectedItem Then

                    'Saco el control de la colección


                    'Destruyo el control


                    'Saco el control del Listbox


                    'Salgo del For

                    Exit For

                End If


        End If

    End Sub

End Class

Open in new window

this code allow to create three kind of control at execution time inside a container.

One that the control is create in the container you can move it whereever you want inside the container.

I would like to know how to do the following:

1.- how can I do the same but with images (without picturebox control)

2.- how to draw lines inside to connect the objects inside the containers

3.- Do exists some kind of tutorial or something like that to know how to do actions after the object is created or selected?????

Question by:altariamx2003
  • 3
  • 2
LVL 25

Expert Comment

ID: 34230188
Well, to do shapes or pictures without a container or control, you will need to create a graphics retention system. Something that remembers each object and can redraw them...kind of like the old Metafiles.

So you'd create a base object
DrawingPrimObj or something that contains (x and y members) or (left and top) if you prefer. And a Draw or Display method (your choice).  Each other type object would inherit from this. So a picture object would inherit from DrawingPrimObj and add width and height Properties. I'd add an Image property that points to a system.drawing.image that contains the actual image.

You would add these objects to a List collection, Maybe make an object call MyCanvas and have it inheirt a generic list of type (DrawingPrimObj)...i.e. it would be a collection of your primitives.  This MyCanvas object would also have a Draw or Display method (whatever you want to call it), and when called it would do
For Each dp as DrawingPrimObj in me

That would loop through its internal collection, calling draw on each object.
This is the basic idea.
LVL 25

Expert Comment

ID: 34230212
This appears, from first glance to be similar to what I am saying:

Author Comment

ID: 34242653

I need a lot of work to make this system

One last question

It is posible to draw lines with arrows as objects?????
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

LVL 25

Accepted Solution

SStory earned 500 total points
ID: 34244302

I recommend you check out this page:

ON lines with arrows, the dotnet line offers arrows on the end. You'd just need your line object to offer that as a property and remember the Line object, which inherits from the other object.

Heres something on custom line caps

Here another article on line caps (can be arrows);

Author Comment

ID: 34258434


LVL 85

Expert Comment

by:Mike Tomlinson
ID: 34258935
You can also calculate the endpoints for an arrow given the start/stop points and an "armlength":
Public Class Form1

    Private R As New Random

    Private ArmLength As Integer = -1

    Private ArrowStart, ArrowEnd As Point

    Private ArrowArmA, ArrowArmB As Point

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        ArmLength = R.Next(3, 21)

        ArrowStart = New Point(R.Next(0, Me.ClientRectangle.Width), R.Next(0, Me.ClientRectangle.Height))

        ArrowEnd = New Point(R.Next(0, Me.ClientRectangle.Width), R.Next(0, Me.ClientRectangle.Height))

        Dim dx As Double = ArrowEnd.X - ArrowStart.X

        Dim dy As Double = ArrowEnd.Y - ArrowStart.Y

        Dim length As Double = Math.Sqrt(Math.Pow(dx, 2) + Math.Pow(dy, 2))

        Dim offsetX As Double = dx / length * ArmLength

        Dim offsetY As Double = dy / length * ArmLength

        ArrowArmA = New Point(ArrowEnd.X - offsetX - offsetY, ArrowEnd.Y - offsetY + offsetX)

        ArrowArmB = New Point(ArrowEnd.X - offsetX + offsetY, ArrowEnd.Y - offsetY - offsetX)


    End Sub

    Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint

        If ArmLength <> -1 Then

            e.Graphics.DrawLine(Pens.Black, ArrowStart, ArrowEnd)

            e.Graphics.DrawLine(Pens.Black, ArrowEnd, ArrowArmA)

            e.Graphics.DrawLine(Pens.Black, ArrowEnd, ArrowArmB)

        End If

    End Sub

End Class

Open in new window


Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Introduction As chip makers focus on adding processor cores over increasing clock speed, developers need to utilize the features of modern CPUs.  One of the ways we can do this is by implementing parallel algorithms in our software.   One recent…
Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…
This video demonstrates how to create an example email signature rule for a department in a company using CodeTwo Exchange Rules. The signature will be inserted beneath users' latest emails in conversations and will be displayed in users' Sent Items…

757 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

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now