Improve company productivity with a Business Account.Sign Up

  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 391
  • Last Modified:

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

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?????

  • 3
  • 2
1 Solution
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.
This appears, from first glance to be similar to what I am saying:
altariamx2003Author Commented:

I need a lot of work to make this system

One last question

It is posible to draw lines with arrows as objects?????
Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.


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);
altariamx2003Author Commented:


Mike TomlinsonMiddle School Assistant TeacherCommented:
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

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.

Join & Write a Comment

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now