Link to home
Start Free TrialLog in
Avatar of altariamx2003
altariamx2003Flag for Mexico

asked on

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()
        MyBase.New()

        'This call is required by the Windows Form Designer.
        InitializeComponent()

        '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
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    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
        Me.GroupBox2.SuspendLayout()
        CType(Me.NumericUpDown2, System.ComponentModel.ISupportInitialize).BeginInit()
        CType(Me.NumericUpDown1, System.ComponentModel.ISupportInitialize).BeginInit()
        Me.SuspendLayout()
        '
        'GroupBox1
        '
        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"
        '
        'ListBox1
        '
        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
        '
        'GroupBox2
        '
        Me.GroupBox2.Controls.Add(Me.RadioButton3)
        Me.GroupBox2.Controls.Add(Me.RadioButton2)
        Me.GroupBox2.Controls.Add(Me.Label3)
        Me.GroupBox2.Controls.Add(Me.NumericUpDown2)
        Me.GroupBox2.Controls.Add(Me.NumericUpDown1)
        Me.GroupBox2.Controls.Add(Me.Label2)
        Me.GroupBox2.Controls.Add(Me.Label1)
        Me.GroupBox2.Controls.Add(Me.btmCrear)
        Me.GroupBox2.Controls.Add(Me.RadioButton1)
        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"
        '
        'RadioButton3
        '
        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"
        '
        'RadioButton2
        '
        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"
        '
        'Label3
        '
        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"
        '
        'NumericUpDown2
        '
        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})
        '
        'NumericUpDown1
        '
        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})
        '
        'Label2
        '
        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"
        '
        'Label1
        '
        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"
        '
        'btmCrear
        '
        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"
        '
        'RadioButton1
        '
        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"
        '
        'btmEliminar
        '
        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"
        '
        'Button1
        '
        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
        '
        'Form1
        '
        Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
        Me.ClientSize = New System.Drawing.Size(997, 572)
        Me.Controls.Add(Me.Button1)
        Me.Controls.Add(Me.btmEliminar)
        Me.Controls.Add(Me.GroupBox2)
        Me.Controls.Add(Me.ListBox1)
        Me.Controls.Add(Me.GroupBox1)
        Me.Name = "Form1"
        Me.Text = "Winform Controls"
        Me.GroupBox2.ResumeLayout(False)
        CType(Me.NumericUpDown2, System.ComponentModel.ISupportInitialize).EndInit()
        CType(Me.NumericUpDown1, System.ComponentModel.ISupportInitialize).EndInit()
        Me.ResumeLayout(False)

    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 
    ''GroupBox1
    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?)
        Me.GroupBox1.Controls.Add(MyNewObject)


        ''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
        Me.ListBox1.Items.Add(MyNewObject.Name)

        'Muevo los valores para que no se sobreescriban los proximos controles
        If NumericUpDown1.Value + 50 <= NumericUpDown1.Maximum Then
            NumericUpDown1.Value += 50
        Else
            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ó
        MessageBox.Show(sender.name)
    End Sub
    'AQUI INICIA
    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))
        Else
            ' 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...
        Try
            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
            Else
                ' 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

    'AQUI TERMINA

    ''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
                    Me.Controls.Remove(Eliminar)

                    'Destruyo el control
                    Eliminar.Dispose()

                    'Saco el control del Listbox
                    Me.ListBox1.Items.Remove(Me.ListBox1.SelectedItem)

                    'Salgo del For
                    Exit For
                End If
            Next
        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?????

Avatar of SStory
SStory
Flag of United States of America image

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
 dp.Draw()
next

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:
http://www.codeproject.com/KB/graphics/Painter.aspx
Avatar of altariamx2003

ASKER

wow

I need a lot of work to make this system

One last question

It is posible to draw lines with arrows as objects?????
ASKER CERTIFIED SOLUTION
Avatar of SStory
SStory
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
nice

help

thanks
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)

        Me.Refresh()
    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

Idle-Mind-375730.flv